Saudi Arabia · ZATCA e-invoicing

ZATCA Phase 2 integration for a custom ERP or in-house billing system: what your side has to do

On this page12 sections

In short: if your invoices come out of software your company built or had built, there is no ready-made ZATCA connector to switch on. For Phase 2 (the Integration phase), that software has to produce each invoice as UBL 2.1 XML, chain every invoice to the one before it with a hash, stamp simplified invoices and print a QR code, onboard each invoicing unit with ZATCA to get a cryptographic stamp identifier (CSID), then send standard (B2B) invoices to the Fatoora platform for clearance before the buyer sees them, and report simplified (B2C) invoices within 24 hours. ZATCA's latest announced group, Wave 25, covers taxpayers with revenue subject to VAT above SAR 187,500 in any year from 2022 to 2025, with a deadline of 1 February 2027.

We build that integration for in-house and custom systems. We are not a ZATCA-listed solution provider and claim no ZATCA approval; ZATCA itself says a taxpayer can use any company as long as the solution meets its requirements. We work with clients worldwide; calls and meetings can be arranged to suit you.

Every requirement below comes from ZATCA's own documents, opened on 12 November 2026 and listed under Sources. Where a detail depends on a document version or your own setup, we say so and point you to ZATCA's guidelines.

Who has to integrate, and by when

Phase 1 (the Generation phase) has applied since 4 December 2021: invoices must be generated electronically by a compliant solution. Phase 2 started on 1 January 2023 and is rolled out in waves, each defined by revenue subject to VAT. ZATCA says it tells each wave at least six months before its integration date, by the official email and SMS registered with it.

Wave Who is in it (revenue subject to VAT) Integrate with Fatoora by ZATCA announcement
Wave 24 above SAR 375,000 in 2022, 2023 or 2024 30 June 2026 26 September 2025
Wave 25 above SAR 187,500 in 2022, 2023, 2024 or 2025 1 February 2027 24 July 2026

Three things to read from this:

  • The threshold has halved. Businesses that were too small for Wave 24 are now in Wave 25. If your revenue subject to VAT passed SAR 187,500 in any one of those four years, expect the notification.
  • The notification decides your date, not this table. Your integration date is the one ZATCA sends you. Until then you keep following Phase 1; ZATCA's guideline also mentions a voluntary option to start Phase 2 earlier.
  • No later wave was on ZATCA's news page when we checked on 12 November 2026. If a Wave 26 is announced, we will add it here.

Clearance or reporting: which ZATCA API each invoice uses

ZATCA splits invoices into two kinds, and each goes to a different API. Your system has to know, for every document, which one it is: the invoice type code carries a subtype (0100000 for a standard tax invoice, 0200000 for a simplified one).

Standard tax invoice (mostly B2B and B2G) Simplified tax invoice (mostly B2C)
ZATCA model Clearance, in real time Reporting, near real time
Who stamps it ZATCA adds its cryptographic stamp and QR code Your system stamps it with its own CSID and adds the QR code
When the buyer gets it Only after ZATCA returns the cleared XML At once, printed or electronic
Deadline to send Before you share it with the buyer Within 24 hours of issuing it
Format sent to ZATCA XML (not PDF/A-3) XML (not PDF/A-3)
Format for the buyer XML or PDF/A-3 with the XML embedded Printed copy, or electronic by agreement
Credit and debit notes Follow the invoice: cleared Follow the invoice: reported

ZATCA's guideline also notes a supplier may issue a simplified invoice to a business buyer when the taxable supply is under SAR 1,000. Consumer sales can use simplified invoices at any value.

Why a custom ERP is a different job from a packaged one

A packaged ERP or POS vendor ships ZATCA support as a feature, and you configure it. An in-house system has no such switch: the rules have to be built into code that was written for other purposes. ZATCA's guideline lists functions an e-invoicing solution must not have from the Integration phase. In custom systems these are where most of the work hides:

  • No editing or deleting issued invoices. To cancel, you issue a credit note and a new invoice. Many in-house systems allow "edit invoice" for admins.
  • No counter reset and one sequence per unit. Each invoicing unit keeps one chain, linked by the previous invoice hash. Systems that number invoices per branch, per year or per user need a separate counter per unit.
  • No changing the clock. Invoices must not carry timestamps changed by the user or by software time changes.
  • Logs that cannot be changed. Every user action in the invoicing process is logged, and the logs cannot be edited or deleted.
  • No anonymous access and no default passwords. Every user logs in with their own credentials.
  • No exporting the stamping key. The private key behind each CSID must not be exportable.

ZATCA calls each piece of software or device that issues invoices an E-invoice Generation Solution (EGS) unit. A head-office ERP, a branch server and each smart till can each be a unit with its own CSID. Deciding how your system splits into units is the first design choice, because it sets how many chains, keys and onboarding runs you will have.

An e-invoice outbox screen in the in-house ERP of a fictional company, Ramlah Crest Trading, set to ZATCA's simulation environment. A table lists six documents with their type code and subtype, the invoicing unit and its counter, the start of the previous invoice hash, the API used and the status: tax invoices and a credit note cleared with code 200, simplified till invoices reported, one invoice accepted with a 202 warning, one simplified invoice queued after a 503 and retrying, and one tax invoice rejected with a 400 because its issue date was later than the current date. A side panel shows the rejection detail and three invoicing units: two with production CSIDs and one still passing compliance checks.
An outbox inside the ERP: every document waits for ZATCA's answer, failures retry, rejections go to a person. Illustrative screen for a fictional company, sample data.

ZATCA API integration steps, from sandbox to production

ZATCA's technical guideline describes three stages: make the solution compliant, onboard each unit, then clear and report. In practice, for a custom system, the work runs in this order.

  1. Map your data to ZATCA's fields. The Data Dictionary and the XML Implementation Standard (version 1.2, 19 May 2023) define every field and business rule. Typical gaps in in-house systems: the buyer's VAT number and full address, invoice issue time, VAT category codes and exemption reasons, and the reference from a credit note back to the original invoice.
  2. Generate UBL 2.1 XML. ZATCA validates syntax against UBL 2.1, then content against a customised subset of EN 16931 rules plus Saudi-specific rules (BR-KSA-…). Either your system writes the XML or a separate integration layer builds it from your invoice records.
  3. Build and test in the Developer Portal sandbox. The Developer Portal has the Compliance and Enablement Toolbox (an SDK you can run offline or from the command line, plus a web validator for XML files) and the Integration Sandbox, where you call test versions of the APIs. Nothing here is tied to your VAT registration.
  4. Create a key pair and a certificate signing request (CSR) for each unit. The CSR carries the unit's details and its functionality map: 1000 for standard invoices only, 0100 for simplified only, 1100 for both.
  5. Get an OTP from the Fatoora portal. Someone at your company logs in to Fatoora with the company's ZATCA (ERAD) credentials and requests one-time passwords, one per unit. Each OTP is valid for one hour.
  6. Request the compliance CSID. The unit sends its CSR with the OTP to the compliance API and gets a compliance CSID back.
  7. Pass the compliance checks. The unit submits sample documents of every type in its functionality map to the compliance checks API. For a standard-only unit (1000) that is three requests: a standard tax invoice, a debit note and a credit note.
  8. Request the production CSID. Once the checks pass, the unit asks for its production CSID, which it then uses to sign simplified invoices and to authenticate every clearance and reporting call.
  9. Rehearse in the simulation portal, then go live. The Fatoora simulation portal is a separate environment with its own onboarding, for end-to-end functional testing (ZATCA says it is not for load testing). Production onboarding is repeated on the real Fatoora portal.

CSIDs expire and have to be renewed before their expiry date, and they are revoked automatically if the company is deregistered for VAT or joins a VAT group. Build renewal into the system rather than leaving it to someone's calendar.

The endpoint paths are published in ZATCA's Fatoora portal user manual. Production and simulation differ only in one path segment:

https://gw-fatoora.zatca.gov.sa/e-invoicing/{env}/compliance                     compliance CSID
https://gw-fatoora.zatca.gov.sa/e-invoicing/{env}/compliance/invoices            compliance checks
https://gw-fatoora.zatca.gov.sa/e-invoicing/{env}/production/csids               production CSID (request or renew)
https://gw-fatoora.zatca.gov.sa/e-invoicing/{env}/invoices/clearance/single      clearance: standard documents
https://gw-fatoora.zatca.gov.sa/e-invoicing/{env}/invoices/reporting/single      reporting: simplified documents
{env} = core (production) or simulation

The APIs use OAuth 2 Basic Authentication: the client ID is the certificate issued at onboarding and the secret is issued with it. Request and response details are in the API documentation linked from the Fatoora portal and the Developer Portal; see ZATCA's guidelines for the current version.

The invoice hash chain, the counter and the QR code

Three things link your invoices into a record ZATCA can trust.

The previous invoice hash (PIH). Every invoice carries the hash of the invoice before it from the same unit. Per the XML standard, the hash is built by removing the UBLExtensions block, the QR document reference and the Signature block, canonicalising the XML with C14N11, hashing it with SHA-256 and Base64-encoding the result. The first invoice of a unit uses a fixed value, the Base64 encoding of the SHA-256 hash of the character "0". The field and the value, as the standard gives them:

Where it goes (XML Implementation Standard, field KSA-13):
ubl:Invoice / cac:AdditionalDocumentReference / cac:Attachment / cbc:EmbeddedDocumentBinaryObject

Value for the first invoice of an EGS unit (rule BR-KSA-26):
NWZlY2ViNjZmZmM4NmYzOGQ5NTI3ODZjNmQ2OTZjNzljMmRiYzIzOWRkNGU5MWI0NjcyOWQ3M2EyN2ZiNTdlOQ==

The counter and the UUID. Each invoice has a UUID generated by the solution and stored in the XML, and an invoice counter value (ICV, field KSA-16, digits only) from a counter per unit that cannot be reset. ZATCA's FAQ adds that invoices may be submitted in any order as long as they were generated in sequence; gaps found in its back-end checks are investigated. Your invoice reference numbers can still follow your own format, for example a sequence per branch, as long as each is unique and sequential.

The QR code. It is Base64 text of up to 700 characters, built from Tag-Length-Value fields. Tags 1 to 5 (seller name, VAT number, timestamp, total with VAT, VAT total) have applied since 4 December 2021. Phase 2 adds tag 6 (hash of the XML invoice), 7 (ECDSA signature of that hash), 8 (the public key) and, for simplified invoices and their notes, 9 (the signature of the cryptographic stamp issued by ZATCA's certificate authority). The stamp itself is an enveloped XAdES signature using SHA-256 and ECDSA. For standard invoices ZATCA adds the stamp and QR code during clearance; for simplified invoices your system does it.

Error handling and retries: what ZATCA expects when things fail

ZATCA's guideline lists the API responses and what to do with each. Your integration should act on them without a person watching:

Response Meaning What the system should do
200 Accepted Store the response (and, for clearance, the cleared XML) and release the invoice
202 Accepted with warnings Release it, and send the warnings to a fix list; ZATCA says warnings may become rejections later
303 Clearance switched off Submit through reporting instead, as the response says
400 Rejected Hold the invoice, correct the data and resubmit
401 Unauthorised Check the certificate and secret, then resubmit
413 Payload too large Resend with a smaller payload
429, 500, 503, 504 Not received (too many requests, server error, unavailable, timed out) Resend, with a back-off

For outages, the guideline's failure scenarios give the pattern. If ZATCA's servers do not respond to a clearance call, its example retries for about five minutes, shares the uncleared invoice with the buyer while keeping records, then keeps trying about every 15 minutes (ZATCA marks both timings "to be confirmed") and shares the cleared invoice once clearance succeeds. Uncleared and manual invoices are treated as VAT invoices only until the compliant one is issued, and are not eligible for VAT deduction. For simplified invoices, the system keeps trying to report within the 24 hours; if your own side fails for longer, you notify ZATCA through the form on its website and again when you recover. Keep the API logs: ZATCA says taxpayers should keep evidence of trying to clear.

What that means in code: an outbox table that every invoice passes through, a queue worker with back-off, idempotent resubmission of the same signed XML, a hold state that stops a rejected standard invoice reaching the buyer, an alert when a simplified invoice nears its 24 hours, and an API log nobody can edit.

Arabic on the invoice

The guideline is direct: under Article 53 of the VAT regulations invoices must be in Arabic, and other languages may appear alongside. ZATCA's technical FAQ says every data field visible on the human-readable invoice must be in Arabic, and the invoice can be bilingual. The human-readable copy (the printout or PDF) can use Arabic or Hindi numerals, while amounts inside the XML use the digits 0 to 9. For an in-house system that prints English-only invoices, this means Arabic labels and Arabic names for products and parties, laid out right to left where the template needs it. We build Arabic and English screens and documents with right-to-left layouts.

ZATCA Phase 2 readiness: a tick-list for your system

Tick what your system already does today. Be strict: "we could add it" is not ticked.

What your invoicing system already does for ZATCA Phase 2
Tick what your invoicing system already does today.

Your ticks go into the message for you to read and edit. Nothing is sent until you press send in the form or in WhatsApp.

This runs in your browser. Nothing you tick is sent anywhere unless you choose to send it.

Build or buy: when a ready connector is the better choice

A custom integration is not always the right answer. Be honest about which case you are in.

Your situation Usually better Why
You run a packaged ERP or POS whose vendor ships ZATCA Phase 2 support The vendor's module It is maintained when ZATCA changes its rules, and the vendor carries the testing
You are about to replace the system anyway Move to software with ZATCA support built in Integrating a system you are retiring is money spent twice
You run an in-house or heavily customised system you will keep A custom integration No connector exists, and the rules have to live where invoices are created
Several systems issue invoices (ERP, tills, a web shop) A custom integration layer One outbox, one queue and one log across all units
A middleware or e-invoicing service fits your stack Compare it with a build It can work if it reads your data cleanly; check who owns the keys and the logs

ZATCA publishes a Solution Providers Directory of companies that have passed its qualification process. Its page also says taxpayers may get e-invoicing services from any company, as long as the solution meets the requirements, and that using a provider outside the directory does not make a taxpayer non-compliant. Choosing a listed provider is a reasonable filter; it is not the only route.

What we do on a ZATCA Phase 2 integration

We are a software company founded in 2020 with more than 100 projects delivered. On a ZATCA job we work on your side of the API:

  • Scope. We read how your system issues invoices, list the EGS units, find the data gaps against the Data Dictionary and agree the design: XML inside your system or in a separate layer.
  • Build. UBL 2.1 XML for every document type you issue, the counter, UUID and hash chain, XAdES stamping and the QR code for simplified invoices, the onboarding calls, clearance and reporting, the outbox with retries and an API log, and Arabic on your invoice templates.
  • Test. Every invoice type through ZATCA's SDK and the Developer Portal sandbox, then the compliance checks and an end-to-end rehearsal in the Fatoora simulation portal.
  • Go live. We support your team through production onboarding (your company requests the OTPs with its own Fatoora login; we never hold your credentials) and the first weeks of live invoices, including CSID renewal.

What we don't do: we are not in ZATCA's Solution Providers Directory and hold no ZATCA qualification, approval or certification, we give no tax advice, and the code, keys and accounts stay yours. We have no office in Saudi Arabia; we work with clients worldwide, and calls and meetings can be arranged to suit you. You get a fixed written quote after a scoping call.

Price for your integration

See the price for your integration

Tell us how your system issues invoices today and we send you a price for the ZATCA integration and a fixed written quote after a short scoping call.

  1. Tell us what you need
  2. Short scoping call
  3. Price and fixed written quote
Phone or WhatsApp

We use your details only to reply to this enquiry. See our privacy notice.

Prefer WhatsApp? Send the same request there.

Sources

All opened on 12 November 2026.

This guide explains published requirements so you can plan the work. It is not tax or legal advice, and ZATCA updates its documents: check the current versions on zatca.gov.sa before you build.

FAQ

Questions about ZATCA Phase 2 for in-house systems

Does ZATCA Phase 2 apply to a custom or in-house billing system?

Yes. ZATCA's rules apply to whatever solution issues your tax invoices, including software you built yourself. Once your wave date arrives, that system has to produce invoices in ZATCA's XML format, be onboarded with a cryptographic stamp identifier (CSID) for each unit, and send invoices to the Fatoora platform through ZATCA's APIs. ZATCA's guideline says you can keep the system you used for Phase 1 if you update it to meet the Phase 2 requirements.

What is the difference between clearance and reporting?

Standard tax invoices, usually issued to businesses, and their credit and debit notes go to Fatoora for clearance before you share them: ZATCA validates the XML, adds its cryptographic stamp and QR code and sends the cleared invoice back. Simplified tax invoices, usually issued to consumers, are stamped by your own system with its CSID, carry a QR code, go to the customer at once and must be reported to Fatoora within 24 hours.

When is the Wave 25 deadline for ZATCA Phase 2?

ZATCA's announcement of 24 July 2026 says Wave 25 covers taxpayers whose revenue subject to VAT exceeded SAR 187,500 in 2022, 2023, 2024 or 2025, and that they must integrate with the Fatoora platform by no later than 1 February 2027. ZATCA notifies each targeted taxpayer directly, so check the notification your company received.

Is Coded Idea a ZATCA-approved solution provider?

No. We are not in ZATCA's Solution Providers Directory and hold no ZATCA qualification, approval or certification. ZATCA's directory page says taxpayers may get e-invoicing services from any company, as long as the solution meets the requirements. We build and change your own system: the XML, onboarding, clearance and reporting calls, the retry queue and the tests in ZATCA's sandbox and simulation portal. Your company onboards its units on Fatoora with its own login.

Next step

Book a 20-minute walkthrough

Show us how invoices leave your system today. We tell you what has to change for ZATCA Phase 2, then quote a fixed price for building it.

Contact for price

Get a price for your project

Every project is different, so we quote a fixed price. Tell us what you need and we'll come back to you by email.

Phone or WhatsApp

We use your details only to reply to this enquiry. See our privacy notice.