FiscalAPI
CFDI: What It Is and How It Works in Mexico

CFDI: What It Is and How It Works in Mexico

2 de abril de 2026

Every commercial transaction in Mexico that needs to be tax-deductible requires a CFDI. If you're building software that handles payments, electronic invoicing, payroll, or logistics in Mexico, this isn't optional. The CFDI is the backbone of the country's entire tax compliance system, and understanding how it works will save you from a lot of rejected stamps and confused clients.

What is a CFDI

CFDI stands for Comprobante Fiscal Digital por Internet, which translates to Digital Tax Receipt via Internet. It's an XML document that records a taxable transaction, digitally signed by the issuer and certified by a government-authorized provider called a PAC (Proveedor Autorizado de Certificacion).

Here's what trips up most people outside Mexico: CFDI doesn't just mean "invoice." An invoice is one type of CFDI. But payroll receipts, credit notes, payment confirmations, and goods transfer documents are all CFDIs too. The term covers every standardized fiscal document that the SAT (Mexico's tax authority, like the IRS) uses to track economic activity.

The current version is CFDI 4.0, mandatory since January 2023. No PAC will stamp anything in an older format.

How CFDI works

The issuance flow involves three parties: the issuer (you), the PAC, and the SAT.

The critical step is the timbrado (stamping). When the PAC validates your XML and everything checks out, it assigns a UUID (the folio fiscal) and attaches a digital tax stamp (sello digital). That UUID becomes the permanent identifier for the document. Cancellations, status queries, verification, everything references that UUID.

The PAC does more than stamp. It validates that the issuer's RFC is active, that the tax regime matches what's registered with SAT, that the usage codes and payment form codes exist in the current catalog. One wrong code and the whole thing gets rejected.

Nobody builds the XML by hand in production. You either use invoicing software or an API like Fiscalapi that handles XML construction, PAC communication, and returns the stamped CFDI ready to deliver.

Types of CFDI

The typeCode field determines what kind of fiscal document you're issuing. Each type serves a different purpose.

The standard sales invoice. You issue this when you charge for a product or service. If a client buys a software license for $5,000 MXN, you generate an Ingreso CFDI with the amount, applicable taxes (IVA, ISR withholding if relevant), and the client's fiscal data.

This is the type most people mean when they say "factura."

Anatomy of a CFDI

A CFDI has dozens of fields, but these are the ones that determine whether your stamp request gets accepted or rejected.

1

RFC (issuer and recipient)#

The RFC (Registro Federal de Contribuyentes) is Mexico's tax ID. Both parties need one. In CFDI 4.0, you also need the recipient's exact legal name as it appears in their Constancia de Situacion Fiscal (tax status certificate). One character off and the PAC rejects the stamp.

2

Tax regime#

Both issuer and recipient must declare their tax regime code. 601 for General de Ley Personas Morales (standard corporate), 612 for Personas Fisicas con Actividades Empresariales (sole proprietors), 616 for Sin Obligaciones Fiscales (general public). The regime must match what's registered with SAT. Getting the tax regime wrong is one of the top reasons stamps get rejected in production.

3

CFDI usage code#

The recipient declares what they'll use the receipt for. G03 for general expenses, G01 for merchandise acquisition, S01 for no fiscal effect. This affects how the recipient deducts the expense, so it's not a field to fill randomly.

4

Payment form vs. payment method#

Two fields that everyone confuses at first. Payment form (paymentFormCode) is how you got paid: 01 cash, 03 wire transfer, 04 credit card, 99 to be defined. Payment method (paymentMethodCode) is when: PUE (single payment) or PPD (deferred/installment).

If you set payment form 99 with method PUE, the PAC will reject it. Form 99 only works with PPD.

5

Line items#

Each line describes a product or service with its SAT product key (prodServCode), unit of measure (unitCode), quantity, unit price, and applicable taxes. The product key comes from SAT's catalog, which has thousands of entries.

The most common production error is a recipient name mismatch. "EMPRESA SA DE CV" is not the same as "EMPRESA, S.A. DE C.V." for stamping purposes. Always verify the recipient's fiscal data against their Constancia de Situacion Fiscal before issuing.

CFDI 4.0: the current version

Version 4.0 became mandatory on January 1, 2023. The biggest changes from 3.3 hit the recipient data requirements hard.

Previously, you could get away with just the recipient's RFC and a generic usage code. Now you need their full legal name, RFC, fiscal domicile (zip code), and tax regime. This broke integrations everywhere because most systems didn't collect that level of detail from clients. For companies building tax compliance into their software, it meant reworking entire onboarding flows to capture the extra fields.

A mandatory export field was added to every CFDI, even if you don't export anything (set it to 01 - Not Applicable in that case).

Cancellation rules changed significantly. You can no longer cancel a CFDI unilaterally after 24 hours. The recipient has to accept the cancellation, except for amounts under $1,000 MXN.

Starting in 2026, every CFDI must back a real, existing operation. The SAT calls this "materialidad" (materiality): they can now verify that the transaction actually occurred. A stamped CFDI alone isn't proof of anything anymore; you need to demonstrate that the service was rendered or the product was delivered.

CFDI frequently asked questions

Issuing a CFDI with Fiscalapi

Building the XML, validating against SAT's catalog, communicating with the PAC, handling the response: doing all of this from scratch is not a good use of your time. Fiscalapi wraps the entire flow into a single API call.

var fiscalapi = FiscalApiClient.Create(settings => {
    settings.ApiUrl = "https://test.fiscalapi.com";
    settings.ApiKey = "YOUR_API_KEY";
    settings.Tenant = "YOUR_TENANT";
});

var invoice = await fiscalapi.Invoices.CreateAsync(new Invoice {
    VersionCode = "4.0",
    Series = "F",
    TypeCode = "I",
    PaymentFormCode = "03",
    PaymentMethodCode = "PUE",
    CurrencyCode = "MXN",
    ExpeditionZipCode = "42501",
    Issuer = new InvoiceIssuer { Id = "ISSUER_ID" },
    Recipient = new InvoiceRecipient { Id = "RECIPIENT_ID" },
    Items = new List<InvoiceItem> {
        new InvoiceItem {
            Id = "PRODUCT_ID",
            Quantity = 1
        }
    }
});

Fiscalapi handles the stamping, PDF generation, and storage. The stamped XML and UUID come back in the response. Cancellations, status checks, and PDF downloads all use the same invoice id from the response.

The sandbox environment at test.fiscalapi.com lets you stamp CFDIs at no cost with no fiscal consequences. It simulates SAT's full behavior, including RFC and tax regime validation. Use it before pointing anything at production. The full API documentation covers every endpoint from issuance to cancellation.