Parse CFDI 4.0 XML
parse_cfdiConvert Mexican CFDI 4.0 invoice XML into structured JSON with labeled SAT codes, validated RFCs, and checked totals.
Instructions
Turn the XML of a Mexican electronic invoice (CFDI 4.0) into structured JSON: header, issuer, receiver, every line item with its transferred and withheld taxes, the tax totals, and the Timbre Fiscal Digital (UUID, stamp date, SAT certificate number, PAC's RFC) — or timbre: null when the document was never stamped.
Three things this does beyond reading attributes:
It labels the catalogue codes. '601' becomes 'General de Ley Personas Morales', 'G03' becomes 'Gastos en general', 'PPD' becomes 'Pago en parcialidades o diferido'. An unknown code is reported as unknown rather than guessed at.
It validates both RFCs (issuer and receiver) with the full modulus-11 check, and flags the SAT generics.
It checks the arithmetic: subtotal − discount + transferred − withheld should equal the declared total. A mismatch is a warning, not a verdict — rounding at the line level is allowed within a centavo.
It walks the document by local element name, so it does not care whether the PAC used the cfdi: and tfd: prefixes, different ones, or none.
What this does NOT do: it does not verify the digital signature, and it does not ask the SAT anything. A document that parses cleanly can still be cancelled, or have been fabricated wholesale. Use cfdi_status for the SAT's own answer.
Args:
xml (string): the CFDI XML.
response_format ('markdown' | 'json'): output format (default 'markdown').
Returns: { version, serie, folio, fecha, tipo(+label), forma_pago(+label), metodo_pago(+label), moneda, tipo_cambio, sub_total, descuento, total, lugar_expedicion, exportacion, condiciones_de_pago, no_certificado, emisor{rfc, nombre, regimen(+label), rfc_valid, rfc_kind, rfc_errors}, receptor{… domicilio, uso(+label)}, conceptos[{descripcion, clave_prod_serv, cantidad, clave_unidad, unidad, valor_unitario, importe, descuento, objeto_imp(+label), traslados[], retenciones[]}], concepto_count, total_trasladados, total_retenidos, stamped, timbre{uuid, fecha_timbrado, no_certificado_sat, rfc_prov_certif} | null, arithmetic{…}, findings[] }.
Example: "Read this invoice and tell me who issued it and for how much" -> parse_cfdi(xml="<cfdi:Comprobante …>").
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| xml | Yes | The complete CFDI XML as a string, from '<cfdi:Comprobante' (or '<?xml') to the closing tag. | |
| response_format | No | Output format: 'markdown' for a human-readable summary (default) or 'json' for the full structured payload. | markdown |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| tipo | Yes | ||
| fecha | Yes | ||
| folio | Yes | ||
| serie | Yes | ||
| total | Yes | ||
| emisor | Yes | ||
| moneda | Yes | ||
| timbre | Yes | ||
| stamped | Yes | ||
| version | Yes | ||
| findings | Yes | ||
| receptor | Yes | ||
| conceptos | Yes | ||
| descuento | Yes | ||
| sub_total | Yes | ||
| arithmetic | Yes | ||
| forma_pago | Yes | ||
| tipo_label | Yes | ||
| exportacion | Yes | ||
| metodo_pago | Yes | ||
| tipo_cambio | Yes | ||
| concepto_count | Yes | ||
| no_certificado | Yes | ||
| total_retenidos | Yes | ||
| forma_pago_label | Yes | ||
| lugar_expedicion | Yes | ||
| metodo_pago_label | Yes | ||
| total_trasladados | Yes | ||
| conceptos_truncated | Yes | ||
| condiciones_de_pago | Yes | ||
| total_traslados_locales | Yes | ||
| total_retenciones_locales | Yes |