What is ZATCA e-invoicing integration, and does your business need it?
ZATCA e-invoicing integration is the technical link between the software that creates your tax invoices and ZATCA's FATOORA platform, so each invoice is either cleared or reported electronically. ZATCA calls this Phase 2, the Integration phase, and according to its e-invoicing introduction it became enforceable from 1 January 2023, rolled out in waves of taxpayer groups.
You need a ZATCA e-invoicing integration project when your invoices come from something you or a developer built: a custom online checkout, a bespoke ERP, a job-costing tool, a subscription billing script or a branch POS with its own backend. Popular accounting packages and store platforms usually ship their own Phase 2 support, so the first check is whether the tool you already use does the work for you.
Resident VAT-registered taxpayers are in scope; ZATCA's own summary excludes non-resident taxpayers. If you are unsure whether your entity is covered or which wave it belongs to, that is a question for your tax adviser and for your FATOORA portal notifications, not for a developer.
- Invoices generated by your own code or a heavily customised system: integration work is needed
- Invoices from a mainstream accounting tool with Phase 2 support: configuration, not development
- Invoices from a store platform: check its built-in e-invoicing before paying for anything
- Invoices typed into spreadsheets or Word: move to a compliant solution; do not integrate the spreadsheet
Phase 1 vs Phase 2: what changed for your invoicing software?
Phase 1 was about generating and storing invoices electronically; Phase 2 is about connecting to ZATCA and producing invoices in a stricter structured format. ZATCA enforced Phase 1, the Generation phase, from 4 December 2021. From that date a handwritten or free-form document stopped being acceptable, and invoices needed a QR code with five basic fields for simplified invoices.
Phase 2 raises the bar for the software itself. The invoice becomes an XML document that follows ZATCA's XML Implementation Standard, which is built on UBL 2.1. Each invoicing unit is onboarded and receives a cryptographic stamp identifier (CSID). Every document carries a hash of the previous one, a digital signature and an extended QR code. And every invoice travels to FATOORA through an API, either before it reaches the buyer (clearance) or shortly after the sale (reporting).
In practice a Phase 1 system that stored PDFs with a QR code is not close to Phase 2 compliance. The data model often lacks fields ZATCA now validates, such as the buyer's structured national address or the reason for a zero-rated line. That is why a ZATCA e-invoicing integration starts with a data audit rather than with code.
How do you know when your business must complete Phase 2 integration?
ZATCA tells you. Its roll-out page states that taxpayers are notified of their Phase 2 wave at least six months in advance, and the integration requirement applies from the date set for your group. Watch the notifications linked to your VAT registration and the FATOORA portal rather than relying on blog posts that guess at thresholds.
Six months sounds generous, but it goes quickly once you count the steps: choosing between a ready-made solution and a direct build, cleaning invoice data, development, sandbox testing, onboarding every live device and training the finance team. For a custom system we suggest starting the gap report as soon as the notice arrives, so that development finishes with at least a month of sandbox and simulation testing left before the deadline.
If your notice has already arrived and the deadline is close, say so in your first message. The honest answer might be that a ready-made solution is the faster route for this deadline, with a direct ZATCA e-invoicing integration built afterwards once the pressure is off. We would rather tell you that than promise a timeline the project cannot meet.
Clearance vs reporting: how B2B and B2C invoices flow to ZATCA
Standard tax invoices (B2B) follow the clearance model, and simplified tax invoices (B2C) follow the reporting model. ZATCA's detailed guideline puts it plainly: a standard document is valid only once it has been cleared, so the seller must submit it for clearance before giving it to the buyer. FATOORA validates it, applies ZATCA's cryptographic stamp and returns an updated QR code.
Simplified documents work differently. You issue them to the customer at the point of sale, then submit them through the Reporting API within 24 hours of the transaction. FATOORA validates them and confirms, but does not stamp them, because your own device already signed them with its production CSID.
This split shapes your architecture. Clearance is synchronous: your system waits for ZATCA's answer before the invoice can be emailed, so a slow or failed call blocks a sales process. Reporting is asynchronous: a queue can batch and retry, which suits a busy checkout or a POS that briefly loses its connection.
Credit and debit notes
They follow the same model as the invoice they relate to: standard notes are cleared, simplified notes are reported, and each references the original document.
Self-billing
Where a ZATCA-approved self-billing agreement exists, the buyer submits the standard document for clearance instead of the seller. Your system needs a flag and a different submission path for these.
What is a CSID, and how does onboarding work for ZATCA integration?
A CSID (cryptographic stamp identifier) is the certificate that identifies one invoicing unit to ZATCA and lets it sign documents. Every E-invoice Generation Solution unit, which ZATCA shortens to EGS, gets its own. A single web server can be one unit; a chain with twelve POS terminals may have twelve.
Onboarding follows the steps in ZATCA's detailed technical guideline. A user with access to the FATOORA portal generates one-time passwords, up to 100 at a time, each valid for one hour. The unit creates a key pair, sends a certificate signing request with the OTP and receives a compliance CSID. It then passes a set of compliance checks by submitting sample documents, and only after that requests its production CSID, which is what live invoices are signed with.
CSIDs expire and need renewal through the same OTP routine before the expiry date. ZATCA's guideline also notes that production CSIDs are revoked automatically if the VAT registration is deregistered or suspended, for example on joining a VAT group, in which case the group re-onboards its units. Your ZATCA e-invoicing integration should therefore store each CSID's expiry and status and alert someone weeks in advance, not on the morning invoices start failing.
- Portal side (you): generate OTPs in FATOORA and pass them securely to the unit
- Unit side (the code): key pair, CSR with the right organisation fields, compliance CSID
- Compliance checks: sample standard and simplified documents that must pass
- Production CSID: stored in a key vault, never in the application database
Inside a Phase 2 invoice: UBL 2.1 XML, the hash chain and the signature
A Phase 2 invoice is a UBL 2.1 XML document with ZATCA-specific extensions, and FATOORA only accepts documents in XML, not PDF. ZATCA's XML Implementation Standard says tag names must follow the UBL 2.1 sequence and all mandatory UBL elements must be present, which is where hand-rolled string templates tend to break.
Beyond ordinary invoice data, three technical pieces matter. Each document has a UUID and an invoice counter value. Each carries the previous document hash (PDH): the SHA-256 hash of the last document the same unit generated, so all of a unit's standard and simplified documents form one chain. And each is signed with ECDSA using the unit's private key, with the signature, certificate details and signing time placed in the UBL extensions.
The chain rule has a sharp edge. ZATCA records the hash of rejected submissions too, so the next document must still point at the rejected one. A system that deletes a failed invoice and regenerates it with the same number breaks the chain for everything after it. In a ZATCA e-invoicing integration we treat the generated XML as immutable: fixes go into a new document or a credit note, never into an edited copy.
The Phase 2 QR code: which fields it carries and where it goes
The QR code is a base64 string of TLV-encoded fields (tag, length, value) that a phone can read to check the invoice. ZATCA's guideline lists the tags: seller's name, seller VAT number, invoice date and time, invoice total with VAT and VAT total (tags 1 to 5, required since Phase 1), then the XML hash, the ECDSA signature, the public key and, for simplified invoices, ZATCA's signature of the stamp's public key (tags 6 to 9, added in Phase 2).
For simplified invoices your unit builds the full QR itself and prints it on the receipt or PDF straight away. For standard invoices FATOORA adds or updates the QR during clearance, so the PDF you send the buyer should be rendered from the cleared response, not from your original draft.
Common faults we check for: lengths counted in characters instead of UTF-8 bytes (which breaks as soon as the seller's name is Arabic), timestamps in the wrong format, totals rounded differently from the XML, and a QR printed too small to scan on thermal receipts. Each is simple to fix and easy to miss without a decoder in the test suite.
Build a direct ZATCA e-invoicing integration or connect a ready-made solution?
Build direct when invoices are core to a system you own and will keep; connect through a ready-made solution when you want someone else to own the cryptography and the spec updates. Both are legitimate, and ZATCA publishes a Solution Providers directory on its e-invoicing site for businesses that prefer the second route.
A direct build puts every part in your hands: onboarding, XML, signing, API calls and storage. It suits a company with an in-house or long-term development partner, many document types, or invoices generated inside a workflow that a third-party tool cannot see. The cost is the build plus a commitment to keep up with ZATCA's published changes.
A connector is thinner. Your system sends clean invoice data to the provider's API; the provider signs, submits and returns the result, which you store and print. You pay the provider's fees for as long as you use it, and your data model still has to be good enough, so the clean-up work does not disappear.
Choose a direct ZATCA e-invoicing integration when
You issue several document types from your own code, you want the keys in your own cloud account, or per-invoice fees would add up at your volume.
Choose a connector when
The deadline is close, volumes are modest, or nobody will maintain the integration code after launch.
Choose a platform's built-in support when
Your invoices already come from a store or accounting tool that handles Phase 2 itself. Then the work is configuration and testing, not development.
ZATCA e-invoicing integration for online stores and custom checkouts
Online stores mostly issue simplified invoices, so the integration is a reporting flow triggered when an order is paid or completed. The store generates the XML, signs it, adds the QR to the customer's emailed receipt and queues the document for the Reporting API, with retries well inside the 24-hour window.
Which part needs development depends on the platform. Hosted Saudi store platforms and many international ones provide e-invoicing features or apps, and our Shopify developer page for Saudi stores covers that route. Custom checkouts and self-hosted stores built on WooCommerce or similar frameworks are where a direct build or connector usually earns its keep.
Watch the edge cases rather than the happy path. Partial refunds must produce simplified credit notes that reference the original invoice. Cash-on-delivery orders raise the question of when the sale is complete. B2B customers who give a VAT number at checkout may need a standard invoice and clearance instead of reporting. A good gap report lists each of these and agrees with your accountant how the store should treat it before any code is written.
Connecting an in-house ERP or billing system to FATOORA
For an ERP, the usual design is a separate e-invoicing service that the ERP calls when a document is approved, rather than cryptographic code threaded through the old modules. The service owns the keys, the counters and the hash chain, talks to FATOORA and writes the result back: status, cleared XML, QR string and any warnings.
Decide early how many invoicing units you have. One central service that issues all invoices can be a single unit. Branches that issue documents independently, or offline POS devices, each need their own unit, their own CSID and their own chain, which affects how you number invoices and how finance reconciles them.
Clearance adds a blocking call to your approval flow. If your ERP emails the invoice the moment someone clicks approve, that step must now wait for FATOORA's answer and handle a rejection gracefully, showing the error to the person who can fix the data. We usually add an “awaiting clearance” state and a small screen where finance can see and correct rejected documents without calling a developer.
- One e-invoicing service, called by the ERP, holding keys and counters
- A clear map of invoicing units: central server, branches, POS devices
- An “awaiting clearance” status before any standard invoice is sent
- Cleared XML and ZATCA's response stored with the invoice for archiving
What happens when ZATCA rejects an invoice or the API is down?
FATOORA returns one of three outcomes: valid, accepted with warnings, or invalid. ZATCA's guideline explains that warnings mean the document is accepted but not fully compliant, while an invalid document has at least one fatal error and is rejected with the error messages attached. Your system must record all three and route warnings and errors to a person.
Rejections of standard invoices are urgent, because the buyer cannot receive the invoice until it clears. Rejections of simplified invoices are urgent in a different way: the customer already has the receipt, so the fix must still be reported within the timeframe. In both cases the correction is a new document in the chain, not an edit to the rejected one.
Outages need a written plan. A reporting queue that retries with back-off copes with short interruptions. For clearance, agree with your finance team what the sales process does if the API is unreachable, and check ZATCA's current guidance on disabled clearance, which its guideline says can route standard documents through the Reporting API instead. We build the queue, the alerts and a daily summary of anything older than a few hours.
How to test a ZATCA e-invoicing integration before going live
Test in two layers: offline validation with ZATCA's SDK, then online submissions in the Integration Sandbox. ZATCA describes the Compliance and Enablement Toolbox as a downloadable tool that validates XML invoices, credit and debit notes and QR codes against its published rules, usable locally or through a command-line interface. The sandbox is a test FATOORA backend where a unit can go through onboarding and submit test documents for clearance and reporting.
We wire the SDK into the automated test suite, so every change to the invoice builder is checked against ZATCA's rules before it reaches the sandbox. The test set covers each document type you issue, zero-rated and exempt lines, discounts at line and document level, foreign-currency invoices if you have them, very long Arabic names, and credit notes against both invoice types.
Then comes a rehearsal on production-like data: a copy of last month's real invoices replayed through the new service, with totals compared against your accounting records. Differences of a halala usually point to a rounding rule, and it is far better to find them in rehearsal than in the first live week.
Keys, certificates and access: keeping the integration secure
The private key of each invoicing unit is the most sensitive part of a ZATCA e-invoicing integration, because anyone holding it can sign documents in your name. It belongs in a managed key vault or secrets store in your cloud account, readable only by the e-invoicing service, and never in source code, a shared drive or a chat message.
ZATCA's guideline uses ECDSA on the secp256k1 curve for the unit's key pair. We generate keys inside your environment, so they never pass through our laptops, and we log every signing operation with the document UUID, timestamp and outcome. Admin access to the service uses two-factor login and named accounts, so you can remove any person, including us, on the day they no longer need it.
OTPs deserve the same care. They are short-lived, but whoever generates them in the FATOORA portal controls which units join your account. Keep that permission with a small number of finance or IT staff, and have them enter or pass the OTPs themselves during onboarding sessions rather than sending batches of them to a supplier.
How much does ZATCA e-invoicing integration cost, and what drives the price?
With us, a direct integration for a custom system starts from US$900, and a thin connector to a solution you have already chosen sits at the lower end of that range. Quotes from other providers vary widely, and the gap usually comes from scope, not from hourly rates.
The biggest cost drivers are document variety, device count and data quality. A single web store issuing only simplified invoices is a modest job. An ERP that issues standard invoices, credit notes, debit notes and self-billed documents across several branches, each with its own unit, is several times larger. Data quality is the hidden one: if buyer addresses are free text and VAT categories are missing, the clean-up can take as long as the integration itself.
Running costs matter too. A direct build has hosting and maintenance costs but no per-invoice fee; a ready-made solution usually charges per invoice, per branch or per month. Compare three years of each, not just the first invoice. Your itemised quote from us lists document types, units, screens and tests separately, so you can see exactly what each part costs.
Working with an India-based team on ZATCA integration from Saudi Arabia
India is 2.5 hours ahead of the Kingdom, so a Saudi working day from 8 am to 5 pm sits inside our day, and the Sunday–Thursday week overlaps with ours on four days. Calls happen on Google Meet or Teams in English, and quick questions go through WhatsApp every day of the week.
The money side is simple. Quotes and invoices are in US dollars, the riyal being pegged to the dollar, and you pay by Wise, bank wire or PayPal against the milestones in the written quote. Invoices are issued from India; how your business treats a payment to a non-resident service provider for VAT or withholding tax is a question for your accountant, and we will supply whatever invoice details they need.
Ownership is set up on day one. The repository sits in your organisation's account, the cloud account and key vault are yours, and the FATOORA portal stays with your staff. We work as invited users you can remove.
Days 1–5
Kick-off call, access to a sample of invoices and your current schema, and a walkthrough of how documents are created and sent today.
Days 6–10
Gap report against ZATCA's data dictionary, a list of units to onboard, the agreed architecture and a fixed milestone plan for your approval.
Worked example: a hypothetical Dammam spare-parts wholesaler
Say a spare-parts wholesaler in Dammam, invented for this example, sells to garages on account through its own order system and to walk-in customers through two branch counters. Its notification has arrived, and its current system prints invoices with a Phase 1 QR code.
The gap report finds three document types (standard invoices to garages, simplified invoices at the counters, credit notes for returns), three invoicing units (the central order system and one per counter), and buyer addresses stored as a single text line. Fixing addresses becomes the first task, with a form that asks garages for their structured national address the next time they order.
The build adds an e-invoicing service in the wholesaler's cloud account. Garage invoices wait in “awaiting clearance” for a few seconds before they are emailed; counter receipts print instantly with the full QR and are reported through a queue. Returns generate credit notes linked to the original invoice. After SDK validation and sandbox runs, each unit is onboarded with OTPs generated by the finance manager, and last month's invoices are replayed to confirm totals match. That is a representative shape, not a promise about any real business's timeline.
ZATCA e-invoicing integration checklist and red flags
Run through this list before go-live, and treat the red flags below as reasons to ask harder questions of any developer, including us.
- Wave notification date recorded, with a sandbox deadline one month before it
- Every document type listed, with its model: clearance or reporting
- Every invoicing unit named, with who generates its OTP
- Seller and buyer data mapped to ZATCA's data dictionary, gaps fixed
- SDK validation running in automated tests
- Sandbox onboarding and submissions passed for each document type
- Private keys in a vault; CSID expiry dates monitored
- Retry queue, alerts and a daily summary of unsubmitted documents
- Cleared XML and responses archived with each invoice
- Finance staff trained to read and fix rejections
Red flags: a quote that never mentions the hash chain or CSID renewal; a plan to store private keys in the database; “we just generate a QR code”; no sandbox testing in the timeline; or anyone who offers tax advice alongside the code. Tax treatment belongs with your accountant, and the integration itself should be tested against ZATCA's tools, not against a promise. If personal data is involved in your invoices, our PDPL website compliance guide covers the data-protection side.