Если в 2026 году вы отправляете e-invoices немецкому B2B-клиенту, файл либо ZUGFeRD-compliant, либо будет отклонен при получении. Во Франции с Factur-X та же логика. Формат — PDF/A-3 wrapper с вложенным EN 16931 CII XML; сгенерировать его с нуля непросто, а для проверки нужен reference engine.
На практике этот engine — Mustang (mustangproject.org): open-source Java-проект, который извлекает embedded XML из PDF/A-3 и валидирует его по EN 16931 Schematron. У Mustang самая глубокая поддержка ZUGFeRD и Factur-X среди open-source инструментов, и именно его запускают многие независимые валидаторы.
Ниже — типичные failures, которые показывает Mustang, и более быстрый способ запускать проверку.
Что Mustang реально проверяет
Когда вы даете Mustang PDF Factur-X или ZUGFeRD, он примерно делает следующее:
- Извлекает embedded file. PDF/A-3 хранит attachments в name tree
/EmbeddedFiles. Mustang ищет каноническое имя (factur-x.xmlдля Factur-X,zugferd-invoice.xmlдля ZUGFeRD 2.x) и читает bytes. - Проверяет AFRelationship. Attached file должен быть объявлен как
AFRelationship="Alternative"по baseline Factur-X / ZUGFeRD. Любое другое значение (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). XML должен быть well-formed и начинаться с правильного CII root element (
rsm:CrossIndustryInvoice). - Запускает EN 16931 Schematron. Это основная часть проверки: около 200 business rules по семантике полей, обязательным кодам, математике totals, VAT logic, party identifiers и т. д.
Pass = invoice приемлем для любого EN 16931-conformant AP system в ЕС. Fail = AP automation клиента отклонит invoice при получении, а AR team получит manual exception.
Пять самых частых failures
Они постоянно появляются в колонке Mustang на validator, когда команды тестируют первые e-invoices.
1. Wrong AFRelationship
ERROR: Embedded file factur-x.xml uses AFRelationship="Source",
expected "Alternative".
PDF spec допускает несколько relationship types для attached files. Factur-X / ZUGFeRD требуют именно Alternative: attached XML является альтернативным представлением видимого PDF content. Если ваш PDF generator использует Data (частый default в libraries), Mustang сразу падает. Видимый PDF все еще рендерится, но 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#.
XMP packet PDF должен объявлять Factur-X profile (MINIMUM, BASIC, EN 16931, EXTENDED) и имя файла, которое нужно искать. Это легко забыть при ручной сборке PDF/A-3 wrapper; endpoint gPdf /api/v1/e-invoice/render автоматически emits эти поля.
3. CII XML well-formed, но EN 16931 Schematron падает
ERROR: BR-CO-25 — In an invoice (BR-01) the
ram:SpecifiedTradePaymentTerms/ram:DueDateDateTime is required when
ram:DocumentTypeCode is 380.
Это основная масса реальных failures. XML синтаксически валиден; падают business rules. У EN 16931 Schematron rules есть стабильные IDs (BR-01, BR-CO-25 и т. д.), которые можно искать в спецификации. Частые:
- BR-01: invoice должен иметь уникальный номер.
- BR-04: invoice должен иметь issue date.
- BR-05: invoice должен иметь invoice type code.
- BR-CO-25: payment terms обязательны, когда document type — “Commercial invoice”.
- BR-Z-01: VAT category codes должны быть одним из
S,Z,E,AE,K,G,O,L,M.
Исправьте source data, пересоберите и провалидируйте снова.
4. PDF/A wrapper не валидируется
INFO: CII XML extracted and validates against EN 16931.
ERROR: PDF/A-3b conformance check failed: missing Output Intent.
Здесь XML check в Mustang проходит, но underlying PDF/A-3 wrapper падает. Частая причина: XML написали правильно, но выпустили обычный PDF вместо PDF/A-3. Embedded file есть, но archival wrapper rules не выполнены. Validator на gpdf.com/validator/ ловит это параллельным veraPDF: PDF/A-3 fail появляется в колонке veraPDF, пока 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 emit-ит UTF-8 BOM, а затем эти bytes встраиваются raw. Исправление: удалить BOM перед embedding. E-invoice endpoint gPdf нормализует это.
Как запускать Mustang без установки Java
Java + Mustang CLI подходят для разовой проверки. Но для постоянной верификации — каждый generated invoice, каждый CI run для e-invoice compliance — это лишнее friction.
gpdf.com/validator/ запускает Mustang в браузере:
- Перетащите Factur-X / ZUGFeRD PDF в upload zone.
- Validator извлекает embedded XML и запускает Schematron engine Mustang (compiled to JavaScript / WebAssembly, runs in the Cloudflare Worker).
- Report Mustang возвращается рядом с veraPDF PDF/A-3 report, потому что обе layers должны пройти.
- Скачайте JSON report как QA evidence.
Без login. Без quota. Та же проверка Mustang, которую вы поставили бы через Maven, просто как бесплатный публичный сервис.
TL;DR
Mustang показывает 5 common failure modes; чаще всего это означает, что файл сгенерирован инструментом, который не emit-ит полностью conformant Factur-X / ZUGFeRD PDF/A-3. E-invoice API gPdf делает это одним вызовом. validator проверяет результат Mustang + veraPDF параллельно.
Большинство багов, которые ловит Mustang, связаны с wrapper или AFRelationship, а не только с XML semantics. Правильная генерация файла — большая часть работы; validator — receipt, который это доказывает.