2026’da Alman bir B2B customer’a e-invoice gönderiyorsanız, dosya ya ZUGFeRD-compliant olur ya da receipt sırasında bounce edilir. Fransa’da Factur-X için de aynı durum geçerlidir. Format, EN 16931 CII XML attachment içeren bir PDF/A-3 wrapper’dır. Bunu sıfırdan generate etmek kolay değildir; validate etmek için reference engine gerekir.
Pratikte bu engine Mustang’dir (mustangproject.org): PDF/A-3 içinden embedded XML extract eden ve EN 16931 Schematron’a karşı validate eden open-source Java project. ZUGFeRD ve Factur-X için open-source araçlar arasında en derin support Mustang’dedir ve birçok independent verifier bunu çalıştırır.
Bu yazı Mustang’in flag ettiği failure modes’u ve daha hızlı çalıştırma yolunu anlatır.
Mustang gerçekte ne kontrol eder
Bir Factur-X veya ZUGFeRD PDF verdiğinizde Mustang kabaca şunları yapar:
- Embedded file extract eder. PDF/A-3 attachments’ı
/EmbeddedFilesname tree içinde saklar. Mustang canonical filename’i arar (factur-x.xmlfor Factur-X,zugferd-invoice.xmlfor ZUGFeRD 2.x) ve bytes’ı okur. - AFRelationship kontrol eder. Attached file, Factur-X / ZUGFeRD baseline gereği
AFRelationship="Alternative"olarak deklar edilmelidir. Diğer değerler (Source,Data,Supplement) fail olur. - XMP namespace ve version kontrol eder. Factur-X 1.0
urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#kullanır. ZUGFeRD 2.xurn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#kullanır. Yanlış namespace veya version string fail olur. - XML’i Cross-Industry Invoice (CII) olarak parse eder. XML well-formed olmalı ve doğru CII root element (
rsm:CrossIndustryInvoice) ile başlamalıdır. - EN 16931 Schematron çalıştırır. Validation’ın büyük kısmı budur: field semantics, mandatory codes, totals math, VAT logic, party identifiers gibi yaklaşık 200 business rule.
Pass = invoice, EU genelinde herhangi bir EN 16931-conformant AP system tarafından kabul edilebilir. Fail = customer’ın AP automation’ı invoice’u receipt sırasında reddeder ve AR team manual exception alır.
En sık gördüğümüz beş failure mode
Teams ilk e-invoices’larını test ederken validator Mustang tarafında bunlar sık çıkar.
1. Wrong AFRelationship
ERROR: Embedded file factur-x.xml uses AFRelationship="Source",
expected "Alternative".
PDF spec attached files için birkaç relationship type’a izin verir. Factur-X / ZUGFeRD specifically Alternative ister: attached XML, visible PDF content’in alternative representation’ıdır. PDF generator Data kullanıyorsa (birçok library’de default), Mustang hemen fail olur. Visible PDF doğru render eder, ama structured payload AP system için geçersizdir.
2. Wrong / missing XMP namespace
ERROR: XMP metadata missing fx:DocumentType or fx:DocumentFileName under
namespace urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#.
PDF’in XMP packet’i bunun hangi Factur-X profile olduğunu (MINIMUM, BASIC, EN 16931, EXTENDED) ve hangi filename’in aranacağını declare etmelidir. PDF/A-3 wrapper’ı elle yazarken kaçması kolaydır; gPdf /api/v1/e-invoice/render endpoint’i bunları auto-emit eder.
3. CII XML well-formed ama EN 16931 Schematron fail
ERROR: BR-CO-25 — In an invoice (BR-01) the
ram:SpecifiedTradePaymentTerms/ram:DueDateDateTime is required when
ram:DocumentTypeCode is 380.
Gerçek dünyadaki failures’ın büyük kısmı buradadır. XML syntactically valid’dir; business rules fail olur. EN 16931 Schematron rules stable IDs taşır (BR-01, BR-CO-25 vb.) ve EN 16931 specification’da lookup edilebilir. Yaygın olanlar:
- BR-01: invoice unique invoice number içermelidir.
- BR-04: invoice issue date içermelidir.
- BR-05: invoice type code olmalıdır.
- BR-CO-25: document type “Commercial invoice” ise payment terms required.
- BR-Z-01: VAT category codes
S,Z,E,AE,K,G,O,L,Mdeğerlerinden biri olmalıdır.
Source data’yı düzeltin, rebuild edin, re-validate edin.
4. PDF/A wrapper validate olmaz
INFO: CII XML extracted and validates against EN 16931.
ERROR: PDF/A-3b conformance check failed: missing Output Intent.
Bu durumda Mustang’in XML check’i pass olur, fakat underlying PDF/A-3 wrapper fail olur. Common cause: XML doğru yazılmıştır ama PDF/A-3 yerine ordinary PDF emit edilmiştir. Embedded file vardır, ama archival wrapper rules karşılanmamıştır. gpdf.com/validator/ bunu veraPDF’i parallel çalıştırarak yakalar: PDF/A-3 fail veraPDF column’da görünürken Mustang XML pass gösterir.
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.
XML tool UTF-8 BOM emit edip bu raw olarak embed edildiğinde şaşırtıcı derecede sık görülür. Fix: embedding öncesi BOM’u strip etmek. gPdf e-invoice endpoint bunu normalise eder.
Java kurmadan Mustang nasıl çalıştırılır
Tek seferlik check için Java + Mustang CLI kurulumu makuldür. Sürekli verification için — her generated invoice, e-invoice compliance assert eden her CI run — gereksiz friction’dır.
gpdf.com/validator/ Mustang’i browser içinde çalıştırır:
- Factur-X / ZUGFeRD PDF’i upload zone’a sürükleyin.
- Validator embedded XML’i extract eder ve Mustang’in Schematron engine’ini çalıştırır (JavaScript / WebAssembly’e compiled, Cloudflare Worker’da run).
- Mustang report, veraPDF PDF/A-3 report ile side-by-side döner; çünkü iki layer da pass olmalıdır.
- QA evidence için JSON report indirin.
Login yok. Quota yok. Maven ile kuracağınız Mustang ile aynı tür kontrol, ücretsiz public service olarak sunulur.
TL;DR
Mustang 5 common failure mode flag eder; çoğu “dosya fully-conformant Factur-X / ZUGFeRD PDF/A-3 emit etmeyen bir tool ile generated” anlamına gelir. gPdf E-invoice API bunu tek call’da emit eder. validator sonucu Mustang + veraPDF ile parallel verify eder.
Mustang’in yakaladığı bugs’ın çoğu wrapper veya AFRelationship sorunlarıdır; yalnızca XML semantics değildir. File’ı doğru generate etmek işin büyük kısmıdır; validator bunu kanıtlayan receipt’tir.