Skip to main content

The problem with duplicates

When your system issues an invoice and the connection drops before receiving the response, should you retry? If you do so without precautions, you could generate two identical invoices registered with the SAT. Idempotency is the property that guarantees that sending the same request more than once produces the same result: a single invoice, not several.

The technical foundation: original string and seal

Original String

The SAT defines a concatenation format (via an XSLT) that converts all CFDI fields into a single plain-text string. That string is the Original String. It includes, among other fields:
  • Version
  • Date
  • Seal
  • PaymentForm
  • CertificateNumber
  • Certificate
  • Subtotal
  • Currency
  • Total
  • Receipt Type
  • Export
  • Payment Method
  • PlaceOfIssue
  • Issuer data
  • Receiver data
  • Line items and their details (description, quantity, unit value, amount, etc.)
  • Taxes (transferred and withheld).
An example fragment of the original string might look like this:

Issuer’s Digital Seal

The Original String is processed with SHA-256 and the result is signed with the issuer’s CSD private key using RSA:
This seal guarantees three properties:

PAC validation

Before certifying the CFDI, the PAC verifies:
  1. The XML structure is valid (SAT XSD schemas)
  2. The DigitalSeal corresponds to the issuer’s CSD
  3. The CFDI was not previously stamped (uniqueness)
If the same XML reaches the PAC twice, the second attempt is rejected because the seal was already registered.

The UUID as a unique identifier

The PAC generates a UUID (Folio Fiscal) when stamping. This UUID is unique nationwide and is registered with the SAT:
It is the definitive value to identify a CFDI. It cannot be repeated, it cannot be reused, and it remains in the SAT records even if the CFDI is cancelled.

How idempotency works in API Web

The Facturama API Web (a single issuer RFC) has three fields that, if not specified, are automatically generated on every call: If you omit these fields and make two calls with the same JSON, Facturama generates two different CFDIs because Date and Folio change. This breaks idempotency.

How to implement idempotency in API Web

Explicitly specify the three fields before sending: Folio, Date, and for Carta Porte IdCCP
With Date and Folio fixed, the resulting XML is identical on every retry. The PAC will detect the duplicate and reject the second attempt, and the API will show the invoice that had already been stamped with the same data.
You can use the Folio as an idempotency key in your database. If a CFDI with that folio already exists, do not send it again.

The IdCCP field

For CFDIs with the Carta Porte complement, there is an additional field IdCCP that identifies the carta porte:
If you do not specify it, a new one is generated on every call. Specify it to ensure the Carta Porte complement is identical across retries.

When to use idempotency

Apply the idempotency strategy when the error is recoverable by retrying:
On a 5xx error or a timeout, do not assume the invoice was not created. First check whether a CFDI with that folio exists before retrying. If it already exists, use the existing UUID.
For the Multi-issuer API, use type = issedLite