Skip to main content

CFDI cancellations

This guide explains how invoice cancellations work in Facturapi, what each status means, and what to expect after requesting a cancellation.

Requirements and rules

  • You can only cancel invoices with status: "valid".
  • If the invoice is draft, the cancel method deletes it.
  • If the invoice is already canceled or has a cancellation in progress (cancellation_status: "pending" or "verifying"), the method will return an error.

Cancellation motives (SAT) and substitution

The SAT defines cancellation motives, and Facturapi exposes them via the motive parameter. Cancellations use the SAT's new cancellation scheme (effective since 2022).

  • 01: Invoice issued with errors with relation. Requires substitution with the UUID (or Facturapi ID) of the replacing invoice.
  • 02: Invoice issued with errors without relation.
  • 03: Operation not carried out.
  • 04: Nominative operation related to a global invoice.

The SAT expects the motive to match the use case; otherwise the cancellation may fail.

Notes:

  • If you choose motive 01, you must send substitution, and the replacement invoice must exist.
  • If the SAT considers your CFDI non-cancellable (by status or relationships), the request will be rejected even if the motive is valid.

Cancellation flow and statuses

To cancel an invoice, use cancelInvoice with a cancellation motive:

curl "https://www.facturapi.io/v2/invoices/58e93bd8e86eb318b019743d?motive=02" \
-H "Authorization: Bearer sk_test_API_KEY" \
-X DELETE

After calling cancelInvoice, you may get:

  • Success with status: "canceled" and cancellation_status: "accepted" (finalized).
{
"id": "58e93bd8e86eb318b019743d",
"status": "canceled",
"cancellation_status": "accepted",
"uuid": "39c85a3f-275b-4341-b259-e8971d9f8a94"
}
  • Success with status: "valid" and cancellation_status: "pending" (requires receiver approval).
{
"id": "58e93bd8e86eb318b019743d",
"status": "valid",
"cancellation_status": "pending",
"uuid": "39c85a3f-275b-4341-b259-e8971d9f8a94"
}
  • Success with status: "valid" and cancellation_status: "verifying" (SAT received the request and is validating it).
{
"id": "58e93bd8e86eb318b019743d",
"status": "valid",
"cancellation_status": "verifying",
"uuid": "39c85a3f-275b-4341-b259-e8971d9f8a94"
}
  • An error explaining why the cancellation could not be completed.

Meaning of cancellation_status:

StatusMeaningWhat to do
noneNo request registered by the SAT.You can request cancellation if needed.
verifyingSAT received the request and is validating it.Wait for automatic updates or fetch the invoice.
pendingReceiver approval is required.Wait for acceptance/rejection or expiration.
acceptedCancellation was accepted.Invoice moves to status: "canceled".
rejectedCancellation was rejected.Review the motive and retry if applicable.
expiredReceiver did not respond in time.You may retry cancellation if applicable.

Automatic status updates

Facturapi periodically checks the SAT and updates cancellation_status. You can:

  • Fetch the invoice using Get Invoice.
  • Subscribe to the invoice.cancellation_status_updated webhook to receive changes when the status leaves pending or verifying.

Cancellation receipt and verification

When the cancellation is accepted, you can download the cancellation receipt in XML or PDF from the Cancellation receipt endpoint. You can also validate the CFDI using verification_url.

# XML receipt
curl "https://www.facturapi.io/v2/invoices/58e93bd8e86eb318b019743d/cancellation_receipt/xml" \
-H "Authorization: Bearer sk_test_API_KEY" \
-X GET \
-o "cancellation_receipt.xml"

# PDF receipt
curl "https://www.facturapi.io/v2/invoices/58e93bd8e86eb318b019743d/cancellation_receipt/pdf" \
-H "Authorization: Bearer sk_test_API_KEY" \
-X GET \
-o "cancellation_receipt.pdf"

Common errors

  • 409 Conflict: the invoice is not valid or already has a cancellation in progress.
  • 400 Bad Request: invalid motive or missing substitution when required by SAT rules.
  • 404 Not Found: the folio or UUID does not exist in the SAT.