The SAT operates a SOAP web service atDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/eclipxe13/CfdiUtils/llms.txt
Use this file to discover all available pages before exploring further.
https://consultaqr.facturaelectronica.sat.gob.mx/ConsultaCFDIService.svc that lets you query the current status of any CFDI in real time. The response tells you whether a CFDI is currently valid (Vigente) or cancelled (Cancelado), whether it is eligible for cancellation, the status of any pending cancellation request, and whether the issuer is on the EFOS (simulated-operations) list.
CfdiUtils implements this integration in the CfdiUtils\ConsultaCfdiSat namespace without requiring the WSDL file. The SAT stopped publishing the WSDL in October 2018, but the service itself continues to work and CfdiUtils constructs the SOAP call manually.
This feature requires PHP’s
ext-soap extension. Verify it is enabled with php -m | grep soap.WebService
CfdiUtils\ConsultaCfdiSat\WebService is the entry point. It wraps a SoapClient instance and exposes a single request() method.
Config Options
Maximum seconds to wait for the SAT web service to respond.
Whether to verify the SAT server’s SSL certificate. Set to
false only for troubleshooting — never in production.The SOAP endpoint URL. Override if you are routing through a reverse proxy.
Request Parameters
CfdiUtils\ConsultaCfdiSat\RequestParameters encapsulates all the data extracted from the CFDI’s QR code expression. The SAT web service accepts this same expression as its input.
CFDI version:
'3.2', '3.3', or '4.0'. Controls the format of the query expression built by expression().RFC of the CFDI issuer.
RFC of the CFDI recipient.
Total amount of the CFDI. Commas used as thousands separators are stripped automatically.
The Folio Fiscal (UUID) from the Timbre Fiscal Digital complement.
The CFDI’s
Sello attribute. Only the last 8 characters are used (they always end in == for SHA-256 signatures). Required for CFDI 3.3 and 4.0 expressions; ignored for 3.2.Building from a Cfdi Object
If you already have a parsedCfdiUtils\Cfdi object, use the static factory:
StatusResponse
CfdiUtils\ConsultaCfdiSat\StatusResponse holds the four values returned by the SAT service plus convenience boolean methods.
The raw
CodigoEstatus response. Starts with S - for a successful lookup, or N - for a lookup failure.The CFDI state:
Vigente, Cancelado, or No Encontrado.Whether the CFDI can be cancelled:
No cancelable, Cancelable sin aceptación, or Cancelable con aceptación.Status of any cancellation process: empty,
Cancelado sin aceptación, En proceso, Plazo vencido, Cancelado con aceptación, or Solicitud rechazada.EFOS validation result:
200 (not listed) or 100 (listed as simulated-operations emitter).| Method | Returns true when |
|---|---|
responseWasOk() | getCode() starts with 'S - ' |
isVigente() | getCfdi() === 'Vigente' |
isCancelled() | getCfdi() === 'Cancelado' |
isNotFound() | getCfdi() === 'No Encontrado' |
isEfosListed() | getValidationEfos() === '100' |
Make a Query
Gather the CFDI data
You need the RFC of the issuer, RFC of the recipient, total amount, UUID (Folio Fiscal), and the last 8 characters of the Sello (for CFDI 3.3 and 4.0).
Instantiate WebService and call request()
Pass the
RequestParameters to WebService::request() and receive a StatusResponse.Example: Query from a CFDI file
Example: Query from known data
Understanding the Response
CodigoEstatus (query status)
Reflects whether the SAT was able to find the CFDI given the query expression — not the validity of the CFDI itself.| Value | Meaning |
|---|---|
S - Comprobante obtenido satisfactoriamente | SAT found the CFDI; check getCfdi() for its state |
N - 601: La expresión impresa proporcionada no es válida | The query expression was malformed |
N - 602: Comprobante no encontrado | No CFDI matched the provided data |
Estado (CFDI state)
| Value | Meaning |
|---|---|
Vigente | The CFDI is currently valid |
Cancelado | The CFDI has been cancelled |
No Encontrado | The CFDI does not exist in the SAT database |
EsCancelable
| Value | Meaning |
|---|---|
No cancelable | Cannot be cancelled (e.g. related documents exist) |
Cancelable sin aceptación | Can be cancelled immediately without recipient approval |
Cancelable con aceptación | Can be cancelled but requires the recipient to approve |
EstatusCancelacion
| Value | Meaning |
|---|---|
| (empty) | No cancellation has been requested |
Cancelado sin aceptación | Cancelled; recipient approval was not required |
En proceso | Cancellation requested; awaiting recipient approval |
Plazo vencido | Cancelled automatically because the approval window expired |
Cancelado con aceptación | Cancelled with explicit recipient approval |
Solicitud rechazada | Recipient rejected the cancellation request |
Mutually Exclusive States
CodigoEstatus | Estado | EsCancelable | EstatusCancelacion | Explanation |
|---|---|---|---|---|
N - ... | * | * | * | SAT could not identify the CFDI |
S - ... | Cancelado | * | Plazo vencido | Cancelled by expiry of the approval window |
S - ... | Cancelado | * | Cancelado con aceptación | Cancelled with recipient consent |
S - ... | Cancelado | * | Cancelado sin aceptación | Cancelled without needing recipient consent |
S - ... | Vigente | No cancelable | * | Cannot be cancelled |
S - ... | Vigente | Cancelable sin aceptación | * | Cancellable, no request made yet |
S - ... | Vigente | Cancelable con aceptación | (empty) | Cancellable, no request made yet |
S - ... | Vigente | Cancelable con aceptación | En proceso | Cancellation requested, awaiting approval |
S - ... | Vigente | Cancelable con aceptación | Solicitud rechazada | Cancellation was rejected by recipient |
EFOS (Empresas que Facturan Operaciones Simuladas)
EFOS is a SAT blacklist of companies suspected of issuing invoices for fictitious (“simulated”) operations — i.e., billing for goods or services that were never actually provided. Receiving a CFDI from an EFOS-listed emitter may have tax deduction implications. The web service returns a numeric code inValidacionEFOS:
| Code | Meaning |
|---|---|
200 | Issuer was not found in the EFOS list |
100 | Issuer was found in the EFOS list |
isEfosListed() as a convenient check: