Se sei un ingegnere a cui hanno appena detto «le fatture devono essere PDF/A-3 con Factur-X entro il prossimo trimestre», e il tuo unico contesto è che qualcuno in legale ha pronunciato quelle parole, questo post è per te.
Tagliamo il tono dei documenti di standardizzazione e spieghiamo cosa vincolano realmente questi profili, perché i governi hanno iniziato a renderli obbligatori, e la pipeline pratica più piccola per emettere un PDF conforme da un renderer di dati strutturati.
PDF/A in due paragrafi
PDF è un formato flessibile. Troppo flessibile — la stessa specifica PDF ti permette di embeddare JavaScript, linkare a risorse esterne che potrebbero non esistere tra 50 anni, cifrare contenuti con crittografia reversibile, referenziare font esterni, e cento altre cose che rendono un documento non auto-contenuto.
PDF/A («A» per Archival) è un profilo di PDF che vieta le parti che impedirebbero al documento di renderizzare identicamente tra 50 anni. Le regole di alto livello:
- Tutti i font devono essere embedded.
- Niente JavaScript, niente link esterni, niente audio/video.
- Niente cifratura.
- Tutta la trasparenza deve essere appiattita o supportata dalla versione del profilo.
- I colori devono essere device-independent (profilo ICC richiesto).
- Tutto il contenuto deve essere nel file — niente riferimenti che dipendono dalla rete.
Esistono varie versioni, ognuna che aggiunge tolleranza per feature più recenti:
| Profilo | Anno | Cosa aggiunge |
|---|---|---|
| PDF/A-1b | 2005 | Baseline originale — il più stretto |
| PDF/A-2b | 2011 | Permette JPEG2000, trasparenza, layer |
| PDF/A-3b | 2012 | Permette allegati di file arbitrari (la fondazione di Factur-X) |
| PDF/A-4 | 2020 | Base ISO 32000-2 (PDF 2.0), livelli di conformità semplificati |
Il suffisso «b» significa conformità «basic» (fedeltà visiva). Esistono anche varianti «u» (unicode-mappata) e «a» (taggata accessibilità) — per la maggior parte dei workflow fattura/ricevuta, «b» è ciò che vuoi, perché la conservazione fiscale si preoccupa della riproducibilità visiva, non della semantica per screen reader.
Conclusione pratica: se il tuo renderer dice di supportare PDF/A-3b, dovrebbe essere un singolo flag di configurazione ({ profile: "PDF/A-3b" } o equivalente). Se devi eseguire un secondo strumento (Ghostscript, qpdf, Acrobat) per convertire dopo, è una lacuna di workflow da considerare nelle tue ops.
Perché PDF/A-3 conta specificamente: è il portatore delle fatture elettroniche
PDF/A-3 ha aggiunto una capacità che si è rivelata cambiare il mondo: allegati di file arbitrari dentro il PDF.
Sembra noioso. Non lo è. È l’intera fondazione tecnica dei mandati di fatturazione elettronica che si stanno spiegando in Europa proprio ora.
L’architettura: un singolo file PDF che è sia
- Una fattura leggibile dall’uomo (layout visivo, totali, branding) — la parte che l’umano legge.
- Una fattura XML leggibile dalla macchina — la parte che il software dell’autorità fiscale parsa.
Entrambe dentro un file, entrambe rappresentanti la stessa fattura, e il wrapper PDF/A-3 garantisce che il file sarà ancora parseable in decenni.
I due formati XML principali:
- Factur-X (Francia) — profilo XML basato su UN/CEFACT Cross Industry Invoice
- ZUGFeRD (Germania) — sostanzialmente identico a Factur-X (i due standard si sono fusi tecnicamente nel 2018)
- EN 16931 — la norma europea a cui entrambe le implementazioni si conformano
- FatturaPA (Italia) — formato XML italiano via SDI (Sistema di Interscambio); quando esportato per interoperabilità EU si conforma a EN 16931
Per la maggior parte dei workflow, «Factur-X» e «ZUGFeRD» sono termini intercambiabili — condividono uno schema, condividono il meccanismo di embedding, e un singolo PDF conforme con uno è generalmente conforme con l’altro.
Cosa è obbligatorio, dove, quando
Una snapshot non esaustiva per ingegneri che pianificano rollout Q2/Q3 2026:
| Paese | Status | Formato richiesto |
|---|---|---|
| Italia | B2B obbligatorio dal 2019 via SDI; B2G dal 2014 | FatturaPA via SDI |
| Germania | B2B obbligatorio per ricezione dal 2025-01-01; emissione dal 2027 | EN 16931 (ZUGFeRD / Factur-X / XRechnung) |
| Francia | Emissione obbligatoria per grandi imprese 2026-09; PMI 2027-09 | Factur-X via Chorus Pro |
| Polonia | Obbligatorio dal 2024-07 | KSeF |
| Spagna | Obbligatorio dal 2026 (B2B) | Facturae via FACe |
| Belgio | Obbligatorio dal 2026-01 | Peppol BIS 3 |
Il pattern: ogni stato membro UE sta implementando una variante di e-fatturazione conforme EN 16931 su una timeline 2024–2027. Se i tuoi clienti operano in uno di questi mercati, il tuo generatore PDF dovrà emettere XML allegato accanto alla fattura visiva.
Per team italiani specificamente: la FatturaPA (in vigore dal 2019 per B2B) è gestita via Sistema di Interscambio (SDI) dell’Agenzia delle Entrate. Ogni fattura B2B italiana deve essere inviata via SDI in formato XML strutturato. La conservazione 10 anni richiede file PDF/A-3 con XML embedded — esattamente il setup Factur-X / ZUGFeRD.
La pipeline pratica più piccola
Dimentica cosa prescrivono i documenti di standardizzazione. Ecco la vista da ingegnere:
┌─────────────────────┐
│ Dati della tua │ (già un oggetto JSON da qualche parte)
│ fattura │
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ Costruire XML │ (mapping deterministico; lib testate esistono)
│ EN 16931 │
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ Renderizzare │
│ PDF/A-3b + allegare │ (singola chiamata API a gPdf — o due step altrove)
│ l'XML │
└─────────┬───────────┘
│
▼
┌─────────────────────┐
│ Consegnare a │
│ SDI / Chorus Pro / │
│ Peppol / etc │
└─────────────────────┘
I due step non banali:
Step 1: costruire l’XML
Questo è fastidioso ma meccanico. Mappi i dati della tua fattura (righe, tasse, totali, parti) ai nomi di campo XML EN 16931 (o FatturaPA per SDI). Diverse librerie Java/Node/Python lo fanno per te — cerca «factur-x library» o «fatturapa library» nel tuo linguaggio. Non scriverlo da zero a meno che tu davvero non goda delle specifiche schema XML.
Step 2: renderizzare PDF/A-3 e allegare l’XML
È qui che la scelta del renderer conta.
Senza supporto integrato: renderizzi un PDF ordinario, poi post-processi con uno strumento che converte a PDF/A-3 e allega l’XML come file embedded. Stack comuni: Ghostscript + qpdf, o uno strumento a pagamento come Aspose. Due step extra, due punti di fallimento extra, e devi assicurarti che il post-processing non faccia derivare il layout visivo.
Con supporto integrato (l’approccio di gPdf): una chiamata.
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 fattura-con-factur-x.pdf
Questa è l’intera pipeline. Il renderer emette PDF/A-3b, allega il tuo XML come factur-x.xml (o zugferd-invoice.xml, entrambi riconosciuti da ogni consumer), e restituisce i byte.
Trabocchetti comuni
Alcune cose che la gente impara nel modo difficile:
«PDF/A» e «con font conformi PDF/A» non sono la stessa cosa
Un file PDF/A-3 richiede che tutti i font siano embedded con copertura completa dei glifi usati. Se la tua fattura ha un nome cliente straniero e il renderer fa fallback a un font che non è completamente embeddable, gli strumenti di validazione lo rifiuteranno. Verifica che il tuo renderer embedda font CJK in modalità PDF/A — molti non lo fanno di default.
Visivo + XML devono coincidere
La fattura XML e la fattura visiva devono rappresentare la stessa fattura. I revisori fiscali le diff-eranno. Se il tuo codice emette XML con total: 119,00 e il PDF visivo mostra Totale: 120,00 (a causa di un bug di arrotondamento o di un template stantio), hai una discrepanza fiscale negli archivi. Genera entrambe dalla stessa source-of-truth, idealmente nello stesso percorso di codice.
Livelli di «profilo» in EN 16931
Factur-X ha profili: MINIMUM, BASIC, EN 16931, EXTENDED. Differiscono per quanti dati ci sono nell’XML. Usa BASIC a meno che il tuo cliente non richieda specificamente di più — copre codici fiscali, righe, parti, totali, che è abbastanza per il ~95 % della fatturazione B2B.
Validazione prima dell’invio
Valida sempre il PDF generato contro un validatore PDF/A (veraPDF è lo standard open-source) e valida l’XML contro lo schema EN 16931 prima di inviare all’autorità fiscale. Invii falliti a SDI / Chorus Pro / FACe contano contro le tue metriche di affidabilità con il regolatore.
TL;DR
PDF/A è un profilo di documento auto-contenuto. PDF/A-3 ti permette di allegare file. Factur-X / ZUGFeRD è «un XML EN 16931 allegato dentro un PDF/A-3». I mandati di fatturazione elettronica attraverso l’UE rendono questa combinazione il formato di fatto B2B per il 2025–2027.
Se il tuo renderer tratta PDF/A-3 + Factur-X come un singolo flag di configurazione, la migrazione è meccanica. Se non lo fa, stai costruendo una pipeline ops multi-step. Il /api/v1/e-invoice/render di gPdf è la versione single-flag — la referenza API ha lo schema completo, o prova un render di esempio nel Playground.