ब्लॉग

इंजीनियरों के लिए PDF/A और Factur-X बिना कानूनी भाषा के

PDF/A profiles असल में क्या सीमित करते हैं, EU e-invoicing में Factur-X क्यों महत्वपूर्ण है, और JSON renderer से compliant PDF निकालने की सबसे छोटी pipeline.

अगर आप ऐसे engineer हैं जिन्हें अभी बताया गया है कि “अगली तिमाही तक invoices PDF/A-3 with Factur-X होने चाहिए”, और आपका पूरा संदर्भ सिर्फ इतना है कि legal team ने ये शब्द बोले, तो यह post आपके लिए है.

हम standards documents वाली भाषा हटाकर बताएँगे कि ये profiles वास्तव में क्या constrain करते हैं, governments इन्हें क्यों mandate कर रही हैं, और structured-data renderer से compliant PDF emit करने की सबसे छोटी practical pipeline क्या है.

दो paragraphs में PDF/A

PDF एक flexible format है. बहुत flexible — वही PDF spec आपको JavaScript embed करने, ऐसे external resources link करने जो 50 साल बाद शायद मौजूद न हों, reversible cryptography से content encrypt करने, external fonts reference करने, और ऐसी कई चीजें करने देता है जो document को self-contained नहीं रहने देतीं.

PDF/A में “A” का अर्थ Archival है. यह PDF का एक profile है जो उन हिस्सों को रोकता है जो document को 50 साल बाद identically render होने से रोक सकते हैं. High-level rules:

  • सभी fonts embedded होने चाहिए.
  • JavaScript नहीं, external links नहीं, audio/video नहीं.
  • Encryption नहीं.
  • Transparency flatten होनी चाहिए या profile version द्वारा supported होनी चाहिए.
  • Colours device-independent होने चाहिए; ICC profile required है.
  • सारा content file के अंदर होना चाहिए; network पर निर्भर references नहीं.

कई versions हैं, और हर version newer features के लिए कुछ tolerance जोड़ता है:

Profile Year क्या जोड़ता है
PDF/A-1b 2005 Original baseline, सबसे strict
PDF/A-2b 2011 JPEG2000, transparency, layers allow करता है
PDF/A-3b 2012 Arbitrary file attachments allow करता है, यही Factur-X का foundation है
PDF/A-4 2020 ISO 32000-2 (PDF 2.0) base, simplified conformance levels

“b” suffix का मतलब “basic” conformance है, यानी visual fidelity. “u” यानी unicode-mapped और “a” यानी accessibility-tagged variants भी हैं. अधिकांश invoice/receipt workflows के लिए “b” सही है, क्योंकि tax archival को visual reproducibility चाहिए, screen-reader semantics नहीं.

Practical takeaway: अगर आपका renderer PDF/A-3b support बताता है, तो वह एक single config flag होना चाहिए, जैसे { profile: "PDF/A-3b" } या equivalent. अगर आपको बाद में convert करने के लिए Ghostscript, qpdf या Acrobat जैसी दूसरी tool चलानी पड़ती है, तो वह ops में गिनने लायक workflow gap है.

PDF/A-3 खास तौर पर क्यों महत्वपूर्ण है: यह e-invoices का carrier है

PDF/A-3 ने एक capability जोड़ी जो सुनने में साधारण लगती है लेकिन बहुत महत्वपूर्ण निकली: PDF के अंदर arbitrary file attachments.

यह boring लगता है. असल में नहीं है. Europe में अभी rollout हो रहे e-invoice mandates की पूरी technical foundation यही है.

Architecture: एक ही PDF file जो दोनों होती है:

  1. Human-readable invoice, यानी visual layout, totals और branding वाला हिस्सा.
  2. Machine-readable XML invoice, यानी tax authority का software जिसे parse करता है.

दोनों एक ही file के अंदर, दोनों उसी invoice को represent करते हुए, और PDF/A-3 wrapper यह guarantee देता है कि file decades बाद भी parseable रहेगी.

मुख्य XML formats:

  • Factur-X (France), UN/CEFACT Cross Industry Invoice पर आधारित XML profile.
  • ZUGFeRD (Germany), Factur-X के लगभग समान; दोनों standards 2018 में technically merge हुए.
  • EN 16931, European norm जिसके अनुसार दोनों implementations conform करते हैं.

Most workflows में “Factur-X” और “ZUGFeRD” interchangeable terms हैं. वे schema share करते हैं, embedding mechanism share करते हैं, और जो PDF एक के साथ compliant है वह आम तौर पर दूसरे के साथ भी compliant होता है.

क्या mandatory है, कहाँ, कब

Q2/Q3 2026 rollouts plan करने वाले engineers के लिए non-exhaustive snapshot:

Country Status Required format
Germany invoice receipt के लिए B2B mandatory from 2025-01-01; 2027 से issuing भी EN 16931 (Factur-X / ZUGFeRD / XRechnung)
France large enterprises के लिए mandatory issuing 2026-09; SMEs 2027-09 Factur-X via Chorus Pro
Italy B2B mandatory since 2019 FatturaPA via SDI
Poland Mandatory since 2024-07 KSeF
Spain Mandatory from 2026 (B2B) Facturae via FACe
Belgium Mandatory from 2026-01 Peppol BIS 3

Pattern साफ है: हर EU member state 2024-2027 timeline में EN 16931-compatible e-invoicing का कोई न कोई flavour implement कर रहा है. अगर आपके customers इन markets में operate करते हैं, तो आपके PDF generator को visual invoice के साथ attached XML भी emit करना होगा.

सबसे छोटी practical pipeline

Standards documents क्या prescribe करते हैं, उसे फिलहाल भूलिए. Engineering view यह है:

   ┌─────────────────────┐
   │  Your invoice data  │  (कहीं पहले से JSON object)
   └─────────┬───────────┘


   ┌─────────────────────┐
   │ Build EN 16931 XML  │  (deterministic mapping; tested libs मौजूद हैं)
   └─────────┬───────────┘


   ┌─────────────────────┐
   │ Render PDF/A-3b +   │
   │ attach the XML      │  (gPdf को single API call, या elsewhere two-step)
   └─────────┬───────────┘


   ┌─────────────────────┐
   │  Hand off to        │
   │  Chorus Pro / SDI / │
   │  Peppol / etc       │
   └─────────────────────┘

दो non-trivial steps:

Step 1: XML build करें

यह annoying है लेकिन mechanical है. आप invoice data, जैसे lines, taxes, totals और parties, को EN 16931 XML field names पर map करते हैं. Java/Node/Python की कई libraries यह कर देती हैं; अपनी language में “factur-x library” search करें. XML schema specs सच में पसंद हों तभी इसे scratch से लिखें.

Step 2: PDF/A-3 render करें और XML attach करें

यहाँ renderer choice मायने रखती है.

Built-in support के बिना: आप ordinary PDF render करते हैं, फिर एक tool से post-process करते हैं जो PDF/A-3 में convert भी करे और XML को embedded file की तरह attach भी करे. Common stacks: Ghostscript + qpdf, या Aspose जैसी paid tool. दो extra steps, दो extra failure points, और आपको ensure करना पड़ता है कि post-processing visual layout drift न करे.

Built-in support के साथ (gPdf approach): one call.

curl -X POST https://api.gpdf.com/api/v1/e-invoice/render \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "settings": {
      "profile": "pdfa-3b",
      "e_invoice": {
        "standard": "factur_x",
        "profile": "en16931",
        "document_type": "invoice",
        "xml": {
          "format": "cii",
          "encoding": "utf8",
          "content": "<rsm:CrossIndustryInvoice>...</rsm:CrossIndustryInvoice>"
        }
      }
    },
    "pages": [{ "size": "a4", "elements": [...] }]
  }' \
  --output invoice-with-einvoice.pdf

बस यही पूरी pipeline है. Renderer PDF/A-3b emit करता है, आपका XML factur-x.xml या zugferd-invoice.xml के रूप में attach करता है, और bytes return करता है. दोनों filenames consumers पहचानते हैं.

Common gotchas

कुछ बातें लोग कठिन तरीके से सीखते हैं:

“PDF/A” और “PDF/A-compliant fonts के साथ” एक ही बात नहीं हैं

PDF/A-3 file में सभी fonts embedded होने चाहिए और used glyphs की full character coverage होनी चाहिए. अगर invoice में Japanese customer name है और renderer किसी ऐसे fallback font पर जाता है जो fully embeddable नहीं है, तो validation tools इसे reject करेंगी. Check करें कि आपका renderer PDF/A mode में CJK fonts embed करता है; कई default रूप से नहीं करते.

Visual + XML match करने चाहिए

XML invoice और visual invoice को same invoice represent करना चाहिए. Tax auditors उनका diff कर सकते हैं. अगर code XML में total: 119.00 emit करता है और visual PDF Total: 120.00 दिखाता है, rounding bug या stale template की वजह से, तो file में tax discrepancy है. दोनों को same source-of-truth से generate करें, ideally same code path में.

EN 16931 में “profile” levels

Factur-X profiles हैं: MINIMUM, BASIC, EN 16931, EXTENDED. फर्क यह है कि XML में कितना data है. BASIC use करें जब तक customer specifically अधिक न माँगे; यह tax codes, line items, parties और totals cover करता है, जो लगभग 95% B2B invoicing के लिए पर्याप्त है. EN 16931 profile edge cases के लिए extra detail जोड़ता है.

Submission से पहले validation

Generated PDF को PDF/A validator से हमेशा validate करें; veraPDF open-source standard है. XML को भी EN 16931 schema के विरुद्ध validate करें before tax authority को भेजें. Chorus Pro / SDI पर failed submissions regulator के साथ आपकी reliability metrics को प्रभावित करते हैं.

TL;DR

PDF/A self-contained-document profile है. PDF/A-3 files attach करने देता है. Factur-X / ZUGFeRD का अर्थ है “PDF/A-3 के अंदर attached EN 16931 XML”. EU e-invoice mandates 2025-2027 के बीच इस combination को de facto B2B invoice format बना रहे हैं.

अगर आपका renderer PDF/A-3 + Factur-X को single config flag की तरह treat करता है, तो migration mechanical है. अगर नहीं, तो आप multi-step ops pipeline बना रहे हैं. gPdf का /api/v1/e-invoice/render single-flag version है; API reference में full schema है, या Playground में sample render try करें.