Skip to main content
Belgium Peppol E-Invoicing — Send structured B2B invoices over the Peppol network for Belgium directly from Odoo, with tax ma — 1/1Illustrative preview

Send structured B2B invoices over the Peppol network for Belgium directly from Odoo,

with tax mapping driven by your own master data and a full rejection-and-correction workflow.

ECOSIRE builds, installs and supports it for your exact Odoo version after a scoping call.

What is Belgium Peppol E-Invoicing?

Send structured B2B invoices over the Peppol network for Belgium directly from Odoo, with tax mapping driven by your own master data and a full rejection-and-correction workflow. ECOSIRE builds, installs and supports it for your exact Odoo version after a scoping call. Built to order by ECOSIRE for Odoo 17, 18, 19 — indicative price from $999.00 USD; request a quote for a scoped proposal.

Key Features

Peppol BIS Billing 3.0 outbound document generation from `account.move`, produced at posting from the same data that renders the PDF so the human and machine documents can never diverge
Certified access-point integration with queued, retry-aware transmission driven by `ir.cron` or an automated action, so a slow or unavailable endpoint never blocks the invoicing user
Transmission state machine stored on an inherited `account.move` (draft / queued / sent / acknowledged / rejected) with the access-point message id and timestamps as stored, searchable, filterable fields
`res.partner` extension for Peppol participant identification, typically scheme `0208` for Belgian enterprise numbers, with directory lookup so unreachable customers are caught before posting
Configurable tax mapping from your own `account.tax` records to VAT category codes and exemption reason codes, held as editable data records rather than hard-coded Python
Belgian master-data validation on partners and company: enterprise number format and check digit, VAT number, legal address completeness, with blocking checks surfaced on the invoice form
Rejection handling that stores the specific failed validation rule in readable form on the invoice, flags the record, and notifies the responsible user through the standard `mail.thread` chatter
Correction workflow linking credit notes and corrective invoices to the original document reference so the correction is machine-readable to the receiving party, not just a note
Unit-of-measure and currency code normalisation to the UN/ECE and ISO 4217 code lists the schema requires, mapped from your existing `uom.uom` records
QWeb PDF report generated from the identical posting data, embeddable as the human-readable rendition alongside the structured payload
Immutable archiving of every transmitted payload and every returned acknowledgement as attachments, with an append-only audit log model for retention and inspection
Credential and endpoint configuration held in system parameters, exposed only to an accounting-manager group via `ir.model.access.csv` plus record rules — no credentials in code or in a user-visible field
Multi-company aware: per-company access-point configuration, participant identifiers and sequences, so a Belgian entity inside a group posts under its own identity
Transmission and status models exposed over the standard XML-RPC/JSON-RPC API for treasury tools, portals or middleware, with the same access rules as the UI
Built and tested against your specific Odoo series — 17.0, 18.0 or 19.0 — with view inheritance throughout so existing invoice-form customisations survive the install

Built to order, done for you

No DIY setup — a working app, built, installed and supported by ECOSIRE.

  1. 1

    You order

    Start with a one-time build price. We scope it with you at kickoff.

  2. 2

    We build & install

    ECOSIRE builds, configures and installs it on your Odoo.

  3. 3

    Go live + support

    You go live in about one working week, with two weeks of go-live support. Defects in the code we deliver are fixed free of charge.

Technical Specifications

Odoo Compatibility
Odoo 17, Odoo 18, Odoo 19
Editions
Enterprise & Community
License
Licence confirmation required
Python Requirement
Python 3.10+
Database
PostgreSQL 12+

About this Product

Belgium's move to mandatory structured B2B e-invoicing changes what "sending an invoice" means. A PDF attached to an email is no longer an invoice in the eyes of the process — the legally meaningful document is a structured XML file, validated against Peppol BIS Billing 3.0 rules, transported through a certified access point to your customer's receiving corner, with a transport-level acknowledgement you can produce months later. The finance team's pain is not the format itself; it is that the format is unforgiving. A missing enterprise number, a VAT category code that does not match the tax you actually charged, a unit of measure Odoo stores as "Units" and the schema expects as C62 — any one of these turns a posted invoice into a rejected transmission that nobody notices until the customer chases the payment.

Odoo native gets you partway. account_edi and the UBL/EDI framework in 17.0 and later can produce a UBL document, and Odoo Enterprise ships its own e-invoicing plumbing, but there is a real gap between "Odoo can emit UBL" and "our Belgian entity is compliant". The gap is in your data and your process: the Belgian legal-form and enterprise-number fields on res.partner, the mapping from your specific account.tax records to the correct VAT category and exemption reason codes, what happens when a customer's Peppol participant identifier is unregistered, who is told when a transmission is rejected three hours after posting, and how a credit note is linked back to the original document so the correction is machine-readable rather than a note in the chatter.

What we build is a Belgium-specific compliance layer that sits on top of account.move rather than replacing it. Concretely: an inherited account.move carrying transmission state, the Peppol document identifier, the access-point message id and the returned status, all computed and stored so they are searchable and reportable; a res.partner extension for participant identification (typically 0208 enterprise number for Belgian counterparties) with a lookup against the access point's directory so you learn a customer is unreachable before you post, not after; a configurable mapping layer from your account.tax master data to VAT category codes and exemption reasons, kept as data records so your accountant can amend it without a developer; and a QWeb report so the same posting produces both the machine document and the human-readable PDF your customer's AP clerk still wants to look at, generated from one source of truth so the two can never disagree. Transmission runs through a queued, retry-aware outbound job driven by an automated action or a scheduled ir.cron, so a slow access point never blocks the invoicing user. Rejections come back into a correction workflow: the invoice is flagged, the specific BIS rule that failed is stored in readable form on the record, the responsible user is notified via the standard mail thread, and the corrected document is re-sent or credited with the original reference preserved. Access-point credentials live in system parameters and are exposed only to an accounting-manager group via ir.model.access.csv and record rules, and every sent payload plus every acknowledgement is archived as an immutable attachment with a timestamped audit trail you can hand to an auditor.

Everything is built against the Odoo release you actually run — 17.0, 18.0 or 19.0 — with the __manifest__.py pinned to that series and dependencies declared honestly, including whether the work sits on Community or leans on Enterprise accounting features you already licence. Views are extended, never replaced, so an existing customisation on the invoice form survives the install. Where you need to drive the flow from outside Odoo — a treasury tool, a portal, a middleware layer — the transmission and status models are exposed through the standard XML-RPC/JSON-RPC API rather than through a private hook.

This is a build-to-order product, not a download. It starts with a scoping call where we look at your chart of accounts, your tax records, your customer master data and your access-point arrangement, and we agree in writing what "done" means. From confirmed scope, typical delivery is one working week. You get the module installed on a staging database first, a UAT pass against real historical invoices, then a scheduled go-live with a rollback plan, followed by a post-go-live support window while the first real cycles run. The source code and its git repository are handed over to you at the end — there is no lock-in and no obfuscated build.

What you get

  • Installable module source code built and tested for your exact Odoo series (17.0, 18.0 or 19.0) and your Community or Enterprise edition
  • Installation and configuration on your staging database, including access-point connection setup, tax mapping and partner master-data configuration
  • Technical documentation: model and field reference, extension points, cron and queue behaviour, security groups and record rules, and the API surface for external callers
  • End-user guide for the finance team plus a live training session covering posting, transmission status, rejection handling and the correction workflow
  • UAT on staging against a sample of your real historical invoices, with a written go-live plan and a tested rollback path
  • Scheduled production go-live with ECOSIRE present during the first transmission cycle
  • Post-go-live support window for defect fixes and configuration adjustments while the first real invoicing cycles run
  • Handover of the git repository with full commit history — you own the code, with no obfuscation and no licence lock-in

Who this is for

Finance Manager / Head of Accounting, Belgian entity

Owns the compliance outcome for the Belgian B2B mandate. Needs certainty that every posted customer invoice actually reached the counterparty as a valid structured document, that rejections are visible the same day rather than at month-end chasing, and that the archive will stand up if it is ever asked for. Wants the tax mapping in a place their own team can amend without raising a ticket.

AR / Billing Team Lead

Runs the day-to-day invoicing cycle inside Odoo and lives on the invoice list view. Needs the transmission state visible and filterable next to the payment state, a clear reason on the record when something is rejected, and a correction path that keeps the credit note linked to the original so nothing has to be reconciled by hand later.

ERP Manager / Odoo Administrator

Responsible for the upgrade path and for everything already customised on the invoice form. Needs a module that extends rather than replaces, declares its dependencies honestly in `__manifest__.py`, keeps credentials behind proper access rules, and arrives with source code and a repository so the next upgrade is not a rebuild from scratch.

Group Finance Controller, multi-entity organisation

Has a Belgian entity inside a wider group on one Odoo database. Needs per-company access-point configuration and participant identifiers so the Belgian entity transmits under its own identity, without imposing Belgian-specific rules on sister companies in other jurisdictions.

How Belgium Peppol E-Invoicing Compares

CriterionECOSIRECustom BuildCompetitorOdoo Native
Belgian mandate fitScoped to your Belgian entity's actual tax records, partner data and access point before a line is writtenFit depends entirely on how well your developer knows both Peppol BIS and Belgian VAT rulesGeneric Peppol or EU e-invoicing coverage; Belgian specifics often left as configuration you must work outProduces UBL through the EDI framework, but Belgian identifiers, mappings and process are yours to close
Tax and VAT code mappingEditable mapping records from your own `account.tax` to VAT category and exemption codes, changeable by your accountantUsually hard-coded to the taxes that existed on build dayFixed mapping table; new tax situations require a vendor releaseRelies on standard tax configuration; exemption reason coverage is limited
Rejection and correction handlingFailed rule stored readably on the invoice, user notified in chatter, correction linked to the original document referenceFrequently descoped as an edge case and discovered in the first month of productionStatus flag on the record; the reason often has to be read in the provider portalTransmission errors surface as technical log entries with no finance-facing workflow
Archiving and audit trailImmutable payload and acknowledgement attachments plus an append-only audit log built for retentionWhatever was specified; audit retention is commonly an afterthoughtAttachments retained, though evidence of the acknowledgement may live only at the providerStandard attachments and chatter; no dedicated compliance archive
Version and edition supportBuilt and tested for your exact series — 17.0, 18.0 or 19.0 — and for Community or Enterprise as you run itSingle-version build; each upgrade is a fresh projectOnly the versions the vendor chose to publish; your series may lagFollows Odoo's own release cycle, with capability differing between Community and Enterprise
Code ownershipFull source plus the git repository handed over — no obfuscation, no licence key gateYou own it, at the cost of building and specifying it yourselfLicensed per database and often version-locked to the vendor's roadmapOpen source core, but the compliance gap remains yours to fill
Getting it liveStaging install, UAT on your real historical invoices, scheduled go-live with a rollback plan and a support windowDepends on your internal capacity and testing disciplineInstall and configure yourself; support is typically ticket-basedConfiguration exercise for your team with no delivery assistance
External system integrationTransmission and status models exposed over XML-RPC/JSON-RPC under the same access rules as the UIPossible, but the API surface has to be designed deliberatelyOften internal models only, with no documented external contractCore accounting models are accessible; transmission state is not modelled to integrate against

Frequently Asked Questions about Belgium Peppol E-Invoicing

How long does delivery take, and what does the process look like?

This is build-to-order: nothing is downloaded from an app store. It starts with a scoping call of roughly 30 minutes where we review your chart of accounts, tax records, customer master data and access-point arrangement, and agree in writing what is in scope. From confirmed scope, typical delivery is one working week. That covers development against your Odoo version, installation on staging, a UAT pass against your real historical invoices, and a scheduled go-live with a rollback plan.

What happens after go-live — how are support and Odoo updates handled?

A post-go-live support window is included, covering defect fixes and configuration adjustments while your first real invoicing cycles run; its length is set during scoping and written into the scope. Because you receive the source code and the git repository, your own team can maintain it afterwards. Where the Peppol specification or Belgian rules change, or you upgrade to a newer Odoo series, we scope that as a separate maintenance or migration engagement rather than pretending it is free — we would rather be honest about that up front.

Do we still need a Peppol access point?

Yes. Peppol is a four-corner network: you send to your access point, which delivers to your customer's. This module is corner one — it makes Odoo produce a valid BIS 3.0 document and drive the exchange, with credentials and endpoint held in secure configuration. If you already have an access-point provider we integrate with theirs; if not, we discuss options during scoping. We do not resell access-point services as part of this module.

Does this work on Odoo Community, or do we need Enterprise?

We build for whichever you run. Odoo Enterprise ships its own accounting and e-invoicing plumbing that the module can sit alongside rather than duplicate; on Community, more of the document generation and exchange layer lives inside our module. That difference is one of the first things the scoping call establishes, because it changes the design and therefore the estimate. The `__manifest__.py` dependency list is written honestly for the edition and series you actually use — 17.0, 18.0 or 19.0.

What happens when an invoice is rejected by the network?

The rejection is not silent. The invoice record is flagged with its transmission state, the specific BIS validation rule that failed is stored in readable form on the record, and the responsible user is notified through the standard Odoo chatter. From there the correction workflow either re-sends the amended document or issues a credit note that carries the original document reference, so the receiving party can match the correction automatically instead of by email.

Will this break our existing invoice customisations?

Views are extended through inheritance, never replaced, and the accounting logic hooks into `account.move` rather than overriding core methods wholesale. Existing form customisations, custom fields and reports generally survive the install. That said, we verify it rather than assume it: your existing customisations are reviewed during scoping and the module is installed on a staging copy of your database first, so any interaction is found in UAT and not in production.

Can we drive the transmission from outside Odoo?

Yes. The transmission and status models are exposed through the standard XML-RPC/JSON-RPC API with the same access rules as the UI, so a treasury system, customer portal or middleware layer can post an invoice, trigger a send, or read transmission status without a private back door or a direct database connection.

Request a quote

Belgium Peppol E-Invoicing

Send structured B2B invoices over the Peppol network for Belgium directly from Odoo, with tax mapping driven by your own master data and a full rejection-and-correction workflow. ECOSIRE builds, installs and supports it for your exact Odoo version after a scoping call.

  • Peppol BIS Billing 3.0 outbound document generation from `account.move`, produced at posting from the same data that renders the PDF so the human and machine documents can never diverge
  • Certified access-point integration with queued, retry-aware transmission driven by `ir.cron` or an automated action, so a slow or unavailable endpoint never blocks the invoicing user
  • Transmission state machine stored on an inherited `account.move` (draft / queued / sent / acknowledged / rejected) with the access-point message id and timestamps as stored, searchable, filterable fields
  • `res.partner` extension for Peppol participant identification, typically scheme `0208` for Belgian enterprise numbers, with directory lookup so unreachable customers are caught before posting

Request a Quotation

Tell us about your Belgium Peppol E-Invoicing requirements and we'll send pricing, licensing options and a tailored proposal — usually within one business day.

No payment now. This sends a quote request to our team — we'll follow up by email with pricing and next steps.