daniel-monroy / sat-estado-cfdi
Paquete interno Laravel para consultar estado CFDI (SAT)
Requires
- php: ^8.3
- ext-dom: *
- guzzlehttp/guzzle: ^7.9
- laravel/framework: ^11.0|^12.0|^13.0
- nyholm/psr7: ^1.8
- php-http/guzzle7-adapter: ^1.0
- phpcfdi/cfdi-expresiones: ^v3.3.0
- phpcfdi/sat-estado-cfdi: ^2.0
Requires (Dev)
- laravel/pint: ^1.24
- mockery/mockery: ^1.6
- orchestra/testbench: ^10.0|^11.0
- pestphp/pest: ^3.8|^4.0
- pestphp/pest-plugin-laravel: ^3.2|^4.0
Conflicts
- league/commonmark: >=2.0.0,<2.8.2
- symfony/http-foundation: >=7.0.0,<7.3.7
- symfony/process: >=7.0.0,<7.3.11
README
Este paquete integra la librería phpcfdi/sat-estado-cfdi en Laravel 11, 12 y 13 para consultar el estado de un CFDI directamente en el servicio web del SAT.
El protocolo que utiliza el SAT para esta consulta es SOAP sobre HTTP/HTTPS, expuesto como servicio web. Este paquete se conecta mediante un cliente HTTP PSR-18, con compatibilidad para reintentos, timeouts, caché y una integración HTTP opcional para proyectos Laravel.
Documentación
Compatibilidad
| PHP | Laravel |
|---|---|
| 8.3 | 11, 12, 13 |
| 8.4 | 11, 12, 13 |
📦 Instalación
Instálalo vía Composer:
composer require daniel-monroy/sat-estado-cfdi
⚙️ Configuración
Publica el archivo de configuración:
php artisan vendor:publish --tag="sat-estado-cfdi-config"
Ejemplo de configuración en config/sat-estado-cfdi.php:
return [ 'expose_routes' => env('SAT_ESTADO_EXPOSE_ROUTES', false), 'route_prefix' => env('SAT_ESTADO_ROUTE_PREFIX', 'api'), 'middleware' => env('SAT_ESTADO_ROUTE_MIDDLEWARE', 'api'), 'cache_ttl' => env('SAT_ESTADO_CACHE_TTL', 900), // segundos ];
En el archivo .env puedes definir:
SAT_ESTADO_EXPOSE_ROUTES=true SAT_ESTADO_ROUTE_PREFIX=api SAT_ESTADO_ROUTE_MIDDLEWARE=api,auth:sanctum SAT_ESTADO_CACHE_TTL=900
Uso desde Laravel
Servicio
use DanielMonroy\SatEstadoCfdi\Services\SatEstadoCfdi\SatEstadoCfdiService; $response = app(SatEstadoCfdiService::class)->consultByExpression( 'https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?id=UUID&re=AAA010101AAA&rr=BBB010101BBB&tt=123.450000&fe=ABCD1234' );
Facade
use DanielMonroy\SatEstadoCfdi\Facades\SatEstado; $response = SatEstado::consultByExpression( 'id=UUID&re=AAA010101AAA&rr=BBB010101BBB&tt=123.450000' );
Desde XML
use DanielMonroy\SatEstadoCfdi\Facades\SatEstado; $response = SatEstado::consultFromXmlPath(storage_path('app/cfdi.xml'));
📡 Integración HTTP opcional
Si SAT_ESTADO_EXPOSE_ROUTES está en true, se habilitan los siguientes endpoints:
| Método | Endpoint | Descripción |
|---|---|---|
| POST | /api/cfdi/estado |
Consulta el estado de un CFDI |
| GET | /api/cfdi/estatus |
Verifica que el servicio esté activo |
El prefijo (/api) y el middleware (ej. auth, sanctum, etc.) pueden modificarse con la variable
SAT_ESTADO_ROUTE_PREFIX y SAT_ESTADO_ROUTE_MIDDLEWARE.
Ejemplo de consulta
curl -X POST http://tu-dominio.test/api/cfdi/estado \ -H "Content-Type: application/json" \ -d '{ "expression": "id=12345678-1234-1234-1234-123456789012&re=AAA010101AAA&rr=BBB010101BBB&tt=1234.56" }'
o con multipart/form-data enviando directamente el archivo XML:
curl -X POST http://tu-dominio.test/api/cfdi/estado \ -H "Content-Type: multipart/form-data" \ -F "xml=@/ruta/al/archivo.xml"
La respuesta será similar a:
{
"ok": true,
"status": "active",
"id": "XXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"message": "El CFDI se encuentra vigente y es valido.",
"cancelabilidad": "sin_aceptacion",
"cancelacion": "indefinida",
"flags": {
"isActive": true,
"isCancelled": false,
"isPendingCancel": false
},
"raw": {
"query": {
"isFound": true
},
"document": {
"isActive": true,
"isCancelled": false
},
"cancellable": {
"isCancellableByDirect": true,
"isCancellableByApproval": false
},
"cancellation": {
"isCancelledByDirect": false,
"isCancelledByApproval": false,
"isCancelledByExpiration": false,
"isPending": false,
"isDisapproved": false,
"isUndefined": true
},
"efos": null
}
}
Manejo de errores
- Si el CFDI no existe, el paquete responde
404en la integración HTTP opcional y devuelve un DTOnot_found. - Si el XML está mal formado o no puede leerse, la integración HTTP opcional responde
422. - Si la expresión no contiene al menos
id,re,rrytt, la validación HTTP responderá422.
Desarrollo
Instala dependencias de desarrollo y ejecuta las herramientas locales:
composer install
composer test
composer lint
Notas
- El paquete se apoya en y utiliza la librería phpcfdi/sat-estado-cfdi
- El servicio del SAT puede ser intermitente, se recomienda configurar caché y reintentos.
- Los estados dependen de la respuesta oficial del SAT.
- Si necesitas una integración agnóstica al framework, usa directamente
phpcfdi/sat-estado-cfdi. Este paquete está orientado específicamente a Laravel.
Licencia
Este paquete es software libre bajo la licencia MIT.