Mauritius MRA e-Invoicing
Fiscalise customer invoices with the MRA EBS in real time, capture the IRN and QR, print them on the invoice.
Why this module
Mauritius MRA e-Invoicing
A live MRA connector, not a stub
The module posts to the real MRA token and transmission endpoints, runs the full RSA and AES-256 crypto from the MRA technical guide, and parses the actual response. The IRN and QR come back from the MRA, not from a placeholder.
Posting is never blocked
Fiscalisation runs on posting inside a savepoint. If the MRA is unreachable the invoice posts cleanly and is marked Not Yet Fiscalised. There is no blind automatic retry, so a timed-out invoice that may already be fiscalised is never duplicated.
An immutable record of every call
Each transmission writes an append-only log row with the request id, status, IRN, error codes, HTTP status and duration. Rows cannot be edited or deleted, so the log stays a trustworthy trail for an MRA query or an internal review.
Day in the life
From posting to a fiscalised invoice
An operator posts a customer invoice. The module reserves the next per-EBS counter under a row lock, builds the MRA invoice JSON, reuses or refreshes the cached 24-hour token, signs the payload if signing is enabled, encrypts it under the session data key, and transmits it. The MRA returns a SUCCESS with an IRN and a QR image, which are written to the invoice; the EBS hash chain pointer advances to this document. The printed invoice shows the 2cm QR in the correct position. Had the MRA timed out, the invoice would still have posted, marked Not Yet Fiscalised, ready for a one-click retry, with the timeout captured in the log.
Edge cases
The cases most modules quietly ignore.
In the shipped code today, each one a place where a cheaper module silently does the wrong thing.
The invoice counter, issue datetime and previous-note hash are set once and reused on every retry, so resubmitting the same invoice never shifts its position in the chain or consumes a second counter value.
On a transmission timeout the client refuses to auto-resend and raises, because the invoice may already be fiscalised at the MRA; the document is left Not Yet Fiscalised for a human decision. The optional retry cron only re-sends connectivity failures, never MRA rejections, and stops at the configured attempt cap.
The per-EBS invoice counter is reserved with a SELECT FOR UPDATE row lock, so two simultaneous postings cannot collide on the same counter value. The counter is consumed only after the payload validates.
If digital signing is enabled and the private key fails to load or sign, the invoice is marked Rejected and not transmitted, so a wrongly unsigned invoice never reaches the MRA.
A fiscalised invoice cannot be reset to draft; the module directs you to issue a credit note instead, preserving the fiscalised record and its IRN.
Each fiscalised document advances a company-wide SHA-256 chain pointer concatenating datetime, total paid, BRN and document number, matching the MRA worked example; the first document sends a zero anchor.
A 200 response carrying per-invoice errors does not raise; the module records the MRA error code and description, marks the invoice Rejected, and logs the full response preview for diagnosis.
The transmission log stores only the cleartext invoice business data; the bearer token and the AES data key never appear in it. Credentials live in the database solely as AES-256-GCM ciphertext keyed outside the database.
What is inside
Built to do the job, end to end.
- Real-time fiscalisation on posting. Customer invoices and credit notes are built into the MRA invoice payload and transmitted when posted. Auto-fiscalise is on by default and can be switched to manual, where each invoice carries a Fiscalise button. Posting always succeeds regardless of MRA reachability.
- Guide-exact transport and crypto. RSA PKCS1 v1.5 wraps the authentication payload with the MRA public key; AES-256 under the MRA-mandated mode unwraps the data key and encrypts each invoice; SHA256withRSA invoice signing is available as an option. A fresh AES key is generated per session and the data key is recovered exactly per the guide.
- IRN and QR capture. On success the Invoice Registration Number and the base64 PNG QR code returned by the MRA are stored on the invoice. The QR is held inline so Odoo never resizes it, and printed at 2cm on the invoice PDF; the IRN is kept for reference but not printed, per the MRA template.
- Twenty-four-hour token session cache. The MRA bearer token and data key are cached per company with a safe early-refresh window measured from acquisition, so back-to-back invoices reuse one authenticated session instead of re-authenticating each time.
- Append-only transmission log. Every authentication and transmission attempt is recorded with request id, status, IRN, error code and description, HTTP status, duration and a response preview. Only an internal note field is editable; rows cannot be updated or deleted.
- Encrypted credential vault. The MRA portal password and the optional EBS private key are stored only as AES-256-GCM ciphertext, with the master key read from an environment variable or a file outside the database. Per-company record rules isolate credentials, sessions and logs.
- Tax code and buyer mapping. Each tax maps to an MRA item tax code from TC01 to TC06, with an auto-map helper that sets the 15% standard rate to TC01 and a 0% rate to TC02; the remaining codes are set deliberately by the operator. Buyer TAN, BRN, NIC and buyer type sit on the partner, with sensible fallbacks to the standard VAT and registry fields.
Honest about the edges
What this does not do, so nothing surprises you.
- Requires your own MRA EBS registration and credentials: the EBS MRA ID, username, password, area code, seller TAN, and the MRA public key certificate. The module does not create or replace your MRA enrolment.
- This is the transmission layer between Odoo and the MRA, not a substitute for the MRA e-Invoicing portal. Account setup, certificate issuance and EBS activation happen at the MRA.
- The credential vault master key must be configured on the server, through the EH_MU_EINV_MASTER_KEY environment variable or a key file, before fiscalisation can run.
- Scope is customer invoices and credit notes in the accounting app. It does not ship a POS receipt connector, although the previous-note hash chain is modelled at company level to share one chain with POS documents.
- The output is the MRA EBS JSON payload. It does not generate Factur-X, UBL 2.1 or CII documents; those formats are not part of the MRA scheme.
- Tax codes beyond the 15% and 0% auto-map cases, namely exempt, non-fiscal, exempt-body and out-of-scope supplies, must be mapped by the operator, since the rate alone does not distinguish them.
- Requires the Python cryptography and requests libraries and depends on the standard Accounting app, the shared EDI core, and the Mauritius accounting localisation.
Mauritius e-invoicing Odoo, MRA EBS connector, MRA e-invoicing Odoo 19, Invoice Registration Number IRN, Mauritius fiscalisation, real-time invoice clearance Mauritius, MRA QR code invoice, Mauritius Revenue Authority e-invoice, electronic billing system Mauritius, Odoo 19 Community Mauritius localisation, VAT TAN BRN Mauritius invoicing, previous note hash chain, AES-256 RSA invoice encryption, credit note fiscalisation Mauritius
Languages
Available in 19 languages
The interface ships translated out of the box. Switch language in Odoo and the fields, menus, and messages follow.
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Discuss (mail)
• Invoicing (account) |
| Community Apps Dependencies | Show |
| Lines of code | 2124 |
| Technical Name |
eh_l10n_mu_einvoicing |
| License | OPL-1 |
| Website | https://www.erpheritage.com.au/ |
Odoo Proprietary License v1.0 This software and associated files (the "Software") may only be used (executed, modified, executed after modifications) if you have purchased a valid license from the authors, typically via Odoo Apps, or if you have received a written agreement from the authors of the Software (see the COPYRIGHT file). You may develop Odoo modules that use the Software as a library (typically by depending on it, importing it and using its resources), but without copying any source code or material from the Software. You may distribute those modules under the license of your choice, provided that this license is compatible with the terms of the Odoo Proprietary License (For example: LGPL, MIT, or proprietary licenses similar to this one). It is forbidden to publish, distribute, sublicense, or sell copies of the Software or modified copies of the Software. The above copyright notice and this permission notice must be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Please log in to comment on this module