Se você envia e-invoices para um cliente B2B alemão em 2026, o arquivo é ZUGFeRD-compliant ou será rejeitado no recebimento. O mesmo vale para Factur-X na França. O formato é um wrapper PDF/A-3 com um EN 16931 CII XML anexado; gerar isso do zero é não trivial, e validar exige um motor de referência.
Na prática, esse motor é Mustang (mustangproject.org): um projeto Java open-source que extrai o XML embutido de um PDF/A-3 e valida contra EN 16931 Schematron. Ele tem o suporte mais profundo para ZUGFeRD e Factur-X entre ferramentas abertas, e é o que muitos verificadores independentes executam.
Este artigo mostra os modos de falha que Mustang aponta — e uma forma mais rápida de rodá-lo.
O que Mustang realmente checa
Quando você passa um PDF Factur-X ou ZUGFeRD ao Mustang, ele faz aproximadamente:
- Extrai o arquivo embutido. PDF/A-3 armazena anexos na name tree
/EmbeddedFiles. Mustang procura o filename canônico (factur-x.xmlpara Factur-X,zugferd-invoice.xmlpara ZUGFeRD 2.x) e lê os bytes. - Checa AFRelationship. O arquivo anexado deve declarar
AFRelationship="Alternative"conforme a baseline Factur-X / ZUGFeRD. Qualquer outra coisa (Source,Data,Supplement) falha. - Checa namespace XMP e versão. Factur-X 1.0 usa
urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#. ZUGFeRD 2.x usaurn:zugferd:pdfa:CrossIndustryDocument:invoice:2p0#. Namespace ou version string errado falha. - Faz parse do XML como Cross-Industry Invoice (CII). O XML deve ser well-formed e começar pelo root element CII correto (
rsm:CrossIndustryInvoice). - Executa EN 16931 Schematron. É a maior parte da validação: cerca de 200 regras de negócio sobre semântica de campos, códigos obrigatórios, matemática de totais, lógica de VAT, identificadores de partes, etc.
Pass = a fatura é aceitável para qualquer sistema AP conforme EN 16931 na UE. Fail = a automação AP do cliente rejeitará a fatura no recebimento e o time AR terá uma exceção manual.
Os cinco modos de falha mais comuns
Eles aparecem repetidamente no lado Mustang do validator quando equipes testam suas primeiras e-invoices.
1. AFRelationship errado
ERROR: Embedded file factur-x.xml uses AFRelationship="Source",
expected "Alternative".
A especificação PDF permite vários relationship types para arquivos anexados. Factur-X / ZUGFeRD exigem Alternative: o XML anexado é uma representação alternativa do conteúdo visível no PDF. Se seu gerador usa Data (default em muitas bibliotecas), Mustang falha imediatamente. O PDF visível ainda renderiza, mas o payload estruturado não é útil para o sistema AP.
2. Namespace XMP errado ou ausente
ERROR: XMP metadata missing fx:DocumentType or fx:DocumentFileName under
namespace urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#.
O pacote XMP do PDF deve declarar qual perfil Factur-X é (MINIMUM, BASIC, EN 16931, EXTENDED) e qual filename deve ser procurado. É fácil esquecer ao escrever o wrapper PDF/A-3 manualmente; o endpoint /api/v1/e-invoice/render da gPdf emite isso automaticamente.
3. CII XML bem formado, mas EN 16931 Schematron falha
ERROR: BR-CO-25 — In an invoice (BR-01) the
ram:SpecifiedTradePaymentTerms/ram:DueDateDateTime is required when
ram:DocumentTypeCode is 380.
Aqui está a maior parte das falhas reais. O XML é sintaticamente válido; as regras de negócio falham. As regras EN 16931 Schematron têm IDs estáveis (BR-01, BR-CO-25, etc.) consultáveis na especificação. Comuns:
- BR-01: invoice precisa de número único.
- BR-04: invoice precisa de data de emissão.
- BR-05: invoice precisa de invoice type code.
- BR-CO-25: payment terms obrigatórios quando document type é “Commercial invoice”.
- BR-Z-01: VAT category codes devem ser um de
S,Z,E,AE,K,G,O,L,M.
Corrija os dados fonte, gere novamente e valide de novo.
4. O wrapper PDF/A não valida
INFO: CII XML extracted and validates against EN 16931.
ERROR: PDF/A-3b conformance check failed: missing Output Intent.
Neste caso, o check XML do Mustang passa, mas o wrapper PDF/A-3 falha. Causa comum: alguém escreveu o XML certo, mas emitiu um PDF comum em vez de PDF/A-3. O arquivo embutido está lá, mas as regras de arquivo não foram cumpridas. O validator em gpdf.com/validator/ captura isso rodando veraPDF em paralelo: o fail aparece na coluna veraPDF enquanto Mustang mostra 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.
É comum quando a ferramenta XML emite UTF-8 BOM e os bytes são embutidos raw. A correção: remover o BOM antes de embutir. O endpoint de e-invoice da gPdf normaliza isso.
Como rodar Mustang sem instalar Java
Instalar Java + Mustang CLI é aceitável para uma checagem pontual. Para verificação contínua — toda fatura gerada, todo CI que afirma e-invoice compliance — é atrito desnecessário.
gpdf.com/validator/ roda Mustang no navegador:
- Arraste o PDF Factur-X / ZUGFeRD para a zona de upload.
- O validator extrai o XML embutido e roda o Schematron engine do Mustang (compilado para JavaScript / WebAssembly, executado no Cloudflare Worker).
- O report Mustang volta lado a lado com o report PDF/A-3 do veraPDF, porque as duas camadas precisam passar.
- Baixe o report JSON como evidência de QA.
Sem login. Sem quota. O mesmo tipo de Mustang que você instalaria via Maven, servido como serviço público gratuito.
TL;DR
Mustang aponta 5 falhas comuns; a maioria resume-se a “o arquivo foi gerado por uma ferramenta que não emite um PDF/A-3 Factur-X / ZUGFeRD totalmente conforme”. A E-invoice API da gPdf emite um em uma chamada. O validator verifica o resultado com Mustang + veraPDF em paralelo.
A maior parte dos bugs que Mustang encontra está no wrapper ou no AFRelationship, não apenas na semântica do XML. Gerar o arquivo corretamente é grande parte da batalha; o validator é o recibo que prova isso.