Blog

Walidacja ZUGFeRD w Mustang: co przechodzi, co odpada i dlaczego

Mustang to de facto referencyjny checker dla Factur-X / ZUGFeRD. Typowe tryby błędów przy osadzaniu XML CII w PDF/A-3 i sposób weryfikacji przed wysyłką.

Jeśli w 2026 roku wysyłasz e-faktury do niemieckiego klienta B2B, plik jest zgodny z ZUGFeRD albo zostanie odrzucony przy odbiorze. We Francji z Factur-X jest podobnie. Format to opakowanie PDF/A-3 z dołączonym XML CII EN 16931. Wygenerowanie go od zera nie jest trywialne, a sprawdzenie wymaga silnika referencyjnego.

W praktyce tym silnikiem jest Mustang (mustangproject.org): open-source’owy projekt Java, który wyciąga osadzony XML z PDF/A-3 i waliduje go względem Schematron EN 16931. Mustang ma najgłębszą obsługę ZUGFeRD i Factur-X wśród narzędzi open-source i to jego uruchamia większość niezależnych verifierów.

Ten artykuł pokazuje tryby błędów zgłaszane przez Mustang oraz szybszy sposób jego uruchamiania.

Co Mustang naprawdę sprawdza

Gdy podajesz Mustangowi PDF Factur-X albo ZUGFeRD, narzędzie robi mniej więcej to:

  1. Wyciąga osadzony plik. PDF/A-3 przechowuje załączniki w drzewie nazw /EmbeddedFiles. Mustang szuka kanonicznej nazwy pliku (factur-x.xml dla Factur-X, zugferd-invoice.xml dla ZUGFeRD 2.x) i podnosi bajty.
  2. Sprawdza AFRelationship. Dołączony plik musi być zadeklarowany jako AFRelationship="Alternative" zgodnie z bazową regułą Factur-X / ZUGFeRD. Wszystko inne (Source, Data, Supplement) kończy się błędem.
  3. Sprawdza przestrzeń nazw XMP i wersję. Factur-X 1.0 używa urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#. ZUGFeRD 2.x używa urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#. Błędna przestrzeń nazw albo zły ciąg wersji oblewa sprawdzenie.
  4. Parsuje XML jako Cross-Industry Invoice (CII). Musi to być poprawnie sformułowany XML zaczynający się od właściwego elementu głównego CII (rsm:CrossIndustryInvoice).
  5. Uruchamia Schematron EN 16931. To główna część walidacji: około 200 reguł biznesowych dotyczących semantyki pól, obowiązkowych kodów, matematyki sum, logiki VAT, identyfikatorów stron i podobnych warunków.

Pass = faktura jest akceptowalna dla każdego systemu AP zgodnego z EN 16931 w UE. Fail = automatyzacja AP klienta odrzuci fakturę przy odbiorze, a zespół AR dostanie ręczny wyjątek do obsługi.

Pięć najczęstszych trybów błędów

Te problemy regularnie pojawiają się po stronie Mustanga w validator, gdy zespoły testują swoje pierwsze e-faktury.

1. Wrong AFRelationship

ERROR: Embedded file factur-x.xml uses AFRelationship="Source",
expected "Alternative".

Specyfikacja PDF dopuszcza kilka typów relacji dla dołączonych plików. Factur-X / ZUGFeRD wymagają konkretnie Alternative, czyli osadzony XML jest alternatywną reprezentacją widocznej treści PDF. Jeśli generator PDF używa Data, co jest domyślne w wielu bibliotekach, Mustang od razu zwróci błąd. Widoczny PDF nadal renderuje się poprawnie; strukturalne dane pozostają jednak niewidoczne dla systemu AP.

2. Wrong / missing XMP namespace

ERROR: XMP metadata missing fx:DocumentType or fx:DocumentFileName under
namespace urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#.

Pakiet XMP w PDF musi deklarować profil Factur-X, na przykład MINIMUM, BASIC, EN 16931 albo EXTENDED, oraz nazwę pliku, której należy szukać. Łatwo to pominąć, gdy ręcznie składasz opakowanie PDF/A-3. Punkt końcowy gPdf /api/v1/e-invoice/render emituje te pola automatycznie.

3. CII XML well-formed, ale EN 16931 Schematron fails

ERROR: BR-CO-25 — In an invoice (BR-01) the
  ram:SpecifiedTradePaymentTerms/ram:DueDateDateTime is required when
  ram:DocumentTypeCode is 380.

To większość rzeczywistych błędów. XML jest poprawny składniowo, ale zawodzą reguły biznesowe. Reguły Schematron EN 16931 mają stabilne identyfikatory, takie jak BR-01, BR-CO-25 i podobne, które można sprawdzić w specyfikacji EN 16931. Częste przypadki:

  • BR-01: faktura musi mieć unikalny numer faktury.
  • BR-04: faktura musi mieć datę wystawienia.
  • BR-05: faktura musi mieć kod typu faktury.
  • BR-CO-25: warunki płatności są wymagane, gdy typ dokumentu to “Commercial invoice”.
  • BR-Z-01: kody kategorii VAT muszą być jednym z S, Z, E, AE, K, G, O, L, M.

Popraw dane źródłowe, zbuduj plik ponownie i zweryfikuj jeszcze raz.

4. PDF/A wrapper doesn’t actually validate

INFO: CII XML extracted and validates against EN 16931.
ERROR: PDF/A-3b conformance check failed: missing Output Intent.

To przypadek, w którym kontrola XML w Mustang przechodzi, ale bazowe opakowanie PDF/A-3 nie spełnia wymagań. Typowa przyczyna: ktoś poprawnie przygotował XML, ale wyemitował zwykły PDF zamiast PDF/A-3. Osadzony plik istnieje, lecz reguły archiwalnego opakowania nie są spełnione. Validator na gpdf.com/validator/ wyłapuje to przez równoległe uruchomienie veraPDF: błąd PDF/A-3 pojawia się w kolumnie veraPDF, podczas gdy Mustang pokazuje pass dla XML.

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ęsty problem, gdy XML powstaje w narzędziu emitującym UTF-8 BOM, a potem te bajty są osadzane bez zmian. Naprawa: usuń BOM przed osadzeniem. Punkt końcowy e-invoice gPdf normalizuje ten przypadek.

Jak uruchomić Mustang bez instalowania Javy

Instalacja Javy i CLI Mustanga jest w porządku dla jednorazowego sprawdzenia. Przy stałej weryfikacji, czyli dla każdej wygenerowanej faktury i każdego uruchomienia CI potwierdzającego zgodność e-faktur, to tarcie, którego nie potrzebujesz.

gpdf.com/validator/ uruchamia Mustang w przeglądarce:

  1. Przeciągnij PDF Factur-X / ZUGFeRD na obszar uploadu.
  2. Validator wyciąga osadzony XML i uruchamia silnik Schematron Mustanga, skompilowany do JavaScript / WebAssembly i działający w Cloudflare Worker.
  3. Raport Mustanga wraca obok raportu PDF/A-3 z veraPDF, ponieważ obie warstwy muszą przejść.
  4. Pobierz raport JSON jako dowód QA.

Bez logowania. Bez limitu kwoty. Ten sam Mustang, który zainstalowałbyś przez Maven, tylko udostępniony jako bezpłatna usługa publiczna.

TL;DR

Mustang wykrywa 5 typowych trybów błędów; większość sprowadza się do tego, że plik został wygenerowany przez narzędzie, które nie emituje w pełni zgodnego PDF/A-3 Factur-X / ZUGFeRD. API e-invoice gPdf emituje taki plik w jednym wywołaniu. validator weryfikuje wynik równolegle w dwóch silnikach: Mustang + veraPDF.

Większość błędów wyłapywanych przez Mustang dotyczy opakowania albo AFRelationship, nie tylko semantyki XML. Poprawne wygenerowanie pliku to większa część pracy; validator jest potwierdzeniem, że została wykonana.