Cancelación de CFDI
Para cancelar un CFDI, el emisor envía al SAT una solicitud firmada con su CSD, y Fiscalapi la envía por ti. En el esquema vigente, cada solicitud lleva un motivo de cancelación y, según la factura, el receptor puede tener que aceptarla, así que la cancelación no siempre es inmediata. Este tutorial explica las reglas del SAT y cómo Fiscalapi te informa el resultado. Las peticiones y las respuestas están en Cancelar factura.
Motivos de cancelación
Envía el motivo en cancellationReasonCode. El detalle de cada motivo está en el catálogo de motivos de cancelación.
| Motivo | Cuándo usarlo | Qué pide |
|---|---|---|
"01" | La factura tiene errores y la sustituyes con una nueva. | Emite primero la sustituta, relacionada con la original con el tipo de relación "04", y envía su UUID en replacementUuid. |
"02" | La factura tiene errores y no la sustituyes, por ejemplo porque el RFC del receptor está equivocado. | Solo el motivo. Si hace falta, emite después la factura correcta. |
"03" | La operación no se llevó a cabo. | Solo el motivo. |
"04" | Una venta incluida en una factura global se factura de forma nominativa. | Cancela la factura global, reexpídela sin esa venta y emite la factura nominativa. |
Una factura con al menos un documento relacionado vigente es No cancelable. La excepción es el motivo "01": la original queda No cancelable al relacionarse con su sustituta, y ese vínculo se rompe al solicitar su cancelación.
Aceptación del receptor
Según la factura, el SAT la cancela sin intervención del receptor o le pide al receptor que acepte la cancelación. Antes de cancelar, usa Consultar estado de factura: cancelableStatus indica si la factura es cancelable sin aceptación, con aceptación o no cancelable.
El SAT no pide la aceptación del receptor en estos supuestos de la regla 2.7.1.35 de la Resolución Miscelánea Fiscal:
| Supuesto | Facturas |
|---|---|
| Monto | Las que amparan un total de hasta $1,000.00 M.N. |
| Plazo | Las que se cancelan a más tardar el día hábil siguiente a su emisión. |
| Tipo de comprobante | Nómina, egreso, traslado, y CFDI de retenciones e información de pagos. |
| Receptor | Operaciones con el público en general, facturas a residentes en el extranjero y CFDI de ingreso a contribuyentes del RIF. |
| Emisor u origen | Emitidas en Mis cuentas, por integrantes del sistema financiero o por la Federación por derechos, productos y aprovechamientos, y CFDI a través del adquirente y del sector primario (reglas 2.7.3.10 y 2.7.4.1 de la RMF). |
El SAT exceptúa de estos supuestos los CFDI con complemento para recepción de pagos, sin importar su monto. También exceptúa los CFDI de hidrocarburos y petrolíferos: los que llevan su complemento y los de Carta Porte con las claves de producto 15101505, 15101514 o 15101515.
En los demás casos, el SAT avisa al receptor por buzón tributario, y el receptor tiene tres días hábiles para aceptar o rechazar la solicitud. Si no responde a la primera solicitud, el SAT la da por aceptada y cancela la factura. Si el receptor rechazó la primera solicitud y no responde a una segunda o posterior, la cancelación no procede: la factura sigue vigente hasta que el receptor acepte.
Estados de la solicitud en el SAT
La consulta del SAT devuelve el Estado de la factura y el Estatus de cancelación de la solicitud. En la API llegan en status y cancellationStatus de Consultar estado de factura.
| Estado | Estatus de cancelación | Significado |
|---|---|---|
| Vigente | vacío | No hay solicitud de cancelación. |
| Vigente | En proceso | El receptor tiene la solicitud y aún no responde. |
| Vigente | Solicitud rechazada | El receptor rechazó la cancelación. |
| Vigente | Plazo vencido | El receptor no respondió a una segunda solicitud o posterior. La cancelación no procede. |
| Cancelado | Cancelado sin aceptación | El SAT canceló la factura sin requerir la aceptación del receptor. |
| Cancelado | Cancelado con aceptación | El receptor aceptó la cancelación. |
| Cancelado | Plazo vencido | El receptor no respondió a la primera solicitud y el SAT la dio por aceptada. |
Con Estado No Encontrado, el SAT no encontró la factura con los datos de la consulta. Una factura recién timbrada puede tardar en aparecer.
Cómo lo gestiona Fiscalapi
Respuesta de la solicitud
Envía la solicitud con Cancelar factura. Antes de enviarla al SAT, Fiscalapi valida la factura, el motivo, la sustituta y los certificados del emisor. Si algo falla, responde con un error, por ejemplo un 400 de validación, y no envía la cancelación.
| Respuesta del SAT | Respuesta de Fiscalapi |
|---|---|
| Recibió la solicitud (201 o 202). | 200. La factura Vigente pasa a Cancelando. |
| Rechazó la solicitud. | 422, con details en la forma SAT <código>: <descripción>. La factura no cambia de estado. |
Un 200 indica que el SAT recibió la solicitud, no que la factura ya esté cancelada. Para un 422, consulta los códigos de rechazo del SAT y qué hacer ante un rechazo.
Estados de la factura
| Código | Estado | Significado |
|---|---|---|
"V" | Vigente | La factura es válida y acepta una solicitud de cancelación. |
"C" | Cancelando | El SAT recibió la solicitud y Fiscalapi espera su resultado. Acepta otra solicitud. |
"X" | Cancelado | El SAT confirmó la cancelación. La factura no vuelve a otro estado. |
Después de una solicitud aceptada, Fiscalapi consulta al SAT. Pasa la factura a Cancelado cuando el SAT la reporta cancelada, o la regresa a Vigente cuando la cancelación no procede. Mientras el SAT la tiene en proceso, Fiscalapi la consulta al minuto y luego con esperas que se duplican (2, 4, 8 minutos y así en adelante) hasta llegar a una consulta cada 12 horas, durante unos 10 días. Después la consulta una vez al día hasta 30 días después de la última solicitud aceptada. Si en ese plazo el SAT no la resuelve, la factura sigue en Cancelando y acepta otra solicitud.
Seguimiento del resultado
Suscribe un webhook para conocer cada cambio de estado sin consultar la API:
| Evento | Cuándo ocurre |
|---|---|
invoice.cancellation_requested | El SAT recibió la solicitud: la factura pasa de Vigente a Cancelando. |
invoice.canceled | El SAT confirmó la cancelación: la factura pasa de Cancelando a Cancelado. |
invoice.cancellation_rejected | La cancelación no procede: la factura vuelve de Cancelando a Vigente. El motivo llega en data.reason. |
Para leer el estado en el SAT en cualquier momento, usa Consultar estado de factura y lee sus valores con la tabla de estados.
Ambiente de pruebas
En el ambiente de pruebas el SAT es simulado y las facturas no tienen validez fiscal. Una solicitud aceptada se confirma como Cancelado en la primera consulta, alrededor de un minuto después.
Qué hacer ante un rechazo
El rechazo de la solicitud llega en el 422 con el código del SAT. El rechazo posterior llega en invoice.cancellation_rejected, con el motivo en data.reason.
| Rechazo | Qué significa | Qué hacer |
|---|---|---|
| SAT 205 | El SAT aún no refleja la factura porque se timbró hace poco. | Vuelve a solicitar la cancelación más tarde. Puede tardar hasta 48 horas. |
| SAT 203 | El folio fiscal no corresponde al emisor de la solicitud. | Revisa que el RFC y el CSD con que cancelas sean los del emisor de la factura. |
| SAT 312 | Enviaste un folio de sustitución con un motivo que no lo usa. | Quita replacementUuid o usa el motivo "01". |
"rejectedByRecipient" | El receptor rechazó la cancelación. | Acuérdala con el receptor y vuelve a solicitarla. |
"expired" | El receptor no respondió a una segunda solicitud o posterior. | Acuérdala con el receptor: la cancelación procede solo cuando la acepte. |
"notCancelable" | El SAT reporta la factura como no cancelable, por ejemplo porque tiene un documento relacionado vigente. | Cancela primero los documentos relacionados vigentes. Si la factura tiene una sustituta, cancélala con el motivo "01". |
"notRequested" | El SAT no tiene la solicitud de cancelación. | Vuelve a solicitar la cancelación. |
Ejemplo
Esta petición cancela una factura emitida por referencias con el motivo "02", que no lleva replacementUuid.
Request
curl --location --request DELETE 'https://test.fiscalapi.com/api/v4/invoices' \
--header 'X-TENANT-KEY: <tenant>' \
--header 'X-TIME-ZONE: America/Mexico_City' \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <apiKey>' \
--data '{
"id": "21c39425-9d0a-449b-a7ba-49335b85b062",
"cancellationReasonCode": "02"
}'
Si el SAT rechaza la solicitud, Fiscalapi responde 422 con el código del SAT por UUID y el acuse. En este ejemplo el folio fiscal no corresponde al emisor, y el acuse en Base64 está abreviado.
Response
{
"data": {
"base64CancellationAcknowledgement": "PD94bWwgdmVyc2lvbj0iMS4wIj8+...",
"invoiceUuids": {
"<UUID>": "203"
}
},
"succeeded": false,
"message": "Sorry, it's not me, it's you.",
"details": "SAT 203: el folio fiscal no corresponde al emisor de la solicitud de cancelación.",
"httpStatusCode": 422
}