Skip to content

Commit 3d85604

Browse files
authored
Merge pull request #222 from FacturAPI/FAC-1822/document/verifying-cancellation-status
Document verifying cancellation status
2 parents af08570 + 16c3f7c commit 3d85604

6 files changed

Lines changed: 162 additions & 13 deletions

File tree

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
sidebar_position: 10
3+
title: Cancelaciones
4+
---
5+
6+
# Cancelaciones de CFDI
7+
8+
Esta guía explica cómo funciona la cancelación de facturas en Facturapi, qué significa cada estado y qué debes esperar después de solicitar la cancelación.
9+
10+
## Requisitos y reglas
11+
12+
- Solo puedes cancelar facturas con `status: "valid"`.
13+
- Si la factura está en `draft`, el método de cancelar la elimina.
14+
- Si la factura ya está `canceled` o tiene una cancelación en curso (`cancellation_status: "pending"` o `"verifying"`), el método regresará error.
15+
16+
## Motivos de cancelación (SAT) y sustitución
17+
18+
El SAT define **Motivos de cancelación** y Facturapi los expone con el parámetro `motive`. La cancelación usa el **nuevo esquema de cancelación del SAT (vigente desde 2022)**.
19+
20+
- `01`: **Comprobante emitido con errores con relación**. Requiere `substitution` con el UUID (o ID de Facturapi) de la factura que sustituye a la anterior.
21+
- `02`: **Comprobante emitido con errores sin relación**.
22+
- `03`: **No se llevó a cabo la operación**.
23+
- `04`: **Operación nominativa relacionada en una factura global**.
24+
25+
El SAT exige que el motivo sea coherente con el caso de uso; si no, la cancelación puede fallar.
26+
27+
Notas:
28+
29+
- Si eliges el Motivo `01`, debes enviar `substitution` y esa factura debe existir.
30+
- Si el SAT considera que tu CFDI no es cancelable (por su estatus o relaciones), la solicitud será rechazada aunque el Motivo sea válido.
31+
32+
## Flujo de cancelación y estados
33+
34+
Después de llamar a `cancelInvoice`, puede ocurrir:
35+
36+
- Respuesta exitosa con `status: "canceled"` y `cancellation_status: "accepted"` (cancelación finalizada).
37+
- Respuesta exitosa con `status: "valid"` y `cancellation_status: "pending"` (requiere aceptación del receptor).
38+
- Respuesta exitosa con `status: "valid"` y `cancellation_status: "verifying"` (el SAT recibió la solicitud y la está validando).
39+
- Error con la explicación de por qué no se pudo cancelar.
40+
41+
Significado de `cancellation_status`:
42+
43+
| Estado | Significado | Qué hacer |
44+
|:--|:--|:--|
45+
| `none` | No hay solicitud registrada por el SAT. | Puedes solicitar la cancelación si aplica. |
46+
| `verifying` | El SAT recibió la solicitud y la está validando. | Espera la actualización automática o consulta el invoice. |
47+
| `pending` | Requiere aceptación del receptor. | Espera aceptación/rechazo o expiración. |
48+
| `accepted` | La cancelación fue aceptada. | La factura queda en `status: "canceled"`. |
49+
| `rejected` | La cancelación fue rechazada. | Revisa el motivo y vuelve a intentar si aplica. |
50+
| `expired` | El receptor no respondió a tiempo. | Puedes intentar cancelar de nuevo si aplica. |
51+
52+
## Actualización automática del estado
53+
54+
Facturapi consulta periódicamente el SAT y actualiza `cancellation_status`. Puedes:
55+
56+
- Consultar la factura con [Obtener Factura](/api/#tag/invoice/operation/getInvoice).
57+
- Suscribirte al webhook `invoice.cancellation_status_updated` para recibir cambios cuando el estado deje de estar `pending` o `verifying`.
58+
59+
## Acuse de cancelación y verificación
60+
61+
Cuando la cancelación es aceptada, puedes descargar el acuse en XML o PDF desde el endpoint de [Cancellation receipt](/api/#tag/invoice/operation/downloadCancellationReceiptXml). También puedes validar el CFDI con `verification_url`.
62+
63+
## Errores comunes
64+
65+
- `409 Conflict`: la factura no está en `valid` o ya tiene una cancelación en curso.
66+
- `400 Bad Request`: motivo inválido o falta `substitution` cuando el SAT lo requiere.
67+
- `404 Not Found`: el folio o UUID no existe en el SAT.

website/docs/guides/invoices/index.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,6 @@ para indicar que el pago se realizó a una factura de venta a crédito.
4040

4141
Puedes leer más sobre documentos relacionados en la [sección de documentos relacionados](/docs/guides/invoices/relacionados).
4242

43+
## Cancelaciones
44+
45+
El SAT requiere motivos específicos y, en ciertos casos, la aceptación del receptor. Consulta el flujo completo, estados y recomendaciones en la [guía de cancelaciones](/docs/guides/invoices/cancelaciones).
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
sidebar_position: 10
3+
title: Cancellations (Cancelaciones)
4+
---
5+
6+
# CFDI cancellations
7+
8+
This guide explains how invoice cancellations work in Facturapi, what each status means, and what to expect after requesting a cancellation.
9+
10+
## Requirements and rules
11+
12+
- You can only cancel invoices with `status: "valid"`.
13+
- If the invoice is `draft`, the cancel method deletes it.
14+
- If the invoice is already `canceled` or has a cancellation in progress (`cancellation_status: "pending"` or `"verifying"`), the method will return an error.
15+
16+
## Cancellation motives (SAT) and substitution
17+
18+
The SAT defines **cancellation motives**, and Facturapi exposes them via the `motive` parameter. Cancellations use the **SAT's new cancellation scheme (effective since 2022)**.
19+
20+
- `01`: **Invoice issued with errors with relation**. Requires `substitution` with the UUID (or Facturapi ID) of the replacing invoice.
21+
- `02`: **Invoice issued with errors without relation**.
22+
- `03`: **Operation not carried out**.
23+
- `04`: **Nominative operation related to a global invoice**.
24+
25+
The SAT expects the motive to match the use case; otherwise the cancellation may fail.
26+
27+
Notes:
28+
29+
- If you choose motive `01`, you must send `substitution`, and the replacement invoice must exist.
30+
- If the SAT considers your CFDI non-cancellable (by status or relationships), the request will be rejected even if the motive is valid.
31+
32+
## Cancellation flow and statuses
33+
34+
After calling `cancelInvoice`, you may get:
35+
36+
- Success with `status: "canceled"` and `cancellation_status: "accepted"` (finalized).
37+
- Success with `status: "valid"` and `cancellation_status: "pending"` (requires receiver approval).
38+
- Success with `status: "valid"` and `cancellation_status: "verifying"` (SAT received the request and is validating it).
39+
- An error explaining why the cancellation could not be completed.
40+
41+
Meaning of `cancellation_status`:
42+
43+
| Status | Meaning | What to do |
44+
|:--|:--|:--|
45+
| `none` | No request registered by the SAT. | You can request cancellation if needed. |
46+
| `verifying` | SAT received the request and is validating it. | Wait for automatic updates or fetch the invoice. |
47+
| `pending` | Receiver approval is required. | Wait for acceptance/rejection or expiration. |
48+
| `accepted` | Cancellation was accepted. | Invoice moves to `status: "canceled"`. |
49+
| `rejected` | Cancellation was rejected. | Review the motive and retry if applicable. |
50+
| `expired` | Receiver did not respond in time. | You may retry cancellation if applicable. |
51+
52+
## Automatic status updates
53+
54+
Facturapi periodically checks the SAT and updates `cancellation_status`. You can:
55+
56+
- Fetch the invoice using [Get Invoice](/api/#tag/invoice/operation/getInvoice).
57+
- Subscribe to the `invoice.cancellation_status_updated` webhook to receive changes when the status leaves `pending` or `verifying`.
58+
59+
## Cancellation receipt and verification
60+
61+
When the cancellation is accepted, you can download the cancellation receipt in XML or PDF from the [Cancellation receipt](/api/#tag/invoice/operation/downloadCancellationReceiptXml) endpoint. You can also validate the CFDI using `verification_url`.
62+
63+
## Common errors
64+
65+
- `409 Conflict`: the invoice is not `valid` or already has a cancellation in progress.
66+
- `400 Bad Request`: invalid motive or missing `substitution` when required by SAT rules.
67+
- `404 Not Found`: the folio or UUID does not exist in the SAT.

website/i18n/en/docusaurus-plugin-content-docs/current/guides/invoices/index.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,6 @@ para indicar que el pago se realizó a una factura de venta a crédito.
4040

4141
Puedes leer más sobre documentos relacionados en la [sección de documentos relacionados](/docs/guides/invoices/relacionados).
4242

43+
## Cancelaciones
44+
45+
El SAT requiere motivos específicos y, en ciertos casos, la aceptación del receptor. Consulta el flujo completo, estados y recomendaciones en la [guía de cancelaciones](/docs/guides/invoices/cancelaciones).

website/openapi_v1.yaml

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,19 +1517,24 @@ paths:
15171517
- invoice
15181518
summary: Cancelar factura
15191519
description: |
1520-
Realiza una solicitud de cancelación de factura ante el SAT, soportando el esquema de cancelación 2022.
1520+
Realiza una solicitud de cancelación de factura ante el SAT, soportando el **nuevo esquema de cancelación del SAT (vigente desde 2022)**.
15211521
1522-
Al usar este método pueden ocurrir 3 posibles resultados:
1522+
Al usar este método pueden ocurrir los siguientes resultados:
15231523
15241524
- Que la llamada regrese un error con la explicación de por qué no se pudo cancelar.
1525-
- Que la llamada sea satisfactoria y regrese un objeto `invoice` con la propiedad `status: "canceled"`.
1526-
- Que la llamada sea satisfactoria, pero que la cancelación requiera de confirmación de parte de tu cliente, en cuyo caso se obtendrá como respuesta el objeto `invoice` con las propiedades `status: "valid"` y `cancellation_status: "pending"`.
1525+
- Que la llamada sea satisfactoria y regrese un objeto `invoice` con la propiedad `status: "canceled"` (la cancelación ya fue aceptada por el SAT).
1526+
- Que la llamada sea satisfactoria, pero la cancelación requiera confirmación de tu cliente, en cuyo caso se obtendrá como respuesta el objeto `invoice` con las propiedades `status: "valid"` y `cancellation_status: "pending"`.
1527+
- Que la llamada sea satisfactoria, pero el SAT responda que la solicitud fue recibida y está en validación, en cuyo caso se obtendrá `status: "valid"` y `cancellation_status: "verifying"`.
15271528
1528-
En el tercer escenario, el valor de `cancellation_status` será actualizado automáticamente por Facturapi cuando tu cliente acepte, rechace o deje expirar la solicitud, de tal manera que al consultar una factura (usando [Obtener Factura](#tag/invoice/operation/getInvoice)), la propiedad `cancellation_status` reflejará el estado más reciente de la soliitud.
1529+
En los escenarios con `pending` o `verifying`, el valor de `cancellation_status` será actualizado automáticamente por Facturapi cuando el SAT o tu cliente acepten, rechacen o dejen expirar la solicitud. Al consultar una factura (usando [Obtener Factura](#tag/invoice/operation/getInvoice)), la propiedad `cancellation_status` reflejará el estado más reciente de la solicitud.
15291530
15301531
Consulta los valores posibles de `cancellation_status` más abajo.
15311532
15321533
Después de la cancelación la factura ya no tendrá validez, el objeto cambiará su `status` a `"canceled"` y seguirá estando disponible para futuras consultas.
1534+
1535+
Si el estatus de la factura es `draft`, este método la elimina.
1536+
1537+
Si el estatus de la factura no es `valid`, este método regresará un error.
15331538
x-codeSamples:
15341539
- lang: Bash
15351540
label: cURL
@@ -5734,12 +5739,13 @@ components:
57345739
type: string
57355740
enum:
57365741
- none
5742+
- verifying
57375743
- pending
57385744
- accepted
57395745
- rejected
57405746
- expired
57415747
description: |
5742-
Estado actual de la solicitud de cancelación, en caso de haberla realizado. Puedes leer más a detalle en la sección de [Cancelar Factura](#tag/invoice/operation/deleteInvoice)).
5748+
Estado actual de la solicitud de cancelación, en caso de haberla realizado. `verifying` indica que el SAT recibió la solicitud y está validándola; Facturapi seguirá consultando hasta que cambie a un estado final. Puedes leer más a detalle en la sección de [Cancelar Factura](#tag/invoice/operation/deleteInvoice)).
57435749
example: none
57445750
verification_url:
57455751
type: string

website/openapi_v2.en.yaml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3116,23 +3116,24 @@ paths:
31163116
- invoice
31173117
summary: Cancel invoice
31183118
description: |
3119-
Creates a cancellation request to the SAT for the specified invoice.
3119+
Creates a cancellation request to the SAT for the specified invoice, using the **SAT's new cancellation scheme (effective since 2022)**.
31203120
3121-
When using this method, 3 possible results can occur:
3121+
When using this method, the following results can occur:
31223122
31233123
- The call returns an error with the explanation of why the cancellation could not be completed.
3124-
- The call is successful and returns an `invoice` object with the property `status: "canceled"`.
3124+
- The call is successful and returns an `invoice` object with the property `status: "canceled"` (the cancellation has already been accepted by the SAT).
31253125
- The call is successful, but the cancellation requires confirmation from your client, in which case the response will be the `invoice` object with the properties `status: "valid"` and `cancellation_status: "pending"`.
3126+
- The call is successful, but the SAT replies that the request was received and is being validated, in which case the response will be `status: "valid"` and `cancellation_status: "verifying"`.
31263127
3127-
In the third scenario, the value of `cancellation_status` will be automatically updated by Facturapi when your client accepts, rejects, or lets the request expire, so that when you query an invoice (using [Get Invoice](#tag/invoice/operation/getInvoice)), the `cancellation_status` property will reflect the most recent status of the request.
3128+
In the `pending` or `verifying` scenarios, the value of `cancellation_status` will be automatically updated by Facturapi when the SAT or your client accepts, rejects, or lets the request expire, so that when you query an invoice (using [Get Invoice](#tag/invoice/operation/getInvoice)), the `cancellation_status` property will reflect the most recent status of the request.
31283129
31293130
Check the possible values of `cancellation_status` below.
31303131
31313132
After the cancellation, the invoice will no longer be valid, the object will change its `status` to `"canceled"` and will still be available for future queries.
31323133
31333134
If the status of the invoice is `draft`, this method will delete it from the database.
31343135
3135-
If the status of the invoice is `canceled`, this method will return an error.
3136+
If the status of the invoice is not `valid`, this method will return an error.
31363137
x-codeSamples:
31373138
- lang: Bash
31383139
label: cURL
@@ -10841,12 +10842,13 @@ components:
1084110842
type: string
1084210843
enum:
1084310844
- none
10845+
- verifying
1084410846
- pending
1084510847
- accepted
1084610848
- rejected
1084710849
- expired
1084810850
description: |
10849-
Current status of the cancellation request, if it has been made. You can read more in the [Cancel Invoice](#tag/invoice/operation/deleteInvoice) section.
10851+
Current status of the cancellation request, if it has been made. `verifying` means the SAT has received the request and is validating it; Facturapi will keep checking until it changes to a final status. You can read more in the [Cancel Invoice](#tag/invoice/operation/deleteInvoice) section.
1085010852
example: none
1085110853
verification_url:
1085210854
type: string
@@ -10994,12 +10996,13 @@ components:
1099410996
type: string
1099510997
enum:
1099610998
- none
10999+
- verifying
1099711000
- pending
1099811001
- accepted
1099911002
- rejected
1100011003
- expired
1100111004
description: |
11002-
Current status of the cancellation request, if it has been made. You can read more in the [Cancel Invoice](#tag/invoice/operation/deleteInvoice) section.
11005+
Current status of the cancellation request, if it has been made. `verifying` means the SAT has received the request and is validating it; Facturapi will keep checking until it changes to a final status. You can read more in the [Cancel Invoice](#tag/invoice/operation/deleteInvoice) section.
1100311006
example: none
1100411007
verification_url:
1100511008
type: string

0 commit comments

Comments
 (0)