Blog

PDF/A i Factur-X dla inżynierów, bez prawniczego żargonu

Co naprawdę oznaczają profile PDF/A, dlaczego Factur-X staje się wymagany w UE do 2026 roku i jak zbudować najprostszy praktyczny proces zgodności z silnika JSON.

Jeśli jesteś inżynierem i właśnie usłyszałeś, że “faktury muszą być PDF/A-3 z Factur-X do następnego kwartału”, a jedyny kontekst brzmi: “dział prawny tak powiedział”, ten artykuł jest dla ciebie.

Przejdziemy przez standardy bez ich urzędowego tonu: co te profile naprawdę ograniczają, dlaczego administracje zaczęły ich wymagać i jaki jest najmniejszy praktyczny proces emisji zgodnego PDF z silnika danych strukturalnych.

PDF/A w dwóch akapitach

PDF jest formatem elastycznym. Zbyt elastycznym. Ta sama specyfikacja PDF pozwala osadzać JavaScript, linkować do zasobów zewnętrznych, które mogą nie istnieć za 50 lat, szyfrować treść odwracalną kryptografią, odwoływać się do zewnętrznych fontów i robić setki innych rzeczy, które sprawiają, że dokument nie jest samowystarczalny.

PDF/A (“A” od Archival) to profil PDF, który zakazuje elementów uniemożliwiających identyczne renderowanie dokumentu za 50 lat. Najważniejsze reguły:

  • Wszystkie fonty muszą być osadzone.
  • Bez JavaScript, bez linków zewnętrznych, bez audio/wideo.
  • Bez szyfrowania.
  • Przezroczystość musi być spłaszczona albo obsługiwana przez daną wersję profilu.
  • Kolory muszą być niezależne od urządzenia, z wymaganym profilem ICC.
  • Cała treść musi być w pliku, bez odwołań zależnych od sieci.

Istnieje kilka wersji, a każda dopuszcza trochę nowszych możliwości:

Profil Rok Co dodaje
PDF/A-1b 2005 Pierwotna baza, najbardziej rygorystyczna
PDF/A-2b 2011 Pozwala na JPEG2000, przezroczystość i warstwy
PDF/A-3b 2012 Pozwala na dowolne załączniki plikowe, czyli fundament Factur-X
PDF/A-4 2020 Baza ISO 32000-2 (PDF 2.0), prostsze poziomy zgodności

Sufiks “b” oznacza zgodność basic, czyli wierność wizualną. Istnieją też warianty “u” z mapowaniem Unicode oraz “a” z tagowaniem dostępnościowym. Dla większości procesów faktur i potwierdzeń właściwy jest poziom “b”, bo archiwizacja podatkowa dotyczy odtwarzalności wizualnej, nie semantyki dla czytników ekranowych.

Praktyczny wniosek: jeśli silnik renderowania deklaruje obsługę PDF/A-3b, powinno to być jedno ustawienie konfiguracyjne ({ profile: "PDF/A-3b" } albo odpowiednik). Jeśli po renderowaniu musisz uruchamiać drugie narzędzie, takie jak Ghostscript, qpdf albo Acrobat, żeby wykonać konwersję, to jest luka operacyjna, którą trzeba uwzględnić.

Dlaczego PDF/A-3 ma znaczenie: przenosi e-faktury

PDF/A-3 dodał jedną funkcję, która okazała się przełomowa: dowolne załączniki plikowe wewnątrz PDF.

Brzmi nudno. Nie jest. To techniczny fundament obowiązków e-fakturowania, które właśnie rozchodzą się po Europie.

Architektura wygląda tak: jeden plik PDF jest jednocześnie:

  1. fakturą czytelną dla człowieka, z układem wizualnym, sumami i brandingiem, czyli częścią, którą czyta osoba;
  2. fakturą XML czytelną maszynowo, czyli częścią parsowaną przez oprogramowanie administracji podatkowej.

Obie części znajdują się w jednym pliku i reprezentują tę samą fakturę, a opakowanie PDF/A-3 gwarantuje, że plik pozostanie możliwy do odczytu przez dekady.

Dwa główne formaty XML:

  • Factur-X (Francja), profil XML oparty na UN/CEFACT Cross Industry Invoice
  • ZUGFeRD (Niemcy), merytorycznie identyczny z Factur-X; oba standardy połączyły się technicznie w 2018 roku
  • EN 16931, europejska norma, z którą zgodne są obie implementacje

Dla większości procesów “Factur-X” i “ZUGFeRD” są terminami wymiennymi. Dzielą schemat, mechanizm osadzania i zwykle pojedynczy PDF zgodny z jednym jest też zgodny z drugim.

Co jest wymagane, gdzie i kiedy

Niewyczerpujący snapshot dla inżynierów planujących wdrożenia Q2/Q3 2026:

Kraj Status Wymagany format
Niemcy B2B obowiązkowe od 2025-01-01 dla odbioru faktur; od 2027 także dla wystawiania EN 16931 (Factur-X / ZUGFeRD / XRechnung)
Francja Obowiązkowe wystawianie dla dużych przedsiębiorstw od 2026-09; dla MŚP od 2027-09 Factur-X via Chorus Pro
Włochy B2B obowiązkowe od 2019 FatturaPA via SDI
Polska Obowiązkowe od 2024-07 KSeF
Hiszpania Obowiązkowe od 2026 (B2B) Facturae via FACe
Belgia Obowiązkowe od 2026-01 Peppol BIS 3

Wzorzec jest jasny: każde państwo członkowskie UE wdraża jakiś wariant e-fakturowania zgodnego z EN 16931 w latach 2024-2027. Jeśli twoi klienci działają na którymkolwiek z tych rynków, generator PDF będzie musiał emitować załączony XML obok wizualnej faktury.

Najmniejszy praktyczny proces

Odłóżmy na bok język dokumentów standaryzacyjnych. Z perspektywy inżyniera wygląda to tak:

   ┌─────────────────────┐
   │  Dane faktury       │  (już istnieją gdzieś jako obiekt JSON)
   └─────────┬───────────┘


   ┌─────────────────────┐
   │ Zbuduj XML          │  (deterministyczne mapowanie; istnieją sprawdzone biblioteki)
   │ EN 16931            │
   └─────────┬───────────┘


   ┌─────────────────────┐
   │ Wyrenderuj          │
   │ PDF/A-3b +          │
   │ dołącz XML          │  (jedno wywołanie API w gPdf albo dwa kroki gdzie indziej)
   └─────────┬───────────┘


   ┌─────────────────────┐
   │  Przekaż do         │
   │  Chorus Pro / SDI / │
   │  Peppol / etc       │
   └─────────────────────┘

Dwa kroki są nietrywialne.

Krok 1: zbuduj XML

To irytujące, ale mechaniczne. Mapujesz dane faktury, takie jak pozycje, podatki, sumy i strony, na nazwy pól XML EN 16931. Kilka bibliotek Java, Node i Python robi to za ciebie. Szukaj biblioteki Factur-X w swoim języku. Nie pisz tego od zera, chyba że naprawdę lubisz specyfikacje schematów XML.

Krok 2: wyrenderuj PDF/A-3 i dołącz XML

Tutaj znaczenie ma wybór silnika renderowania.

Bez wbudowanej obsługi: renderujesz zwykły PDF, a potem przetwarzasz go narzędziem, które konwertuje do PDF/A-3 i dołącza XML jako osadzony plik. Typowe stosy to Ghostscript + qpdf albo płatne narzędzie, takie jak Aspose. To dwa dodatkowe kroki, dwa dodatkowe punkty awarii i konieczność upewnienia się, że post-processing nie zmienia układu wizualnego.

Z wbudowaną obsługą (podejście gPdf): jedno wywołanie.

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": "<?xml version=\"1.0\"?><rsm:CrossIndustryInvoice>...</rsm:CrossIndustryInvoice>"
        }
      }
    },
    "pages": [{ "size": "a4", "elements": [/* invoice layout */] }]
  }' \
  --output invoice-with-einvoice.pdf

To cały proces. Renderer emituje PDF/A-3b, dołącza twój XML jako factur-x.xml albo zugferd-invoice.xml, oba rozpoznawane przez konsumentów, i zwraca bajty.

Typowe pułapki

Kilku rzeczy zespoły uczą się w bolesny sposób.

“PDF/A” i “fonty zgodne z PDF/A” to nie to samo

Plik PDF/A-3 wymaga, żeby wszystkie fonty były osadzone z pełnym pokryciem użytych glifów. Jeśli faktura zawiera japońską nazwę klienta, a silnik wraca do fontu, którego nie da się w pełni osadzić, narzędzia walidujące odrzucą plik. Sprawdź, czy silnik renderowania osadza fonty CJK w trybie PDF/A. Wiele silników domyślnie tego nie robi.

Warstwa wizualna i XML muszą się zgadzać

Faktura XML i wizualna faktura mają reprezentować tę samą fakturę. Audytorzy podatkowi będą je porównywać. Jeśli kod emituje XML z total: 119.00, a wizualny PDF pokazuje Total: 120.00 przez błąd zaokrąglenia albo stary szablon, masz zapisaną rozbieżność podatkową. Generuj oba artefakty z jednego źródła danych, najlepiej w tej samej ścieżce kodu.

Poziomy profili w EN 16931

Factur-X ma profile: MINIMUM, BASIC, EN 16931, EXTENDED. Różnią się ilością danych w XML. Użyj BASIC, chyba że klient wyraźnie wymaga więcej. Ten profil obejmuje kody podatkowe, pozycje, strony i sumy, co wystarcza dla około 95% fakturowania B2B. Profil EN 16931 dodaje więcej szczegółów dla przypadków brzegowych.

Walidacja przed wysłaniem

Zawsze waliduj wygenerowany PDF walidatorem PDF/A (veraPDF to standard open-source) oraz waliduj XML względem schematu EN 16931 zanim wyślesz plik do administracji podatkowej. Nieudane wysyłki do Chorus Pro / SDI liczą się przeciwko metrykom niezawodności wobec regulatora.

TL;DR

PDF/A to profil samowystarczalnego dokumentu. PDF/A-3 pozwala dołączać pliki. Factur-X / ZUGFeRD to “XML EN 16931 dołączony wewnątrz PDF/A-3”. Obowiązki e-fakturowania w UE czynią tę kombinację de facto formatem faktur B2B w latach 2025-2027.

Jeśli silnik renderowania traktuje PDF/A-3 + Factur-X jako jedno ustawienie, migracja jest mechaniczna. Jeśli nie, budujesz wieloetapowy proces operacyjny. gPdf /api/v1/e-invoice/render to wersja z jednym ustawieniem: pełny schemat jest w dokumentacji API, a przykładowy render możesz uruchomić w Playground.