The SAT requires a formal, two-step cancellation process for stamped CFDIs — you cannot simply void a document or delete the XML. ERPNext Mexico Compliance handles this by submitting a signed cancellation request to the SAT via the TI Sin Problemas web service, recording the acknowledgement XML, and then automatically cancelling the ERPNext document once the SAT confirms the cancellation. Until the SAT approves the cancellation, the document remains in Submitted status withDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/TI-Sin-Problemas/erpnext_mexico_compliance/llms.txt
Use this file to discover all available pages before exploring further.
mx_cfdi_status set to Pending Cancellation.
Cancellation reasons
The SAT mandates that every cancellation request include one of four official reason codes. These are stored in the Cancellation Reason DocType, which is pre-loaded with the following fixture data:| Code | Description (Spanish) | Requires Substitute |
|---|---|---|
01 | Comprobante emitido con errores con relación | ✅ Yes |
02 | Comprobante emitido con errores sin relación | No |
03 | No se llevó a cabo la operación | No |
04 | Operación nominativa relacionada con una factura global | No |
requires_relationship flag on each Cancellation Reason record controls whether a substitute document must be specified before the cancellation request is submitted. Reason 01 requires you to reference the corrected replacement CFDI; reasons 02, 03, and 04 do not.
The Cancellation Reason DocType uses
code as its naming field. Codes are two-digit strings (01–04) matching the SAT catalog.Cancel a Sales Invoice
Open the submitted Sales Invoice
Navigate to the stamped Sales Invoice. The Cancel button is present on all submitted invoices; however, for stamped invoices the cancellation flow goes through the SAT rather than directly cancelling in ERPNext.
Set the Cancellation Reason
In the Cancellation Reason field, select the appropriate SAT reason code. If you leave this field blank, the app throws a validation error: “A Cancellation Reason is required to cancel this sales invoice.”
Set the Substitute Invoice (if required)
If you selected reason
01 (issued with errors, with relationship), the Substitute Invoice (substitute_invoice) field becomes required. Set it to the name of the corrected Sales Invoice that replaces the one being cancelled. The app reads the substitute’s mx_uuid and includes it in the cancellation request sent to the SAT.Click Cancel and select a certificate
Click the Cancel button. Because the invoice is stamped, you are prompted to select a Digital Signing Certificate for the Company. After selecting the certificate, the
cancel method routes to cancel_cfdi(certificate, "substitute_invoice").Cancellation request is submitted
The app posts the cancellation request to
tisp_apps.api.v1.cfdi.cancel, passing the CSD key and certificate, UUID, issuer and receiver RFCs, total amount, cancellation reason code, and substitute UUID (if applicable). The web service returns a cancellation acknowledgement XML.Document enters Pending Cancellation
The acknowledgement XML is stored in
cancellation_acknowledgement, and mx_cfdi_status is set to Pending Cancellation. The document is saved but not yet cancelled in ERPNext. A message confirms: “This Document will be cancelled once the CFDI cancellation request is approved.”Cancel a Payment Entry
The cancellation flow for Payment Entries is identical to Sales Invoices, with one difference: the substitute field is named Substitute Payment Entry (substitute_payment_entry) instead of Substitute Invoice.
Set the Cancellation Reason
Select the SAT cancellation reason code in the Cancellation Reason field.
Set the Substitute Payment Entry (if required)
If the reason is
01, set the Substitute Payment Entry field to the replacement Payment Entry. The app reads its mx_uuid and sends it as the substitute UUID in the cancellation request.Click Cancel and select a certificate
Click Cancel and select the Digital Signing Certificate when prompted. The
cancel method detects that the entry is stamped and routes to cancel_cfdi(certificate, "substitute_payment_entry").Cancellation status tracking
The SAT does not always approve cancellations immediately. Some cancellations (particularly those requiring recipient acceptance) can remain pending for up to 72 hours. ERPNext Mexico Compliance reconciles the status automatically through a scheduled task. Scheduled reconciliation: Thecheck_cancellation_status task runs hourly (configured in hooks.py) and queries all Sales Invoices and Payment Entries whose mx_cfdi_status is Pending Cancellation. For each document, it calls update_cancellation_status, which queries the web service’s tisp_apps.api.v1.cfdi.status endpoint. If the SAT reports the document as Cancelado (Cancelled), update_cancellation_status sets mx_cfdi_status to Cancelled and triggers the native ERPNext _cancel operation on the document.
Manual status check:
You can also trigger a status check on demand by clicking the Check Cancellation Status button on any document that has a pending cancellation acknowledgement. This calls the check_cancellation_status whitelisted controller method, which queries the same web service endpoint and displays the response in a dialog showing:
- CFDI Code
- CFDI Status (e.g., Vigente / Cancelado)
- Is Cancellable (e.g., Cancelable con aceptación / No cancelable)
- Cancellation Status (e.g., En proceso / Cancelado con aceptación)
CFDIStatus values
| Value | Meaning |
|---|---|
| Valid | The CFDI is active and accepted by the SAT. The document is fully submitted in ERPNext. |
| Pending Cancellation | A cancellation request has been submitted to the SAT. The ERPNext document is still open; the SAT approval is outstanding. |
| Cancelled | The SAT has confirmed the cancellation. ERPNext has automatically cancelled the document. |
Cancellation acknowledgement
When a cancellation request is accepted by the web service, the SAT returns an acknowledgement XML. This XML is stored in thecancellation_acknowledgement field on the document (both Sales Invoice and Payment Entry).
You can view the raw ACK XML directly from the document form by inspecting the cancellation_acknowledgement HTML editor field. The ack_cancellation_element property on the controller also parses it into an lxml.etree.Element for programmatic use if needed.