@cfdi/xml
v4.0.19
Published
Generacion, sellado y timbrado de XML CFDI 4.0 para Node.js - facturacion electronica Mexico
Maintainers
Readme
Ecosistema CFDI
Por que @cfdi/xml?
Quick Start
1. Instalar
npm install @cfdi/xml2. Crear y firmar un CFDI
import { CFDI, Emisor, Receptor, Concepto, Impuestos } from '@cfdi/xml';
const cfdi = new CFDI({
xslt: { path: './resources/4.0/cadenaoriginal.xslt' },
});
cfdi.comprobante({
Serie: 'A',
Folio: '1',
Fecha: '2024-01-15T10:30:00',
FormaPago: '01',
MetodoPago: 'PUE',
TipoDeComprobante: 'I',
LugarExpedicion: '64000',
Moneda: 'MXN',
SubTotal: '1000.00',
Total: '1160.00',
});
cfdi.emisor(
new Emisor({
Rfc: 'AAA010101AAA',
Nombre: 'Empresa SA de CV',
RegimenFiscal: '601',
})
);
cfdi.receptor(
new Receptor({
Rfc: 'BBB020202BBB',
Nombre: 'Cliente SA de CV',
UsoCFDI: 'G03',
DomicilioFiscalReceptor: '64000',
RegimenFiscalReceptor: '601',
})
);
const concepto = new Concepto({
ClaveProdServ: '01010101',
Cantidad: '1',
ClaveUnidad: 'E48',
Descripcion: 'Servicio de consultoria',
ValorUnitario: '1000.00',
Importe: '1000.00',
ObjetoImp: '02',
});
concepto.setTraslado({
Base: '1000.00',
Impuesto: '002',
TipoFactor: 'Tasa',
TasaOCuota: '0.160000',
Importe: '160.00',
});
cfdi.concepto(concepto);
const impuestos = new Impuestos({
TotalImpuestosTrasladados: '160.00',
});
impuestos.traslados({
Impuesto: '002',
TipoFactor: 'Tasa',
TasaOCuota: '0.160000',
Importe: '160.00',
Base: '1000.00',
});
cfdi.impuesto(impuestos);3. Certificar y sellar
cfdi.certificar('./certs/certificado.cer');
await cfdi.sellar('./certs/llave.key', '12345678a');4. Obtener el XML
const xml = cfdi.getXmlCdfi();Flujo de firmado
graph LR
A[XML CFDI] --> B[Cadena Original]
B --> C[Sello Digital]
C --> D[CFDI Firmado]
B -- "@cfdi/transform (default)" --> B
B -. "@saxon-he/cli (opcional)" .-> B
C -- ".key + SHA-256" --> C
A -- ".cer" --> DOutput de ejemplo
<?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="1"
Fecha="2024-01-15T10:30:00"
FormaPago="01"
MetodoPago="PUE"
TipoDeComprobante="I"
Moneda="MXN"
SubTotal="1000.00"
Total="1160.00"
LugarExpedicion="64000"
NoCertificado="20001000000300022815"
Certificado="MIIFxTCCA62g..."
Sello="GshKsM2IjAR0+7...">
<cfdi:Emisor Rfc="AAA010101AAA" Nombre="Empresa SA de CV" RegimenFiscal="601"/>
<cfdi:Receptor Rfc="BBB020202BBB" Nombre="Cliente SA de CV" UsoCFDI="G03"
DomicilioFiscalReceptor="64000" RegimenFiscalReceptor="601"/>
<cfdi:Conceptos>
<cfdi:Concepto ClaveProdServ="01010101" Cantidad="1" ClaveUnidad="E48"
Descripcion="Servicio de consultoria" ValorUnitario="1000.00"
Importe="1000.00" ObjetoImp="02">
<cfdi:Impuestos>
<cfdi:Traslados>
<cfdi:Traslado Base="1000.00" Impuesto="002" TipoFactor="Tasa"
TasaOCuota="0.160000" Importe="160.00"/>
</cfdi:Traslados>
</cfdi:Impuestos>
</cfdi:Concepto>
</cfdi:Conceptos>
</cfdi:Comprobante>Motor XSLT
La cadena original se genera mediante transformacion XSLT. Se soportan dos motores:
| Motor | Paquete | Requiere Java | Default |
| ------------------- | ----------------- | ------------- | ------- |
| @cfdi/transform | @cfdi/transform | No | Si |
| Saxon-HE | @saxon-he/cli | Si | No |
// Default: @cfdi/transform (pure Node.js)
const cfdi = new CFDI({
xslt: { path: './resources/4.0/cadenaoriginal.xslt' },
});
// Saxon-HE: requiere Java + Saxon instalado
const cfdiSaxon = new CFDI({
xslt: { path: './resources/4.0/cadenaoriginal.xslt' },
saxon: { binary: 'transform' },
});API
| Metodo | Descripcion |
| ---------------------------- | ----------------------------------------------------- |
| comprobante(attr) | Atributos del comprobante (Serie, Folio, Fecha, etc.) |
| emisor(emisor) | Datos del emisor |
| receptor(receptor) | Datos del receptor |
| concepto(concepto) | Agrega un concepto (puede llamarse multiples veces) |
| impuesto(impuesto) | Resumen de impuestos del documento |
| certificar(cerpath) | Carga certificado .cer |
| sellar(keyfile, password) | Genera cadena original y sello digital |
| getXmlCdfi() | Retorna el XML firmado |
| getJsonCdfi() | Retorna representacion JSON |
| saveFile(file, path, name) | Guarda archivo XML |
| generarCadenaOriginal() | Genera cadena original via XSLT |
| setDebug(debug) | Activa/desactiva modo debug |
Configuracion
interface Config {
debug?: boolean;
compact?: boolean;
xslt?: { path: string }; // Ruta al archivo XSLT (requerido para sellar)
saxon?: { binary: string }; // Si se omite, usa @cfdi/transform
schema?: { path: string };
}