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 $499.00 USD; request a quote for a scoped proposal.
Illustrative previewSend 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.
No DIY setup — a working app, built, installed and supported by ECOSIRE.
Start with a one-time build price. We scope it with you at kickoff.
ECOSIRE builds, configures and installs it on your Odoo.
You go live in about 2–4 weeks, with a post-launch support window.
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 two to four weeks. 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.
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.
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.
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.
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.
| Criterion | ECOSIRE | Custom Build | Competitor | Odoo Native |
|---|---|---|---|---|
| Belgian mandate fit | Scoped to your Belgian entity's actual tax records, partner data and access point before a line is written | Fit depends entirely on how well your developer knows both Peppol BIS and Belgian VAT rules | Generic Peppol or EU e-invoicing coverage; Belgian specifics often left as configuration you must work out | Produces UBL through the EDI framework, but Belgian identifiers, mappings and process are yours to close |
| Tax and VAT code mapping | Editable mapping records from your own `account.tax` to VAT category and exemption codes, changeable by your accountant | Usually hard-coded to the taxes that existed on build day | Fixed mapping table; new tax situations require a vendor release | Relies on standard tax configuration; exemption reason coverage is limited |
| Rejection and correction handling | Failed rule stored readably on the invoice, user notified in chatter, correction linked to the original document reference | Frequently descoped as an edge case and discovered in the first month of production | Status flag on the record; the reason often has to be read in the provider portal | Transmission errors surface as technical log entries with no finance-facing workflow |
| Archiving and audit trail | Immutable payload and acknowledgement attachments plus an append-only audit log built for retention | Whatever was specified; audit retention is commonly an afterthought | Attachments retained, though evidence of the acknowledgement may live only at the provider | Standard attachments and chatter; no dedicated compliance archive |
| Version and edition support | Built and tested for your exact series — 17.0, 18.0 or 19.0 — and for Community or Enterprise as you run it | Single-version build; each upgrade is a fresh project | Only the versions the vendor chose to publish; your series may lag | Follows Odoo's own release cycle, with capability differing between Community and Enterprise |
| Code ownership | Full source plus the git repository handed over — no obfuscation, no licence key gate | You own it, at the cost of building and specifying it yourself | Licensed per database and often version-locked to the vendor's roadmap | Open source core, but the compliance gap remains yours to fill |
| Getting it live | Staging install, UAT on your real historical invoices, scheduled go-live with a rollback plan and a support window | Depends on your internal capacity and testing discipline | Install and configure yourself; support is typically ticket-based | Configuration exercise for your team with no delivery assistance |
| External system integration | Transmission and status models exposed over XML-RPC/JSON-RPC under the same access rules as the UI | Possible, but the API surface has to be designed deliberately | Often internal models only, with no documented external contract | Core accounting models are accessible; transmission state is not modelled to integrate against |
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 two to four weeks. 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.
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.
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.
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.
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.
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.
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.

A build-to-order Odoo localization that loads Algeria's full wilaya and commune hierarchy with bilingual French and Arabic names, wired into partner addresses and reporting. ECOSIRE builds, installs, and supports it after your quotation.



A build-to-order Odoo module that lets you render any accounting report — P&L, Balance Sheet, aged reports, journals, trial balance — in a currency of your choice, with automatic conversion at the rate you define. ECOSIRE scopes, builds, installs and supports it for your Odoo 17/18/19 environment.
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.