A document is not accepted because it is correct. It is accepted because it passes every gate between you and the receiver's ledger, and those gates are maintained by four different parties with four different purposes.
Understanding them as a stack, rather than as "validation", is what makes testing plannable. It also explains the most common project experience in this field: everything passed, go-live went smoothly for a fortnight, and then a major customer started rejecting a category of invoice for a reason nobody had heard of.
The four gates
| Gate | What it checks | Who publishes the rules | What a failure looks like |
|---|---|---|---|
| Syntax | The file is well formed and valid against the schema | The syntax maintainer | An immediate, unambiguous parse or schema error |
| Semantic rules | The business rules of the European standard hold: cardinalities, dependencies, arithmetic | The standards body | A rule identifier and a message, usually intelligible |
| Profile rules | The national or sectoral specification's additional restrictions | The profile owner | A rule identifier that means nothing without the profile documentation |
| Receiver rules | The buyer's own requirements: references, coding, tolerances, approved supplier | Nobody. They are internal | A rejection message written for internal staff, or silence |
The asymmetry in that table is the whole point. Effort in most projects is spent on the first three gates, which are documented, testable against public tools and largely a solved problem. The fourth gate is undocumented, untestable in advance without asking, and responsible for the majority of rejections once real volume flows.
Why the first three are the easy part
They are easy because they are deterministic and public. A validator exists, it implements the published rules, and a document either passes or does not.
That is worth using properly rather than dismissing. Automate it, run it on every build, and treat a semantic rule failure as a defect rather than as a warning. The semantic model is stable and its rules are executable by design, which means there is no reason for a document to reach a customer having failed one.
The profile gate is where it starts to require reading. A core invoice usage specification narrows the standard — making optional things mandatory, forbidding elements, restricting code lists — and the rules it adds are specific to it. A document valid against the standard and invalid against the profile is the normal way this fails, and the fix is always in the profile documentation rather than in the standard.
The single most reliable source of profile-gate failures is the exemption and category area, because that is where three layers of constraint meet at once. It is worth testing disproportionately, for the reasons set out in exemption reason codes.
The fourth gate, and how to get at it
A buyer's own rules exist because a buyer has an accounts payable process. They will reject an invoice with no purchase order reference, or with a reference in the wrong format, or from a supplier not on the approved list, or for an amount outside tolerance against the order.
None of that is unreasonable and none of it is in any specification. It also predates e-invoicing entirely — the same rules were applied to PDFs by a person, who would phone you. What changed is that the rule is now applied by software that sends a code.
Three ways to find out what those rules are, in decreasing order of usefulness.
Ask. Before go-live, ask your largest customers what their receiving requirements are. Large organisations frequently have a supplier specification and will send it, and the request is ordinary rather than intrusive. The number of projects that never ask is remarkable.
Look at what they already reject. If you invoice them today on paper or PDF, their queries and rejections are a record of their rules. Somebody in your receivables team has that history in an inbox.
Fail deliberately and early. Send low-value real documents to a real receiver before the deadline, and treat each rejection as information rather than as a problem. A rejection in a controlled pilot costs a phone call. The same rejection in month one of a mandate costs a month of cash flow across a customer segment.
What the corpus has to contain
The failure of most test sets is that they are clean. They contain the documents that were easy to construct, which are the documents that were never going to fail.
- An exempt supply and a zero-rated supply, each with the reason the applicable profile requires
- A reverse-charge document, with the category and the statement the profile expects
- A credit note, and a credit note correcting a document with mixed treatments
- A multi-line document where the line totals and the document total differ by a rounding unit
- A document from every legal entity you will issue from, with that entity's own registrations
- A counterparty whose legal name contains an accented character, an ampersand or a very long string
- A document with the maximum number of lines your system can produce
- A document missing an optional field that a specific receiver treats as mandatory
The rounding case deserves specific mention because it is the one that passes every review and fails in production. Line-level rounding and document-level rounding can produce a difference of a single unit, the semantic rules check the arithmetic, and a document that is right to the penny in your ledger can be arithmetically inconsistent in the document.
Testing is not a phase
Two things change after go-live, and both invalidate a test performed once.
Profiles are revised. A new version of a specification introduces rules that did not exist, and documents that passed will fail. That is not a defect in your system; it is a maintenance obligation, and it belongs in the recurring column of the cost model rather than being discovered as an incident.
Receivers change their internal rules whenever they change their process, and they do not announce it to suppliers. The first indication is a rejection.
So the corpus is an asset with a lifetime, stored and re-run — on every change to your own system, on every published profile revision, and periodically regardless. That is unglamorous regression testing and it is the difference between finding a problem in an environment and finding it in a customer relationship.
When a rejection does arrive
Work outward from the document, because the gate that reported the failure is not always the gate that caused it.
Identify which gate rejected. A syntax or semantic failure is yours and is usually a defect. A profile failure is a documentation question. A receiver failure is a conversation, and it is frequently not a defect at all — it is a requirement you did not know about.
Then decide whether it is systematic. One document failing is an incident. Every document of a type failing is a configuration problem that will produce hundreds more before anyone fixes it, and the distinction determines urgency far more than the value of the invoice does.
That triage is the front end of exception handling, and the reason it belongs here is that a team which cannot tell the four gates apart cannot triage at all. They escalate everything to whoever built it, which works during the project and stops working the moment that person is on something else.