ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

Validation Pipeline

Four validation stages, four error families, four distinct responses — the pattern that makes partner errors actionable.

Problem

An EDI hub receives an INVOIC that gets rejected. The reject says "invalid message". But: is the EDIFACT structure broken? An unknown qualifier? A business rule ("the invoice references a non-existing PO")? A specific Walmart constraint ("supplier number must be 9 digits")? Without distinction, the EDI support operator does not know who to call (partner supplier? internal business team? partner IT?). Handling is undifferentiated: everything goes to DLC, we spend 4h diagnosing.

Forces

  • Errors come from different sources. Partner software bug, business misunderstanding, partner IG misread, inconsistent data.
  • Handling differs. Syntactic error → technical retry. Business error → business escalation. IG error → partner coordination.
  • Different ACKs exist. CONTRL (EDIFACT syntactic), APERAK (EDIFACT application), 999 (X12 implementation), 824 (X12 application advice), NRR (AS4).
  • Validation order matters. No point checking business if syntax is broken.

Solution

Build an ordered four-level pipeline. 1. Syntactic: schema conformance (EDIFACT message definition, UBL XSD, X12 transaction set). 2. Semantic: code and qualifier validity (Schematron on UBL, EN 16931 BR-CO rules, UN/EDIFACT tables). 3. Business: business rules (reference to existing PO, invoice duplicate, amount consistent with lines). 4. Partner: partner Implementation Guide (Walmart custom rules, PEPPOL country profile). Each failure produces an appropriate ACK and a typed event. The pipeline stops at the first failure — no need to test IG on broken syntax.

Inbound message (EDIFACT INVOIC, X12 810, UBL Invoice)
        │
        ▼
  ┌────────────────────────────────┐
  │ 1. Syntactic validation        │
  │    D.96A schema / UBL XSD      │
  │    structure, types, required  │
  └──────┬─────────────────────────┘
   fail  │ → negative CONTRL / 999 / NRR fault → technical DLC
   ok    ▼
  ┌────────────────────────────────┐
  │ 2. Semantic validation         │
  │    qualifiers, codes, enum     │
  │    Schematron, EN 16931 rules  │
  └──────┬─────────────────────────┘
   fail  │ → APERAK / 824           → semantic DLC
   ok    ▼
  ┌────────────────────────────────┐
  │ 3. Business validation         │
  │    business rules (coherence,  │
  │    duplicates, authorisation)  │
  └──────┬─────────────────────────┘
   fail  │ → APERAK + escalation    → exception flow
   ok    ▼
  ┌────────────────────────────────┐
  │ 4. Partner validation          │
  │    Walmart IG, Stellantis      │
  │    specific, proprietary codes │
  └──────┬─────────────────────────┘
   fail  │ → partner functional    → partner workflow
   ok    ▼
  Accepted message → event broker

EDI implementation

Concrete case: Factur-X hub receives an electronic invoice. Step 1 — UBL 2.1 XSD validates XML structure, returns a FHIR-like OperationOutcome structured if fail. Step 2 — EN 16931 Schematron (BR-CO-01 to BR-CO-25, BR-DE-XX for Germany, BR-FR-XX for France via Factur-X): tax/total consistency, SIRET format, EC valid currency. Step 3 — internal business rules: "the referenced PO exists", "not already invoiced", "amount consistent with received ASN". Step 4 — specific IG: for Walmart, GS06 must be the EIN; for PEPPOL FR, IBAN mandatory. Each step emits: InvoiceSyntacticallyValid, InvoiceSemanticallyValid, InvoiceBusinessValid, InvoicePartnerValid, or typed failure variants. The ops operator has a per-stage dashboard: they know to the second whether there is an EN 16931 issue (internal team) or a custom Walmart problem (escalate to partner). Step 2 tools: Saxon-EE Schematron, the OpenAPI KoSIT validator (EN 16931 reference), peppol-validator.

Anti-patterns

  • Monolithic validation. "The message is valid or not": no diagnosis, lost operator.
  • Business validation in step 1. Testing "PO exists" on a message with broken syntax: false positives, false negatives.
  • HTTP 500 instead of negative ACK. The partner does not know validation failed — believes the hub is down.
  • Validation without versioning. An EN 16931 rule changes in 2027, we lose valid 2025 messages. Version pipelines.
  • Validation after enrichment. Enriching before validating consumes resources on messages destined to be rejected. Validate first (at least steps 1+2).

Sources