Electronic invoicing in Belgium (Peppol BIS)

Status as of 27/07/2026: scope delivered = UBL generation, peppol-bis variant (Epic 6, Story 6.1), validation against the official Peppol BIS Billing 3.0 rule pack (Story 13.1), CII↔UBL conversion, UBL extraction.

What the regulation says

Since January 2026, liable Belgian companies must be able to issue and receive structured electronic invoices over the Peppol network, in the Peppol BIS Billing 3.0 specialization (itself a specialization of UBL 2.1, based on the EN 16931 standard).

What Heartwood covers today

  • UBL 2.1 generation in the peppol-bis variant (POST /v1/generate/ubl?variant=peppol-bis) — same EN 16931 pivot model as Factur-X/CII generation (Epic 1).
  • Validation against the official Peppol BIS Billing 3.0 rule pack (ubl-peppol-bis-3.0.20, Story 13.1): OASIS UBL 2.1 XSD schema and the two official OpenPEPPOL schematron passes (CEN-EN16931-UBL: generic EN 16931 core; PEPPOL-EN16931-UBL: additional rules specific to the Peppol network, PEPPOL-EN16931-R* codes). Selectable explicitly (?rulepack=ubl-peppol-bis-3.0.20) or selected automatically: POST /v1/validate recognizes a UBL document that itself declares targeting Peppol (cbc:CustomizationID) and applies this rule pack with no additional parameter — see rulepacks/README.md for the selection mechanism. The response always cites the pack applied with its version (rulepack.id, rulepack.version), never a "compliant" verdict without specifying against what.
  • Conversion CII↔UBL (POST /v1/convert) — useful to interoperate with a French partner (CII) and a Belgian partner (UBL Peppol) without re-keying.
  • Extraction of a received UBL to normalized JSON (POST /v1/extract) — same schema as for Factur-X/CII.

Known limits

  • The Peppol rule pack is only verified against a single official example (rules/examples/base-example.xml from the OpenPEPPOL repository, release v3.0.20) during the development of this story — not against the complete reference corpus. See rulepacks/ubl-peppol-bis-3.0.20/NOTICE.md.
  • Peppol national rules (rules/national-examples/, e.g. Greece, Norway) are not integrated — only the generic Peppol BIS core (CEN + PEPPOL) is.
  • The Peppol schematron artifacts are never committed to this repository: the OpenPeppol AISBL license forbids their redistribution/repackaging without prior agreement. scripts/peppol-rulepack/fetch-and-compile.sh downloads and compiles them locally (dev, CI, image build) after checking a pinned SHA-256 fingerprint — without a prior run of this script, Peppol validation only covers the XSD schema (schematronChecked: false), never a silent false "compliant".
  • The Peppol network itself is not covered: Heartwood generates/ validates/converts/extracts documents, but transmits nothing over the Peppol network (not a Peppol Access Point) — see the project README for the product scope.
  • [ASSUMPTION]: the fr-socle, peppol-bis and xrechnung variants today share exactly the same core set of modeled fields (core.Invoice) on the generation side — no rule specific to Peppol BIS is distinguished there yet (validation, on the other hand, now applies the real official rules since Story 13.1).