Odoo + PINT-AE: a developer's integration guide
Odoo dominates UAE mid-market ERP, which makes PINT-AE integration the most common request we see. Here is the architecture, the patterns, and the traps.
Odoo is the most-installed ERP in the UAE mid-market by a wide margin. That makes PINT-AE integration for Odoo the single most common request our network sees. This guide is the architecture a senior Odoo developer would land on after running through the trade-offs.
The three architectural options
You have three viable ways to make Odoo produce compliant PINT-AE invoices.
Option A: native Odoo localisation. Odoo S.A. ships a UAE localisation module that handles VAT calculation, account chart, and tax reporting. PINT-AE-specific functionality has been added in successive releases — but the maturity varies by Odoo version and the localisation evolves quickly. Best for: businesses already on the latest Odoo Enterprise edition who want everything in one stack.
Option B: community PINT-AE modules. A growing set of UAE-focused Odoo studios maintain community modules for PINT-AE — typically open-source on GitHub, with paid support contracts available. These tend to be more flexible than the official localisation but require more configuration and have variable maintenance quality. Best for: businesses on Odoo Community Edition or older Enterprise versions.
Option C: external middleware. Keep Odoo's invoicing logic untouched. Build a small middleware service that polls Odoo for new invoices via the XML-RPC API, transforms each one into PINT-AE XML, sends it to your ASP, and writes the FTA response back to Odoo as a chatter message and field update. Best for: businesses that have heavy Odoo customisation, mixed ERP environments, or want PINT-AE logic independent of Odoo upgrade cycles.
We end up recommending Option C more often than the others, but for clear reasons. If your Odoo is vanilla and current, Options A or B are simpler. If your Odoo is heavily customised or you cannot tolerate an Odoo upgrade locked behind a PINT-AE module update, Option C decouples the concerns.
The middleware architecture (Option C)
Pattern: a small Python service that lives next to Odoo and talks to both Odoo and your ASP.
Data flow:
- An Odoo user posts an invoice (
account.move.action_post). - An Odoo automated action publishes a message to a queue (Redis or RabbitMQ).
- The middleware consumer picks up the message, fetches the invoice from Odoo via XML-RPC, validates that all PINT-AE required fields are present.
- The middleware generates compliant UBL 2.1 XML using a templating library, validates against the FTA XSD locally before transmission.
- The middleware POSTs the XML to your ASP's API, receives a tracking ID and submission status.
- The middleware writes back to Odoo: an
l10n_ae_pint_statuscustom field, anl10n_ae_pint_tracking_id, and a chatter message with the FTA response. - A second consumer polls or listens for ASP webhooks to update Odoo when the FTA accepts or rejects the invoice.
This pattern is robust because each component does one thing. Odoo continues to be the source of truth for invoice data. The middleware handles transformation and transmission. The ASP handles the network exchange. Errors at any layer are isolated.
The four things that will trip you up
1. TRN format normalisation. Odoo's res.partner.vat field is free text. UAE businesses store TRNs in dozens of inconsistent formats — with spaces, with "VAT-" prefix, with the country code prefix "AE", as a 13-digit shortened version. Your middleware must aggressively normalise. Anything other than exactly fifteen digits starting with "100" is a validation failure. Add a pre-flight check that warns when normalisation has to make a guess.
2. Tax category code mapping. Odoo's tax records are keyed by Odoo's internal tax IDs, not by PINT-AE category codes. You need a mapping table that translates each Odoo tax to its PINT-AE equivalent. This mapping is environment-specific — every Odoo install has slightly different tax IDs depending on when the chart of accounts was set up. Build the mapping table once, store it in your middleware config, validate it against the FTA's published code list as part of CI.
3. Emirate of supply at line level. Odoo does not capture this natively. You need either a custom field on account.move.line, a default derived from the warehouse, or a default derived from the company partner address. For service businesses with a single company location, a global default works. For trading businesses with multiple warehouses, you need to derive from the picking source location.
4. Reversed invoices and credit notes. Odoo's credit note model uses move_type = "out_refund" with a reversed_entry_id linking back to the original. PINT-AE requires the credit note to reference the original invoice's document ID using a specific UBL element (cac:BillingReference / cac:InvoiceDocumentReference). If your middleware does not pick up the reversal link cleanly, the FTA will reject the credit note even though it validates as XML.
Testing strategy
Skip unit-testing the XML generation. UBL is verbose enough that line-by-line assertions become brittle. Instead:
- Maintain a corpus of representative invoices in your test database — at least 20 variations covering different tax categories, line counts, multi-currency, refunds, intracompany, exports.
- For each, generate the PINT-AE XML and validate it against the FTA's published XSD. Test passes if XSD validation passes.
- Run a subset through your ASP's sandbox environment as a separate integration test. Test passes if the ASP accepts and returns a successful submission ID.
- For business logic specifics (TRN format, tax mapping, emirate code), test those in isolation, not in the XML output.
Cost and timeline
A clean Odoo PINT-AE integration on a single Odoo instance, using Option C middleware, typically takes 6 to 10 weeks end-to-end. Discovery and gap audit: 1-2 weeks. Build and ASP integration: 3-5 weeks. Validation and test cycles: 1-2 weeks. Go-live with hyper-care: 1 week.
Build cost (excluding ASP fees and Odoo licensing) for a vanilla Odoo install typically falls between AED 35,000 and 80,000. Multi-company setups, heavy invoicing customisation, or migration of historical invoice data can push this higher.
If you are starting an Odoo PINT-AE project and want to talk to engineers who have shipped this work, the Odoo development page is the place to start.