Si eres ingeniero al que acaban de decir «las facturas tienen que ser PDF/A-3 con Factur-X para el próximo trimestre», y tu único contexto es que alguien en legal pronunció esas palabras, este post es para ti.
Cortamos el tono de los documentos de estandarización y explicamos qué restringen realmente estos perfiles, por qué los gobiernos empezaron a obligarlos y el pipeline más pequeño práctico para emitir un PDF conforme desde un renderizador de datos estructurados.
PDF/A en dos párrafos
PDF es un formato flexible. Demasiado flexible — la misma especificación PDF te permite embeber JavaScript, enlazar a recursos externos que pueden no existir en 50 años, cifrar contenido con criptografía reversible, referenciar fuentes externas, y cien cosas más que vuelven un documento no autocontenido.
PDF/A («A» de Archival) es un perfil de PDF que prohíbe las partes que impedirían que el documento se renderizara idénticamente en 50 años. Las reglas de alto nivel:
- Todas las fuentes deben estar embebidas.
- Sin JavaScript, sin enlaces externos, sin audio/video.
- Sin cifrado.
- Toda transparencia debe ser aplanada o soportada por la versión del perfil.
- Los colores deben ser independientes del dispositivo (perfil ICC requerido).
- Todo el contenido debe estar en el archivo — sin referencias que dependan de la red.
Hay varias versiones, cada una añadiendo tolerancia para funciones más nuevas:
| Perfil | Año | Qué añade |
|---|---|---|
| PDF/A-1b | 2005 | Línea base original — el más estricto |
| PDF/A-2b | 2011 | Permite JPEG2000, transparencia, capas |
| PDF/A-3b | 2012 | Permite adjuntos de archivo arbitrarios (la fundación de Factur-X) |
| PDF/A-4 | 2020 | Base ISO 32000-2 (PDF 2.0), niveles de conformidad simplificados |
El sufijo «b» significa conformidad «basic» (fidelidad visual). También existen variantes «u» (mapeadas Unicode) y «a» (etiquetadas para accesibilidad) — para la mayoría de workflows factura/recibo, «b» es lo que quieres, porque el archivado fiscal se preocupa por reproducibilidad visual, no semántica para lectores de pantalla.
Conclusión práctica: si tu renderizador dice que soporta PDF/A-3b, debería ser un único flag de configuración ({ profile: "PDF/A-3b" } o equivalente). Si tienes que ejecutar una segunda herramienta (Ghostscript, qpdf, Acrobat) para convertir después, eso es un hueco de workflow para considerar en tus ops.
Por qué PDF/A-3 importa específicamente: es el portador de las facturas electrónicas
PDF/A-3 añadió una capacidad que resultó cambiando el mundo: adjuntos de archivo arbitrarios dentro del PDF.
Suena aburrido. No lo es. Es la fundación técnica completa de los mandatos de factura electrónica desplegándose en Europa ahora mismo.
La arquitectura: un único archivo PDF que es tanto
- Una factura legible por humanos (layout visual, totales, branding) — la parte que el humano lee.
- Una factura XML legible por máquina — la parte que el software de la autoridad fiscal parsea.
Ambas dentro de un archivo, ambas representando la misma factura, y el wrapper PDF/A-3 garantiza que el archivo seguirá siendo parseable en décadas.
Los dos formatos XML principales:
- Factur-X (Francia) — perfil XML basado en UN/CEFACT Cross Industry Invoice
- ZUGFeRD (Alemania) — sustancialmente idéntico a Factur-X (los dos estándares se fusionaron técnicamente en 2018)
- EN 16931 — la norma europea a la que ambas implementaciones se conforman
- Facturae (España) — formato XML español que también se basa en EN 16931 cuando se exporta para interoperabilidad
Para la mayoría de workflows, «Factur-X» y «ZUGFeRD» son términos intercambiables — comparten un esquema, comparten el mecanismo de embedding, y un único PDF conforme con uno generalmente lo es con el otro.
Qué es obligatorio, dónde, cuándo
Una instantánea no exhaustiva para ingenieros planeando rollouts Q2/Q3 2026:
| País | Estado | Formato requerido |
|---|---|---|
| España | Emisión obligatoria desde 2026 (B2B); reglamento Crea y Crece + ley antifraude | Facturae vía FACe; XML EN 16931 |
| Alemania | B2B obligatorio para recepción desde 2025-01-01; emisión desde 2027 | EN 16931 (ZUGFeRD / Factur-X / XRechnung) |
| Francia | Emisión obligatoria para grandes empresas 2026-09; PYMES 2027-09 | Factur-X vía Chorus Pro |
| Italia | B2B obligatorio desde 2019 | FatturaPA vía SDI |
| Polonia | Obligatorio desde 2024-07 | KSeF |
| Bélgica | Obligatorio desde 2026-01 | Peppol BIS 3 |
El patrón: cada estado miembro de la UE está implementando alguna variante de e-facturación conforme EN 16931 en una timeline 2024–2027. Si tus clientes operan en cualquiera de estos mercados, tu generador PDF necesitará emitir XML adjunto junto a la factura visual.
Para equipos en España específicamente: la Ley Crea y Crece (aprobada 2022) más el Reglamento de factura electrónica (2024) son la base legal. En la práctica, esto significa que toda empresa española B2B debe, a partir de 2026, emitir facturas electrónicas estructuradas — no solo PDFs como imágenes, sino archivos PDF/A-3 con XML Facturae integrado, enviados vía FACe (la plataforma pública) o Plataformas de Facturación Electrónica privadas autorizadas.
El pipeline más pequeño práctico
Olvida lo que prescriben los documentos de estandarización. Aquí la vista de ingeniería:
┌─────────────────────┐
│ Datos de tu │ (ya un objeto JSON en algún lugar)
│ factura │
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ Construir XML │ (mapeo determinístico; libs probadas existen)
│ EN 16931 │
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ Renderizar PDF/A-3b │
│ + adjuntar XML │ (una llamada API a gPdf — o dos pasos en otros)
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ Entregar a │
│ FACe / Chorus Pro/ │
│ SDI / Peppol / etc │
└─────────────────────┘
Los dos pasos no triviales:
Paso 1: construir el XML
Esto es molesto pero mecánico. Mapea los datos de tu factura (líneas, impuestos, totales, partes) a nombres de campo XML EN 16931. Varias librerías Java/Node/Python lo hacen por ti — busca «factur-x library» o «facturae library» en tu lenguaje. No lo escribas desde cero a menos que realmente disfrutes especificaciones de esquema XML.
Paso 2: renderizar PDF/A-3 y adjuntar el XML
Aquí importa la elección del renderizador.
Sin soporte integrado: renderizas un PDF ordinario, luego post-procesas con una herramienta que convierte a PDF/A-3 y adjunta el XML como archivo embebido. Stacks comunes: Ghostscript + qpdf, o una herramienta de pago como Aspose. Dos pasos extra, dos puntos de fallo extra, y debes asegurar que el post-procesamiento no derive el layout visual.
Con soporte integrado (el enfoque de gPdf): una llamada.
curl -X POST https://gpdf.com/api/v1/e-invoice/render \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
--data '{
"document": {
"pages": [{ "size": "a4", "elements": [...] }]
},
"einvoice": {
"format": "factur-x",
"profile": "BASIC",
"xml": "<rsm:CrossIndustryInvoice>...</rsm:CrossIndustryInvoice>"
}
}' \
--output factura-con-factur-x.pdf
Eso es todo el pipeline. El renderizador emite PDF/A-3b, adjunta tu XML como factur-x.xml (o zugferd-invoice.xml, ambos reconocidos por cada consumidor), y devuelve los bytes.
Trampas comunes
Algunas cosas que la gente aprende por las malas:
«PDF/A» y «con fuentes conformes a PDF/A» no son lo mismo
Un archivo PDF/A-3 requiere que todas las fuentes estén embebidas con cobertura completa de glifos usados. Si tu factura tiene un nombre de cliente extranjero y el renderizador hace fallback a una fuente que no es completamente embebible, las herramientas de validación lo rechazarán. Verifica que tu renderizador embeba fuentes CJK en modo PDF/A — muchos no lo hacen por defecto.
Visual + XML deben coincidir
La factura XML y la factura visual se supone que representan la misma factura. Los auditores fiscales las van a diff. Si tu código emite XML con total: 119,00 y el PDF visual muestra Total: 120,00 (por un bug de redondeo o una plantilla obsoleta), tienes una discrepancia fiscal en el archivo. Genera ambas desde la misma fuente de verdad, idealmente en el mismo path de código.
Niveles de «perfil» en EN 16931
Factur-X tiene perfiles: MINIMUM, BASIC, EN 16931, EXTENDED. Difieren en cuántos datos están en el XML. Usa BASIC a menos que tu cliente requiera específicamente más — cubre códigos fiscales, líneas, partes, totales, lo que es suficiente para ~95 % de la facturación B2B.
Validación antes de envío
Valida siempre el PDF generado contra un validador PDF/A (veraPDF es el estándar open-source) y valida el XML contra el esquema EN 16931 antes de enviar a la autoridad fiscal. Envíos fallidos a FACe / Chorus Pro / SDI cuentan contra tus métricas de fiabilidad con el regulador.
TL;DR
PDF/A es un perfil de documento autocontenido. PDF/A-3 te permite adjuntar archivos. Factur-X / ZUGFeRD es «un XML EN 16931 adjunto dentro de un PDF/A-3». Los mandatos de factura electrónica a través de la UE hacen de esta combinación el formato de facto B2B para 2025–2027.
Si tu renderizador trata PDF/A-3 + Factur-X como un único flag de configuración, la migración es mecánica. Si no, estás construyendo un pipeline de ops multi-paso. El /api/v1/e-invoice/render de gPdf es la versión single-flag — la referencia API tiene el esquema completo, o prueba un render de muestra en el Playground.