Global invoice for tickets

The global invoice for tickets (ticket: a sales receipt your customer can later turn into a CFDI) covers, in a single CFDI (Mexico's electronic invoice), the Auto CFDI invoicing sales that your customers didn't auto-invoice (auto-invoice: a CFDI your customer requests from a ticket; you remain the issuer). Like any other global invoice (factura global, one CFDI that groups a period's sales to the general public), it's issued to the general public (customers who did not ask for their own CFDI). It also links each line item to its ticket. With that link, Fiscalapi checks that the invoice matches the sales and marks the tickets as invoiced, so nobody can auto-invoice them later.

How it works

You issue the global invoice for tickets with the same request as any other global invoice. The only difference is the ticketId field on each line item, with the ID of the ticket it covers.

StepWhat happens
1At the end of the period, you query the pending tickets of each issuing person (person: any individual or legal entity registered in your tenant).
2You build the global invoice with one line item per ticket and tax group, each with its ticket's ticketId.
3You stamp the global invoice (stamping: the certification by a SAT-authorized provider that makes a CFDI valid). Before it deducts the stamp (one credit, used each time you stamp a CFDI), Fiscalapi reserves all its tickets or none of them, and moves them to globalizing.
4When the CFDI is saved, the tickets move to globalized, with the invoice ID in globalInvoiceId. If the PAC (Proveedor Autorizado de Certificación, a SAT-authorized provider that stamps CFDIs) rejects the CFDI, they return to their previous status and the stamp is refunded.

A validation error or a ticket that's no longer available doesn't use up a stamp or leave tickets reserved. The ticket statuses explain each status value.

A global invoice without ticketId on its line items doesn't mark any ticket: they stay in pending and your customers can auto-invoice them, which invoices the same sale twice. Include the ticketId of every ticket the global invoice covers.

Build the global invoice

Build one global invoice for each combination of issuing person, currency, exchange rate, and place of issue (the postal code where the CFDI is issued): the CFDI carries a single value for each of them, and the postal code of the general public recipient is the place of issue. An invoice accepts at most 1,500 line items; if your tickets need more, split them across several global invoices without splitting a ticket between two of them.

1. Query the pending tickets

Query the issuer's tickets for the period with List tickets and these filters:

FilterValue
statuspending
personIdThe ID of the issuing person.
from and toThe first and last day of the period.
detailstrue, to include the line items with their taxes.

The list is paginated: repeat the query with the next pageNumber while hasNextPage is true.

2. Build one line item per ticket and tax group

Each ticket becomes one line item for each group of its line items with the same tax object (whether an item is subject to tax, ObjetoImp) and the same taxes. Fiscalapi calculates all the taxes of a line item on the same base. So a ticket with products at 16% and 0% IVA (Mexico's value-added tax, VAT) takes two line items, both with the same ticketId.

Line item fieldValue
ticketIdThe ticket's ID.
itemCode01010101
itemSkuThe ticket's folio number (the issuer's own sequential number for the ticket).
quantity1
unitOfMeasurementCodeACT
descriptionVenta
unitPriceThe sum of quantity times unit price for the group's line items.
discountThe sum of the discounts of the group's line items.
taxObjectCode and itemTaxesThe group's values, unchanged.

For each ticket, Fiscalapi compares the sum of its line items in the global invoice against the saved ticket: amounts, discounts, and taxes by tax, factor type, and rate. If they don't match, it returns 400 on the ticketId of the ticket's first line item, without charging.

3. Complete the CFDI

The global invoice for tickets carries the issuer by reference (issuer.id): the issuing person of the tickets. The recipient is the general public, and the form of payment (how the customer paid: cash, bank transfer, card; the FormaPago key) is that of the ticket with the highest amount, according to the guide to filling out the global invoice published by the SAT (Mexico's tax authority, Servicio de Administración Tributaria).

FieldValue
typeCodeI
paymentMethodCodePUE
exportCode01
paymentFormCodeThe form of payment of the ticket with the highest amount.
currencyCode and exchangeRateThe tickets' values. With MXN, the exchange rate is 1.
expeditionZipCodeThe tickets' value.
issuer.idThe ID of the tickets' issuing person.
recipientRFC XAXX010101000, PUBLICO EN GENERAL, tax regime 616, CFDI use S01, and the place-of-issue postal code (RFC: Mexico's taxpayer ID, Registro Federal de Contribuyentes; tax regime: régimen fiscal, the SAT category a taxpayer is registered under, such as 601 or 626; CFDI use: how the recipient will use the CFDI for tax purposes).
globalInformationThe frequency, month, and year of the period. See Global information.

Replace a global invoice for tickets

To exclude tickets from a global invoice you already stamped, for example because a customer asked for their own invoice later, replace it with the standard endpoints (CFDI replacement: you issue a corrected CFDI related to the original with relationship type 04, then cancel the original with reason 01). Issue a new global invoice with the tickets that stay, and cancel the original. The SAT's guide to filling out the global invoice describes this case: the new global invoice leaves out the sale that is invoiced in the customer's name, and it's related to the original by replacement.

 Global original (vigente)            Tickets A, B y C en globalized
            |
            |  1. Crea la sustituta
            |     relatedInvoices: tipo 04 con el UUID de la original
            |     items[].ticketId: solo A y B
            v
 Global sustituta (vigente)           A y B pasan a la sustituta (globalized)
                                      C sigue en globalized en la original
            |
            |  2. Cancela la original
            |     motivo 01 y el UUID de la sustituta
            v
 Original en Cancelando --> el SAT confirma la cancelación
            |
            v
 Original cancelada                   C vuelve a pending

Each step is a request you can retry, and the tickets and invoices hold the state:

StepRequestWhat changes
1Create a global invoice for tickets with relatedInvoices of type 04 and the original's UUID (folio fiscal, the unique ID the PAC assigns when it stamps a CFDI), and the ticketId of the tickets that stay.When the replacement CFDI is saved, its tickets move from the original to it.
2Cancel an invoice on the original with cancellation reason (one of the SAT keys 01 to 04) 01 (issued with errors, replaced by a related CFDI) and the replacement CFDI in replacementUuid.The original moves to Cancelando (canceling) until the SAT confirms.
3None: Fiscalapi checks with the SAT.Once the cancellation is confirmed, the excluded tickets return to pending.

To build the replacement CFDI, query the original's tickets with List tickets, with globalInvoiceId set to the original's ID. Copy the series, the issuing person, the global information, the currency, the exchange rate, and the place of issue from the original, and recalculate the form of payment with the tickets that stay.

While the original is still active, its excluded tickets stay in globalized and the auto-invoice portal doesn't auto-invoice them. When the cancellation of a global invoice is confirmed, each of its tickets returns to the most recent active global invoice that covered it before, or to pending if there's none. For example, if you cancel the replacement CFDI while the original is still active, its tickets return to the original. This way, a sale never stays in pending while an active CFDI covers it.

If the original covered only tickets you're excluding, there's no replacement CFDI: cancel it with the cancellation reason that fits your case, with no related CFDI (a CFDI this one replaces, credits, or pays, with its TipoRelacion key). See the reasons in Cancel an invoice.

Related resources

Was this page helpful?