← Blog Guides 8 min read · 7 September 2026

Connecting your own system to ZATCA: what a direct integration really involves

Two engineering paths side by side: a stack of cryptographic and XML components on one side, a single JSON request on the other
The invoice is the easy part. The certificate lifecycle and the chain state are what you will still be maintaining in three years.

Someone has handed you a ticket that reads "make our system ZATCA compliant". It might be an ERP, a point of sale, a hospital information system, a school fee platform, a booking engine, or an in-house app nobody outside the building has ever seen. The ticket is one line. The work is not. This is an honest account of what a direct integration with the Fatoora platform contains, so you can decide whether to build it, host it, or buy it.

It assumes you know that a standard (B2B) invoice must be cleared before the buyer sees it and a simplified (B2C) one reported within 24 hours; if not, start with what Phase 2 requires.

What a direct integration contains

Roughly in the order you will meet it:

  1. Key pair and CSR. An ECDSA key on the secp256k1 curve, and a certificate signing request carrying your VAT number, establishment name, address and a set of ZATCA-specific extension attributes. Get one wrong and the request is rejected without much explanation.
  2. Compliance CSID. The merchant generates a one-time password in the Fatoora portal; you exchange it with the CSR for a compliance certificate. The OTP is single-use and short-lived, so onboarding has to be completable in one sitting.
  3. The compliance documents. If you issue both invoice types that is six: standard and simplified, with a credit and debit note for each. They must be produced correctly by your own code, not by hand, before you may issue anything real.
  4. Production CSID. Issued on passing that whole set. This is the certificate that signs real invoices, and it expires.
  5. UBL 2.1 XML. Not a template you fill in — a fixed schema with business rules on top, where element order is mandatory and tax categories, exemption reasons and note types come from controlled code lists.
  6. XAdES signing. The document is canonicalised, specific elements are excluded from the digest, a signed properties block carries the certificate digest and issuer details, and the result sits in exactly the position the specification requires. Byte-level correctness matters here: a whitespace difference after canonicalisation is a failed signature.
  7. The chain. Every device keeps an invoice counter value (ICV) that only increments and the previous invoice hash (PIH): persistent, per-device, concurrency-sensitive state. Two workers issuing at once without a lock will claim the same position in the chain, and the break is permanent.
  8. Two transmission paths. Clearance is synchronous and blocks the document: no cleared copy, nothing to send the buyer. Reporting happens after the sale, within 24 hours, so the customer already has their invoice — but a rejected simplified invoice still has to be corrected and resubmitted, which makes the response something you must read rather than discard. Different endpoints, different response shapes, different failure semantics, and reporting needs a retry queue that survives a restart.
  9. Validation responses. Rejections and warnings arrive as coded results — our own catalogue runs to 135 — and you have to map them to something users can act on, because "BR-KSA-44" means nothing to a clinic administrator. See the error catalogue, or BR-KSA-09 for a typical example.
  10. Renewal, forever. Certificates expire. Every device needs a fresh OTP and a renewal run, on a schedule someone owns after you have moved on to other work.

None of this is beyond a competent team. A first working integration is measured in weeks; the long tail — code lists, odd rejections, renewal tooling, the branch model — is measured in quarters.

The three realistic routes

 Build it yourselfSelf-host open sourceSend JSON to an API
Certificates and CSRYou write itLibrary handles it, you operate itHandled for you
XML and signingYou write itLibrary handles itHandled for you
ICV / PIH stateYour database, your lockingYour database, your lockingHeld per device by the service
Rejection codesYou map all of themRaw codes, mostly unmappedShown with the official code and a link to its guide
Certificate renewalYou build and staff itYou build and staff itStill needs the merchant's OTP
Invoice data leaves your serversOnly to ZATCAOnly to ZATCAYes, to the service
Best whenCompliance is your product, or policy forbids third partiesYou want to own the component and can maintain itInvoicing is a feature, not your product

When building it yourself is the right call

Genuinely, sometimes it is, and any vendor who tells you otherwise is selling.

  • Data residency or policy. If a government client, a hospital's information security policy or your own contracts forbid invoice data leaving your infrastructure, that decides it. No comparison table beats a policy.
  • Compliance is the product. If you are building an e-invoicing product, the cryptography is not overhead — it is the thing you are selling.
  • You have the team and want the component. Some organisations would rather own every dependency in the signing path and have the staff to maintain it for years. That is a legitimate choice, not a mistake.

Open-source implementations are a reasonable middle path: you still operate the state, the renewals and the error mapping, but you do not write the XAdES layer from scratch.

The alternative: post JSON, receive a signed invoice

The other route is to keep your system as the source of truth and treat compliance as a call. You post the invoice as JSON — seller, buyer, lines, totals, document type — and you get back the UBL 2.1 XML with its stamp and QR code — for a standard invoice, the cleared document as ZATCA returned it — plus a cleared or reported status, with the counter and hash chain maintained per device. Rejections come back with their official ZATCA code and a link to its guide. That is what our API reference documents.

If you are a software company with many merchants rather than one business, the shape is different and matters more. One partner key, a merchant onboarding link that lets each merchant enter their own Fatoora OTP without your support desk touching it, and branches and devices per merchant underneath. The Partner API reference and the partner guide cover that model. If your customers run stores, there are ready plugins for WooCommerce and Shopify, and an n8n node.

What we are is a compliance layer: signing, clearance and reporting, quotations, receipt vouchers, reports, and six years of downloadable signed XML so a merchant can leave with their archive. What we are not is an accounting system — no general ledger, no journal entries, no inventory, no payroll. If the ticket says "we need accounting", this is not that.

It is free during the launch period — an account starts with 50 invoices and expands when needed — which is enough to run a real integration test against your own data before anyone signs anything: create an account, or talk to us if you are evaluating for a portfolio of clients. More technical write-ups appear on the English blog.

Frequently asked questions

Do we have to build a direct ZATCA integration to be compliant? +
No. The regulation requires that invoices are issued as UBL 2.1 XML, cryptographically stamped and QR-coded as the specification requires for each invoice type, and cleared or reported by a solution onboarded to the Fatoora platform. It does not require that your team writes the cryptography. You can build it, self-host an open-source implementation, or send invoice data to a service that does the signing and transmission for you. The obligation stays with the business issuing the invoice either way.
What are the six compliance invoices? +
After you exchange the OTP and your CSR for a compliance certificate, your solution must issue a set of documents that the Authority validates one at a time. If it issues both invoice types, that is six: a standard invoice with its credit note and debit note, and a simplified invoice with its credit note and debit note. A solution registered for only one of the two types is checked on that type alone. Passing the set is what releases the production certificate. They must be genuinely produced by your code — signed, chained and formatted exactly as your real invoices will be — because that is the point of the exercise.
Can one certificate cover all our branches or tills? +
No. A certificate is issued to a device (an EGS unit), not to a company. Each device onboards with its own OTP, holds its own certificate, and keeps its own ICV counter and PIH chain. Two tills sharing one certificate and one counter will collide the first time they issue at the same moment, and the chain will break.
What happens when the production certificate expires? +
Clearance and reporting start failing. Renewal is not automatic: someone has to sign in to the Fatoora portal, generate a fresh OTP, and run the renewal for every device. If you have forty branches, that is forty renewals on a schedule someone has to own. Build the reminder into your system before you need it, not after.
Can we generate the Phase 2 QR code ourselves? +
Not from the layout layer, and not before the invoice is stamped. The Phase 2 QR carries eight TLV fields, and three of them — the XML hash, the ECDSA signature and the public key — do not exist until the invoice has been hashed and stamped with the device certificate. For a simplified invoice your solution produces that QR itself; for a standard invoice you take the cleared document ZATCA returns, which comes back carrying the Authority's own stamp, rather than drawing your own code. You can inspect any QR you have been handed with our free QR code reader to see which phase produced it.
What is the difference between the API and the Partner API? +
The API is for one business: one account, its own devices, its own invoices. The Partner API is for a software company serving many merchants — one partner key, a merchant onboarding link so each merchant enters their own OTP themselves, and per-merchant branches and devices underneath. Both are documented: the API reference and the Partner API reference, with an overview in the partner guide.
If we integrate with a service, can we get our invoices back out? +
You should insist on it before you sign anything. Invoices must be kept six years in the format they were issued in, which means the signed XML and not only a PDF. With us, the signed XML of every invoice is archived for six years and downloadable, so a merchant can leave and take the archive with them. Ask any vendor the same question and accept only a concrete answer.
Ready to connect your business?

Connecting is free and takes under five minutes.

Start for free