Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/eclipxe13/CfdiUtils/llms.txt

Use this file to discover all available pages before exploring further.

Complements (complementos) are optional but frequently required XML extensions that the SAT defines for specific invoice types — payroll receipts, freight documents, foreign-trade exports, payments, and more. In CfdiUtils, a complement is an element or raw node that you attach to the cfdi:Complemento wrapper inside a Comprobante using the addComplemento() method. The library ships with typed element helpers for several of the most common complements under CfdiUtils\Elements. For complements that do not yet have a dedicated element class, you can fall back to the generic CfdiUtils\Nodes\Node API and attach the raw node directly. Both paths produce the same XML output.

Available Complement Elements

Nómina 1.2 Revision B

Namespace: CfdiUtils\Elements\Nomina12
XML prefix: nomina12
XML namespace URI: http://www.sat.gob.mx/nomina12
XSD: http://www.sat.gob.mx/sitio_internet/cfd/nomina/nomina12.xsd
The Nómina 1.2 revision B complement is valid from January 1, 2020. It is used on TipoDeComprobante = 'N' (payroll) invoices. Node hierarchy (abbreviated):
[0,1] Nomina
      [0,1] Emisor
            [0,1] EntidadSNCF
      [1,1] Receptor
            [0,N] SubContratacion
      [0,1] Percepciones
            [0,N] Percepcion
      [0,1] Deducciones
            [0,N] Deduccion
      [0,1] OtrosPagos
            [0,N] OtroPago
      [0,1] Incapacidades
            [0,N] Incapacidad
Key element methods on Nomina:
MethodReturns
getEmisor() / addEmisor(array $attrs)Emisor
getReceptor() / addReceptor(array $attrs)Receptor
getPercepciones() / addPercepciones(array $attrs)Percepciones
getDeducciones() / addDeducciones(array $attrs)Deducciones
getOtrosPagos() / addOtrosPagos(array $attrs)OtrosPagos
getIncapacidades() / addIncapacidades(array $attrs)Incapacidades
Methods prefixed with get retrieve-or-create the single child node (for [0,1] nodes). Methods prefixed with add for multi-occurrence nodes ([0,N]) always append a new child. Methods prefixed with multi accept variadic attribute arrays and add multiple children at once.
Attaching Nómina to the comprobante:
<?php
use CfdiUtils\CfdiCreator40;
use CfdiUtils\Elements\Nomina12\Nomina;

$creator = new CfdiCreator40(/* ... */);
$comprobante = $creator->comprobante();

$nomina = new Nomina([
    'Version'       => '1.2',
    'TipoNomina'    => 'O', // Ordinaria
    'FechaPago'     => '2024-01-31',
    'FechaInicialPago' => '2024-01-01',
    'FechaFinalPago'   => '2024-01-31',
    'NumDiasPagados'   => '31',
    'TotalPercepciones' => '15000.00',
    'TotalDeducciones'  => '2000.00',
    'TotalOtrosPagos'   => '0.00',
]);

$nomina->addReceptor([
    'NumEmpleado'      => 'EMP001',
    'Curp'             => 'AABL870101HDFXXX01',
    'TipoRegimen'      => '02',
    'NumSeguridadSocial' => '12345678901',
    'FechaInicioRelLaboral' => '2020-01-01',
    'Antigüedad'       => 'P1Y',
    'TipoContrato'     => '01',
    'Sindicalizado'    => 'No',
    'TipoJornada'      => '01',
    'DepartamentoEmisor' => 'Tecnología',
    'CURP'             => 'AABL870101HDFXXX01',
    'SalarioBaseCotApor' => '500.00',
    'SalarioDiarioIntegrado' => '600.00',
    'ClaveEntFed'      => 'JAL',
]);

$percepciones = $nomina->addPercepciones([
    'TotalSueldos'  => '15000.00',
    'TotalGravado'  => '12000.00',
    'TotalExento'   => '3000.00',
]);
$percepciones->addPercepcion([
    'TipoPercepcion'  => '001', // Sueldos, Salarios Rayas y Jornales
    'Clave'           => 'P001',
    'Concepto'        => 'Sueldo mensual',
    'ImporteGravado'  => '12000.00',
    'ImporteExento'   => '3000.00',
]);

$nomina->addDeducciones([
    'TotalOtrasDecucciones' => '2000.00',
    'TotalImpuestosRetenidos' => '0.00',
])->addDeduccion([
    'TipoDeduccion' => '002', // ISR
    'Clave'         => 'D001',
    'Concepto'      => 'ISR',
    'Importe'       => '2000.00',
]);

// Attach the Nomina node to the Comprobante's Complemento section
$comprobante->addComplemento($nomina);

Carta Porte 3.0

Namespace: CfdiUtils\Elements\CartaPorte30
XML prefix: cartaporte30
XML namespace URI: http://www.sat.gob.mx/CartaPorte30
XSD: http://www.sat.gob.mx/sitio_internet/cfd/CartaPorte/CartaPorte30.xsd
Effective: January 1, 2024
Carta Porte 3.0 is used on transport invoices that move goods within Mexico. Key element methods on CartaPorte:
MethodReturns
getUbicaciones() / addUbicaciones(array $attrs)Ubicaciones
getMercancias() / addMercancias(array $attrs)Mercancias
getFiguraTransporte() / addFiguraTransporte(array $attrs)FiguraTransporte
Attaching Carta Porte 3.0:
<?php
use CfdiUtils\CfdiCreator40;
use CfdiUtils\Elements\CartaPorte30\CartaPorte;

$creator = new CfdiCreator40(/* ... */);
$comprobante = $creator->comprobante();

$cartaPorte = new CartaPorte([
    'Version'            => '3.0',
    'TranspInternac'     => 'No',
    'TotalDistRec'       => '250',
]);

// Ubicaciones: origin and destination
$ubicaciones = $cartaPorte->getUbicaciones();
$ubicaciones->addUbicacion([
    'TipoUbicacion'    => 'Origen',
    'RFCRemitenteDestinatario' => 'EKU9003173C9',
    'FechaHoraSalidaLlegada'  => '2024-01-15T09:00:00',
    'DistanciaRecorrida' => '250',
])->addDomicilio([
    'Calle'          => 'Av. Principal',
    'NumeroExterior' => '100',
    'CodigoPostal'   => '64000',
    'Municipio'      => 'Monterrey',
    'Estado'         => 'NLE',
    'Pais'           => 'MEX',
]);

$ubicaciones->addUbicacion([
    'TipoUbicacion' => 'Destino',
    'RFCRemitenteDestinatario' => 'CACX7605101P8',
    'FechaHoraSalidaLlegada'  => '2024-01-15T15:00:00',
])->addDomicilio([
    'CodigoPostal' => '06600',
    'Municipio'    => 'Cuauhtémoc',
    'Estado'       => 'CMX',
    'Pais'         => 'MEX',
]);

// Mercancias
$mercancias = $cartaPorte->addMercancias([
    'PesoBrutoTotal'    => '1000',
    'UnidadPeso'        => 'KGM',
    'NumTotalMercancias' => '1',
]);
$mercancias->addMercancia([
    'BienesTransp'     => '24111500',
    'Descripcion'      => 'Componentes electrónicos',
    'Cantidad'         => '10',
    'ClaveUnidad'      => 'KGM',
    'PesoEnKg'         => '1000',
    'ValorMercancia'   => '50000',
    'Moneda'           => 'MXN',
    'FraccionArancelaria' => '8542310100',
]);

$mercancias->addAutotransporte([
    'PermSCT'     => 'TPAF01',
    'NumPermisoSCT' => '123456',
])->addIdentificacionVehicular([
    'ConfigVehicular' => 'VL',
    'PlacaVM'         => 'ABC1234',
    'AnioModeloVM'    => '2020',
]);

// Attach to comprobante
$comprobante->addComplemento($cartaPorte);

Carta Porte 3.1

Namespace: CfdiUtils\Elements\CartaPorte31
XML prefix: cartaporte31
XML namespace URI: http://www.sat.gob.mx/CartaPorte31
XSD: http://www.sat.gob.mx/sitio_internet/cfd/CartaPorte/CartaPorte31.xsd
Effective: July 17, 2024
Carta Porte 3.1 is the current version of the transport complement. Its element structure is nearly identical to 3.0, with the addition of RegimenesAduaneros on the root CartaPorte node. Extra element methods on CartaPorte (3.1 only):
MethodReturns
getRegimenesAduaneros()RegimenesAduaneros
Usage is otherwise the same as 3.0 — just substitute the namespace:
<?php
use CfdiUtils\CfdiCreator40;
use CfdiUtils\Elements\CartaPorte31\CartaPorte;

$creator = new CfdiCreator40(/* ... */);
$comprobante = $creator->comprobante();

$cartaPorte = new CartaPorte(['Version' => '3.1', 'TranspInternac' => 'No']);
// ... populate $cartaPorte the same way as 3.0 ...

$comprobante->addComplemento($cartaPorte);

Comercio Exterior 2.0

Namespace: CfdiUtils\Elements\Cce20
XML prefix: cce20
XML namespace URI: http://www.sat.gob.mx/ComercioExterior20
XSD: http://www.sat.gob.mx/sitio_internet/cfd/ComercioExterior20/ComercioExterior20.xsd
Effective: January 15, 2024
Comercio Exterior 2.0 is required when exporting goods from Mexico. Compared to version 1.1, the Emisor/Domicilio and Mercancias nodes are now mandatory, and TipoOperacion and Subdivision attributes were removed. Key element methods on ComercioExterior:
MethodReturns
getEmisor() / addEmisor(array $attrs)Emisor
addPropietario(array $attrs)Propietario
getReceptor() / addReceptor(array $attrs)Receptor
addDestinatario(array $attrs)Destinatario
getMercancias() / addMercancias(array $attrs)Mercancias
Attaching Comercio Exterior 2.0:
<?php
use CfdiUtils\CfdiCreator40;
use CfdiUtils\Elements\Cce20\ComercioExterior;

$creator = new CfdiCreator40(/* ... */);
$comprobante = $creator->comprobante();

$cce = new ComercioExterior([
    'Version'           => '2.0',
    'MotivoTraslado'    => '01',
    'ClaveDePedimento'  => 'A1',
    'CertificadoOrigen' => '0',
    'Incoterm'          => 'DAP',
    'TipoCambioUSD'     => '18.50',
    'TotalUSD'          => '2702.70',
]);

$cce->addEmisor()->addDomicilio([
    'Calle'          => 'Insurgentes Sur',
    'NumeroExterior' => '1500',
    'Colonia'        => 'Guadalupe Inn',
    'Localidad'      => '09',
    'Referencia'     => 'Piso 3',
    'Municipio'      => '039',
    'Estado'         => 'CMX',
    'Pais'           => 'MEX',
    'CodigoPostal'   => '01020',
]);

$cce->addReceptor(['NumRegIdTrib' => 'US123456789'])->addDomicilio([
    'Calle'          => 'Main Street',
    'NumeroExterior' => '100',
    'Estado'         => 'CA',
    'Pais'           => 'USA',
    'CodigoPostal'   => '90210',
]);

$mercancias = $cce->getMercancias();
$mercancias->addMercancia([
    'NoIdentificacion'    => 'PN-001',
    'FraccionArancelaria' => '8542310100',
    'CantidadAduana'      => '10',
    'UnidadAduana'        => '06',
    'ValorUnitarioAduana' => '270.27',
    'ValorDolares'        => '2702.70',
])->addDescripcionesEspecificas([
    'Marca'   => 'Acme',
    'Modelo'  => 'X200',
    'SubModelo' => 'Rev-B',
    'NumeroSerie' => 'SN001',
]);

$comprobante->addComplemento($cce);

Adding Unsupported Complements

Not every SAT complement has a dedicated element class in CfdiUtils\Elements. Because CfdiUtils stores all document data as CfdiUtils\Nodes\Node objects internally, you can construct any complement manually using the same low-level API and attach it to the comprobante. The following example attaches a Leyendas Fiscales complement, which does not have a typed element helper:
<?php
use CfdiUtils\CfdiCreator40;
use CfdiUtils\Nodes\Node;

$creator = new CfdiCreator40(/* ... */);
$comprobante = $creator->comprobante();

// Build the complement node manually using CfdiUtils\Nodes\Node
$leyendasFisc = new Node(
    'leyendasFisc:LeyendasFiscales',
    [
        // Required XML namespace declarations for this complement
        'xmlns:leyendasFisc'  => 'http://www.sat.gob.mx/leyendasFiscales',
        'xsi:schemaLocation'  => 'http://www.sat.gob.mx/leyendasFiscales'
            . ' http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xsd',
        'version' => '1.0',
    ]
);

// Add child nodes the same way
$leyendasFisc->addChild(new Node('leyendasFisc:Leyenda', [
    'disposicionFiscal' => 'RESDERAUTH',
    'norma'             => 'Artículo 2. Fracción IV.',
    'textoLeyenda'      => 'El software desarrollado se entrega con licencia MIT',
]));

// Attach to the comprobante — same API as typed complements
$comprobante->addComplemento($leyendasFisc);

$creator->saveXml('cfdi_with_leyendas.xml');
The resulting XML places the xmlns:leyendasFisc declaration on the complement node itself. After calling $creator->moveSatDefinitionsToComprobante() the declaration is promoted to the root cfdi:Comprobante node, as required by the SAT:
<cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/4"
    xmlns:leyendasFisc="http://www.sat.gob.mx/leyendasFiscales"
    xsi:schemaLocation="http://www.sat.gob.mx/cfd/4 ...
        http://www.sat.gob.mx/leyendasFiscales ...">
    <!-- ... -->
    <cfdi:Complemento>
        <leyendasFisc:LeyendasFiscales version="1.0">
            <leyendasFisc:Leyenda disposicionFiscal="RESDERAUTH" ... />
        </leyendasFisc:LeyendasFiscales>
    </cfdi:Complemento>
</cfdi:Comprobante>
A full list of SAT-defined complements and their XSD schemas is published at the SAT’s electronic invoice portal: http://www.sat.gob.mx/informacion_fiscal/factura_electronica/Paginas/complementos_factura_cfdi.aspx

Pagos 2.0

The Pagos (Payment) complement is used on TipoDeComprobante = 'P' payment receipts. CfdiUtils includes a dedicated writer helper — CfdiUtils\SumasConceptos\SumasConceptosWriterPagos20 — that automatically calculates and writes the Totales node of the Pagos 2.0 complement.

Pagos 2.0 Utility

See the Pagos 2.0 documentation for the full API including SumasPagos20 and how to attach and compute the payment totals automatically.

Build docs developers (and LLMs) love