Jeśli w 2026 wysyłasz e-invoices do niemieckiego klienta B2B, plik jest ZUGFeRD-compliant albo zostanie odbity przy odbiorze. We Francji z Factur-X jest tak samo. Format to PDF/A-3 wrapper z dołączonym EN 16931 CII XML; generowanie od zera nie jest trywialne, a walidacja wymaga reference engine.
W praktyce tym engine jest Mustang (mustangproject.org): open-source Java project, który wyciąga embedded XML z PDF/A-3 i waliduje go wobec EN 16931 Schematron. Mustang ma najgłębsze wsparcie dla ZUGFeRD i Factur-X wśród otwartych narzędzi, i to jego uruchamia wiele independent verifiers.
Ten tekst przechodzi przez failure modes, które Mustang zgłasza, oraz szybszy sposób jego uruchomienia.
Co Mustang naprawdę sprawdza
Gdy podasz Mustangowi PDF Factur-X albo ZUGFeRD, robi mniej więcej:
- Wyciąga embedded file. PDF/A-3 przechowuje attachments w name tree
/EmbeddedFiles. Mustang szuka kanonicznej nazwy (factur-x.xmldla Factur-X,zugferd-invoice.xmldla ZUGFeRD 2.x) i czyta bytes. - Sprawdza AFRelationship. Attached file musi być zadeklarowany jako
AFRelationship="Alternative"zgodnie z baseline Factur-X / ZUGFeRD. Inne wartości (Source,Data,Supplement) failują. - Sprawdza XMP namespace i version. Factur-X 1.0 używa
urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#. ZUGFeRD 2.x używaurn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#. Zły namespace albo version string failuje. - Parsuje XML jako Cross-Industry Invoice (CII). XML musi być well-formed i zaczynać się od właściwego CII root element (
rsm:CrossIndustryInvoice). - Uruchamia EN 16931 Schematron. To główna część walidacji: około 200 business rules dotyczących semantyki pól, obowiązkowych kodów, totals math, VAT logic, party identifiers itd.
Pass = faktura jest akceptowalna dla każdego EN 16931-conformant AP system w UE. Fail = AP automation klienta odrzuci invoice przy odbiorze, a AR team dostanie manual exception.
Pięć najczęstszych failure modes
Pojawiają się regularnie po stronie Mustang w validator, gdy zespoły testują pierwsze e-invoices.
1. Wrong AFRelationship
ERROR: Embedded file factur-x.xml uses AFRelationship="Source",
expected "Alternative".
PDF spec dopuszcza kilka relationship types dla attached files. Factur-X / ZUGFeRD wymagają Alternative, czyli attached XML jest alternatywną reprezentacją visible PDF content. Jeśli PDF generator używa Data (default w wielu libraries), Mustang od razu failuje. Widoczny PDF nadal renderuje się poprawnie, ale structured payload nie działa dla AP system.
2. Wrong / missing XMP namespace
ERROR: XMP metadata missing fx:DocumentType or fx:DocumentFileName under
namespace urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#.
XMP packet PDF musi deklarować, który Factur-X profile to jest (MINIMUM, BASIC, EN 16931, EXTENDED) i jakiej nazwy pliku szukać. Łatwo to pominąć przy ręcznym pisaniu PDF/A-3 wrapper; endpoint gPdf /api/v1/e-invoice/render emituje te pola automatycznie.
3. CII XML well-formed, ale EN 16931 Schematron failuje
ERROR: BR-CO-25 — In an invoice (BR-01) the
ram:SpecifiedTradePaymentTerms/ram:DueDateDateTime is required when
ram:DocumentTypeCode is 380.
To większość realnych failures. XML jest składniowo valid; failują business rules. EN 16931 Schematron rules mają stable IDs (BR-01, BR-CO-25 itd.) do sprawdzenia w specyfikacji. Częste:
- BR-01: invoice musi mieć unique invoice number.
- BR-04: invoice musi mieć issue date.
- BR-05: invoice musi mieć invoice type code.
- BR-CO-25: payment terms required, gdy document type to “Commercial invoice”.
- BR-Z-01: VAT category codes muszą być jednym z
S,Z,E,AE,K,G,O,L,M.
Popraw source data, zbuduj ponownie i re-validate.
4. PDF/A wrapper nie waliduje się
INFO: CII XML extracted and validates against EN 16931.
ERROR: PDF/A-3b conformance check failed: missing Output Intent.
Tu XML check Mustanga przechodzi, ale underlying PDF/A-3 wrapper failuje. Częsta przyczyna: XML jest poprawny, ale wygenerowano zwykły PDF zamiast PDF/A-3. Embedded file istnieje, ale archival wrapper rules nie są spełnione. Validator na gpdf.com/validator/ łapie to przez równoległe veraPDF: PDF/A-3 fail jest w kolumnie veraPDF, a Mustang pokazuje XML pass.
5. Encoding / declaration mismatch
ERROR: XML declares <?xml version="1.0" encoding="UTF-8"?> but the
embedded byte stream is UTF-8 with BOM. Mustang strict mode rejects BOM.
Zaskakująco częste, gdy XML tool emituje UTF-8 BOM, a bytes są embedded raw. Fix: strip BOM przed embedding. gPdf e-invoice endpoint normalizuje ten przypadek.
Jak uruchomić Mustang bez instalacji Java
Java + Mustang CLI jest OK dla jednorazowego checku. Przy continuous verification — każda generowana invoice, każdy CI run assertujący e-invoice compliance — to niepotrzebne friction.
gpdf.com/validator/ uruchamia Mustang w przeglądarce:
- Przeciągnij PDF Factur-X / ZUGFeRD do upload zone.
- Validator wyciąga embedded XML i uruchamia Schematron engine Mustang (compiled to JavaScript / WebAssembly, działa w Cloudflare Worker).
- Report Mustang wraca obok veraPDF PDF/A-3 report, bo obie warstwy muszą przejść.
- Pobierz JSON report jako QA evidence.
Bez loginu. Bez quota. Ten sam typ Mustanga, który instalujesz przez Maven, podany jako darmowy public service.
TL;DR
Mustang flaguje 5 common failure modes; większość oznacza, że plik wygenerowało narzędzie, które nie emituje fully-conformant Factur-X / ZUGFeRD PDF/A-3. E-invoice API gPdf emituje go w jednym call. validator sprawdza wynik równolegle przez Mustang + veraPDF.
Większość błędów, które łapie Mustang, dotyczy wrappera albo AFRelationship, nie tylko XML semantics. Poprawne wygenerowanie pliku to większość pracy; validator jest receipt, który to potwierdza.