2026년에 독일 B2B 고객에게 e-invoice를 보내는 경우, 파일은 ZUGFeRD-compliant이거나 수신 시 bounce됩니다. 프랑스의 Factur-X도 마찬가지입니다. 형식은 EN 16931 CII XML이 첨부된 PDF/A-3 wrapper입니다. 처음부터 생성하기 어렵고, 검증에는 reference engine이 필요합니다.
실무에서 그 engine은 Mustang(mustangproject.org)입니다. PDF/A-3에서 embedded XML을 추출하고 EN 16931 Schematron에 대해 validate하는 open-source Java project입니다. ZUGFeRD와 Factur-X에 대한 open-source support가 가장 깊고, 많은 independent verifiers가 Mustang을 실행합니다.
이 글은 Mustang이 flag하는 failure modes와 더 빠르게 실행하는 방법을 설명합니다.
Mustang이 실제로 확인하는 것
Factur-X 또는 ZUGFeRD PDF를 Mustang에 넣으면 대략 다음을 수행합니다.
- Embedded file 추출. PDF/A-3는 attachments를
/EmbeddedFilesname tree에 저장합니다. Mustang은 canonical filename(Factur-X는factur-x.xml, ZUGFeRD 2.x는zugferd-invoice.xml)을 찾아 bytes를 읽습니다. - AFRelationship 확인. Attached file은 Factur-X / ZUGFeRD baseline에 따라
AFRelationship="Alternative"로 선언되어야 합니다. 다른 값(Source,Data,Supplement)은 fail입니다. - XMP namespace와 version 확인. Factur-X 1.0은
urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#를 씁니다. ZUGFeRD 2.x는urn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#를 씁니다. Namespace나 version string이 틀리면 fail입니다. - XML을 Cross-Industry Invoice (CII)로 parse. XML은 well-formed여야 하고 올바른 CII root element(
rsm:CrossIndustryInvoice)로 시작해야 합니다. - EN 16931 Schematron 실행. 검증의 대부분입니다. Field semantics, mandatory codes, totals math, VAT logic, party identifiers 등 약 200개 business rules를 확인합니다.
Pass는 invoice가 EU 내 EN 16931-conformant AP system에서 받아들여질 수 있다는 뜻입니다. Fail은 고객 AP automation이 receipt에서 invoice를 reject하고 AR team이 manual exception을 처리하게 된다는 뜻입니다.
가장 자주 보는 5가지 failure modes
팀들이 첫 e-invoices를 테스트할 때 validator의 Mustang 쪽에서 반복적으로 나타납니다.
1. Wrong AFRelationship
ERROR: Embedded file factur-x.xml uses AFRelationship="Source",
expected "Alternative".
PDF spec은 attached files에 여러 relationship types를 허용합니다. Factur-X / ZUGFeRD는 Alternative를 요구합니다. 즉 attached XML은 visible PDF content의 alternative representation입니다. PDF generator가 Data를 사용한다면(많은 libraries의 default), Mustang은 즉시 fail합니다. Visible PDF는 정상 render되지만 structured payload는 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#.
PDF의 XMP packet은 어떤 Factur-X profile인지(MINIMUM, BASIC, EN 16931, EXTENDED)와 어떤 filename을 찾아야 하는지 선언해야 합니다. PDF/A-3 wrapper를 손으로 작성하면 빠뜨리기 쉽습니다. gPdf의 /api/v1/e-invoice/render endpoint는 이를 자동으로 emit합니다.
3. CII XML은 well-formed이지만 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.
현실의 failures 대부분은 여기입니다. XML 문법은 valid하지만 business rules가 fail합니다. EN 16931 Schematron rules에는 stable IDs(BR-01, BR-CO-25 등)가 있어 specification에서 lookup할 수 있습니다. 흔한 것:
- BR-01: invoice에는 unique invoice number가 있어야 합니다.
- BR-04: issue date가 있어야 합니다.
- BR-05: invoice type code가 있어야 합니다.
- BR-CO-25: document type이 “Commercial invoice”이면 payment terms가 필요합니다.
- BR-Z-01: VAT category codes는
S,Z,E,AE,K,G,O,L,M중 하나여야 합니다.
Source data를 고치고 rebuild한 뒤 re-validate하세요.
4. PDF/A wrapper 자체가 validate되지 않음
INFO: CII XML extracted and validates against EN 16931.
ERROR: PDF/A-3b conformance check failed: missing Output Intent.
이 경우 Mustang의 XML check는 pass하지만 underlying PDF/A-3 wrapper는 fail합니다. 흔한 원인은 XML은 제대로 작성했지만 PDF/A-3가 아니라 ordinary PDF를 emit한 것입니다. Embedded file은 있지만 archival wrapper rules가 충족되지 않습니다. gpdf.com/validator/는 veraPDF를 parallel 실행해 이를 잡습니다. PDF/A-3 fail은 veraPDF column에, Mustang은 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.
XML tool이 UTF-8 BOM을 emit하고 그 bytes를 raw로 embed할 때 자주 생깁니다. 해결은 embedding 전에 BOM을 strip하는 것입니다. gPdf e-invoice endpoint는 이를 normalise합니다.
Java 설치 없이 Mustang 실행하기
One-off check라면 Java + Mustang CLI 설치도 괜찮습니다. 하지만 지속적 verification, 즉 invoice 생성마다, e-invoice compliance를 assert하는 CI run마다 사용한다면 불필요한 friction입니다.
gpdf.com/validator/는 Mustang을 browser에서 실행합니다.
- Factur-X / ZUGFeRD PDF를 upload zone에 drag합니다.
- Validator가 embedded XML을 추출하고 Mustang의 Schematron engine을 실행합니다(JavaScript / WebAssembly로 compiled, Cloudflare Worker에서 run).
- Mustang report는 veraPDF의 PDF/A-3 report와 side-by-side로 돌아옵니다. 두 layer가 모두 pass해야 하기 때문입니다.
- QA evidence용 JSON report를 download합니다.
Login 없음. Quota 없음. Maven으로 설치하는 Mustang과 같은 종류의 check를 free public service로 제공합니다.
TL;DR
Mustang은 5가지 common failure modes를 flag합니다. 대부분은 “fully-conformant Factur-X / ZUGFeRD PDF/A-3를 emit하지 않는 tool로 생성된 파일”이라는 뜻입니다. gPdf의 E-invoice API는 한 번의 call로 이를 emit합니다. validator는 Mustang + veraPDF로 결과를 parallel verify합니다.
Mustang이 잡는 bugs 대부분은 wrapper 또는 AFRelationship 문제이며 XML semantics만의 문제가 아닙니다. File을 올바르게 generate하는 것이 대부분의 작업이고, validator는 그것을 증명하는 receipt입니다.