ZATCA Phase 2 e-invoicing on Odoo 19 Enterprise
Live ZATCA Phase 2 e-invoicing integration for a multi-branch F&B operator, including a custom down-payment invoice numbering scheme and a later read-only compliance audit run directly against production.
- Client
- Multi-branch F&B group, Saudi Arabia
- Sector
- ERP
- Stack
- Odoo 19 Enterprise · Python · XML-RPC · ZATCA API
- Year
- 2025
The problem
A multi-branch food and beverage group in Saudi Arabia needed to move onto ZATCA Phase 2 — the regulator's live e-invoicing integration phase, where invoices must be cleared or reported to the tax authority in near real time. Their existing Odoo setup handled invoicing for day-to-day sales, but the down-payment invoice numbering didn't map to what the regulator expected, which meant every down payment risked failing clearance.
What I built
I implemented a live ZATCA Phase 2 integration on Odoo 19 Enterprise, with an in-UI clearance status indicator so staff could see, per invoice, whether it had cleared with the regulator without leaving the app. Alongside that, I built a custom down-payment invoice numbering scheme that satisfies ZATCA's sequencing rules while staying compatible with the client's existing multi-branch chart of accounts.
Some months after go-live, I returned to run a full compliance audit of the integration. Rather than working from a copy of the database, I wrote read-only XML-RPC scripts and ran them directly against production — pulling invoice state, clearance status, and numbering sequences without ever issuing a write call. That let the audit cover live data with zero risk to the operation it was checking.
Outcome
The integration passed the compliance audit. Clearance status is now visible in-app across branches, and the down-payment numbering issue that would have blocked ZATCA clearance was resolved before it caused a compliance incident.
Why it mattered
Regulated invoicing is unforgiving of half-measures — a numbering scheme that looks right in testing can still fail clearance in production. Running the audit read-only, against live data, meant the client got a real answer about their compliance posture without any risk of the audit itself becoming an incident.
Have a system that needs to work in production?
Tell me what's breaking — or what you're building.