UBL — Universal Business Language — es el estándar de OASIS que sostiene Peppol BIS, EN 16931, ZATCA Fase 2, el perfil PINT de los EAU, el schema IRP/e-invoice de India (con extensiones) y varios regímenes de LATAM. Si tu estrategia de facturación electrónica no hace las paces con UBL 2.1, vas a estar reimplementando el mismo XML una y otra vez.
La forma de una factura UBL
Una factura UBL es un documento XML con tres namespaces principales: cbc (Common Basic Components — tipos primitivos como ID y Amount), cac (Common Aggregate Components — tipos complejos como Party y TaxTotal), y el namespace del propio documento. Cada documento UBL sigue el mismo patrón:
<Invoice
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017</cbc:CustomizationID>
<cbc:ID>INV-2026-0001</cbc:ID>
<cbc:IssueDate>2026-01-15</cbc:IssueDate>
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
<cac:AccountingSupplierParty>...</cac:AccountingSupplierParty>
<cac:AccountingCustomerParty>...</cac:AccountingCustomerParty>
<cac:TaxTotal>...</cac:TaxTotal>
<cac:LegalMonetaryTotal>...</cac:LegalMonetaryTotal>
<cac:InvoiceLine>...</cac:InvoiceLine>
</Invoice>Cinco conceptos que casi siempre están mal
- TaxTotal vs. LegalMonetaryTotal. El primero desglosa el impuesto por tasa. El segundo es el monto consolidado a pagar. No los confundas.
- AllowanceCharge puede ser un descuento o un recargo — lo decide ChargeIndicator (false = allowance, true = charge). Indicador equivocado → total equivocado.
- Los Endpoint IDs necesitan un atributo scheme (schemeID="0088" etc.). Sin él, los validadores devuelven errores crípticos sobre identificadores faltantes.
- Las cantidades usan un código de unidad de UN/CEFACT (EA = each, KGM = kilogramo, HUR = hora). "piece" no es un valor válido.
- Los códigos TaxCategory son UNCL5305: S = tasa estándar, Z = tasa cero, E = exento, AE = inversión del sujeto pasivo. No inventes códigos nuevos.
La EUStrategy de Invocie emite UBL 2.1 conforme a BIS Billing 3.0 — el mismo XML sirve para los APs de Peppol, el perfil UAE PINT, y cualquier sistema que consuma EN 16931.