Generate CFDI 4.0 Invoice XML (Comprobante)
Skill: Convert a sale into a CFDI 4.0 Comprobante XML stamped by a PAC
Region: Mexico (México)
Category: E-Invoicing — Comprobante Fiscal Digital por Internet (CFDI)
Does: Takes ordinary sale/invoice data and produces the CFDI 4.0 cfdi:Comprobante XML (SAT Anexo 20) — Emisor, Receptor, Conceptos, Impuestos — then sends it to a PAC for timbrado, which returns the TimbreFiscalDigital complemento carrying the UUID (folio fiscal).
Standard: SAT CFDI 4.0 (Anexo 20) + TimbreFiscalDigital 1.1
A CFDI is not valid until it is stamped (timbrado) by an authorized PAC (Proveedor Autorizado de Certificación). You build the unstamped
cfdi:Comprobante, seal it with your CSD (Certificado de Sello Digital) to produce theSello, then the PAC validates it, stamps it, and adds thetfd:TimbreFiscalDigitalwith the SAT UUID. All RFCs, claves and códigos must come from the current SAT catálogos (catCFDI). Validate against the Anexo 20 XSD before sending.
When this applies
- Any sale of goods or services, or other taxable operation, that must be invoiced in Mexico (B2B, B2C with the generic
XAXX010101000, exports, etc.). - The CFDI must be issued at the time of the operation and stamped within the SAT-mandated window; the receiver uses the UUID to deduct/credit the operation.
- Use
TipoDeComprobante = I(Ingreso) for a normal sale invoice. Egreso (E), Traslado (T), Nómina (N) and Pago (P) use other types/complementos.
Input data required
| Input | CFDI 4.0 node / attribute |
|---|---|
| Issuer RFC, name, tax regime | Emisor@Rfc, @Nombre, @RegimenFiscal (catálogo c_RegimenFiscal) |
| Issue place (ZIP) | Comprobante@LugarExpedicion (código postal) |
| Receiver RFC, name, regime, ZIP, CFDI use | Receptor@Rfc, @Nombre, @RegimenFiscalReceptor, @DomicilioFiscalReceptor, @UsoCFDI (catálogo c_UsoCFDI) |
| Document data | @Folio, @Serie, @Fecha, @TipoDeComprobante, @Moneda, @FormaPago, @MetodoPago, @Exportacion |
| Each line | Concepto@ClaveProdServ, @ClaveUnidad, @Cantidad, @Descripcion, @ValorUnitario, @Importe, @ObjetoImp |
| Taxes per line | Concepto/Impuestos/Traslados/Traslado (IVA, Base, TipoFactor, TasaOCuota, Importe) |
| CSD | @NoCertificado, @Certificado, @Sello (sealed before timbrado) |
Mexican specifics: the receiver's Nombre, RegimenFiscalReceptor and DomicilioFiscalReceptor (ZIP) must match the receiver's Constancia de Situación Fiscal, or the PAC rejects the stamp. ObjetoImp declares whether the line is subject to tax (02 = sí objeto).
Document structure (cfdi:Comprobante)
cfdi:Comprobante (Version=4.0, Fecha, TipoDeComprobante, Moneda, SubTotal, Total, LugarExpedicion, Sello, NoCertificado, Certificado)
├── cfdi:Emisor (Rfc, Nombre, RegimenFiscal)
├── cfdi:Receptor (Rfc, Nombre, DomicilioFiscalReceptor, RegimenFiscalReceptor, UsoCFDI)
├── cfdi:Conceptos
│ └── cfdi:Concepto (ClaveProdServ, ClaveUnidad, Cantidad, Descripcion, ValorUnitario, Importe, ObjetoImp)
│ └── cfdi:Impuestos/cfdi:Traslados/cfdi:Traslado (Base, Impuesto=002, TipoFactor=Tasa, TasaOCuota=0.160000, Importe)
├── cfdi:Impuestos (TotalImpuestosTrasladados; Traslados summary)
└── cfdi:Complemento
└── tfd:TimbreFiscalDigital (UUID, FechaTimbrado, RfcProvCertif, SelloCFD, NoCertificadoSAT, SelloSAT) ← added by PAC
Impuesto codes: 002 = IVA, 003 = IEPS, 001 = ISR (retención). TipoFactor: Tasa (rate), Cuota (fixed), Exento. IVA general rate is 0.160000; border region 0.080000; 0.000000 for tasa cero.
Calculation rules
- Line
Importe=Cantidad×ValorUnitario(rounded to currency decimals; MXN = 2). SubTotal= sum of lineImporte(before taxes, before discounts).- IVA per line
Importe=Base×TasaOCuota(e.g. 16% → 0.160000). Impuestos/@TotalImpuestosTrasladados= sum of all trasladado tax importes; retenciones reduce the total.Comprobante/@Total= SubTotal − Descuento + traslados − retenciones.- All rate attributes use 6 decimal places (
0.160000); theSellois computed over the cadena original derived from the XML via the Anexo 20 XSLT.
Worked example (TipoDeComprobante I, one line, IVA 16% — pre-timbrado plus TFD)
<?xml version="1.0" encoding="UTF-8"?>
<cfdi:Comprobante
xmlns:cfdi="http://www.sat.gob.mx/cfd/4"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd"
Version="4.0" Serie="A" Folio="1001"
Fecha="2026-06-04T10:15:00" Sello="(sello del CSD)"
FormaPago="03" NoCertificado="30001000000400002463"
Certificado="(certificado base64)" SubTotal="10000.00" Moneda="MXN"
Total="11600.00" TipoDeComprobante="I" Exportacion="01"
MetodoPago="PUE" LugarExpedicion="64000">
<cfdi:Emisor Rfc="AAA010101AAA" Nombre="ACME SA DE CV" RegimenFiscal="601"/>
<cfdi:Receptor Rfc="XEXX010101000" Nombre="CLIENTE EJEMPLO SA DE CV"
DomicilioFiscalReceptor="06000" RegimenFiscalReceptor="601" UsoCFDI="G03"/>
<cfdi:Conceptos>
<cfdi:Concepto ClaveProdServ="81111500" ClaveUnidad="E48" Cantidad="1"
Descripcion="Servicios de consultoria" ValorUnitario="10000.00"
Importe="10000.00" ObjetoImp="02">
<cfdi:Impuestos>
<cfdi:Traslados>
<cfdi:Traslado Base="10000.00" Impuesto="002" TipoFactor="Tasa"
TasaOCuota="0.160000" Importe="1600.00"/>
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Concepto>
</cfdi:Conceptos>
<cfdi:Impuestos TotalImpuestosTrasladados="1600.00">
<cfdi:Traslados>
<cfdi:Traslado Base="10000.00" Impuesto="002" TipoFactor="Tasa"
TasaOCuota="0.160000" Importe="1600.00"/>
</cfdi:Traslados>
</cfdi:Impuestos>
<cfdi:Complemento>
<tfd:TimbreFiscalDigital
xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital"
Version="1.1" UUID="A1B2C3D4-E5F6-4789-ABCD-1234567890AB"
FechaTimbrado="2026-06-04T10:15:30" RfcProvCertif="PAC010101AAA"
SelloCFD="(sello del CFD)" NoCertificadoSAT="00001000000500000123"
SelloSAT="(sello del SAT)"/>
</cfdi:Complemento>
</cfdi:Comprobante>
The tfd:TimbreFiscalDigital (and its UUID/folio fiscal) is returned by the PAC after a successful timbrado; you do not generate it yourself.
Validation checklist
-
Version="4.0"; correctTipoDeComprobante(Ifor sale) and@Exportacion - Emisor
Rfc+RegimenFiscalvalid; ReceptorRfc,Nombre,RegimenFiscalReceptor,DomicilioFiscalReceptormatch the Constancia de Situación Fiscal -
UsoCFDIconsistent with the receiver's regime; validClaveProdServandClaveUnidadfrom current catálogos - Each
ConceptohasObjetoImp; taxed lines carryTraslado(Impuesto002, TasaOCuota0.160000) with rates to 6 decimals -
SubTotal/Totalreconcile with line importes andImpuestossummary;FormaPago/MetodoPago(PUE/PPD) consistent -
Sellocomputed from the cadena original (Anexo 20 XSLT) with a valid CSD; passes Anexo 20 XSD validation - PAC timbrado succeeds and
tfd:TimbreFiscalDigitalwithUUIDis present
Last updated: 2026-06-04 — confirm the active CFDI/SAT schema version, catálogos, and PAC/portal requirements against the current SAT specifications before use.