Wise Hustlers — Digital Product & App Development Studio Logo
Get Consultation
By Wise Hustler Admin9/22/20268 min read

ZATCA clearance vs reporting: which path your invoices take, and what it does to your architecture

ZATCA clearance vs reporting: which path your invoices take, and what it does to your architecture

The difference matters more than it sounds. Clearance means ZATCA sees the invoice before your customer does and returns a stamped version you must deliver. Reporting means you give the customer the invoice immediately and tell ZATCA within 24 hours. Standard tax invoices — mostly B2B — are cleared. Simplified tax invoices — mostly B2C — are reported.

That one distinction decides whether the Fatoora platform is a synchronous dependency in your checkout or an asynchronous job behind it. Teams that get it wrong do not get a compliance failure. They get a till that stops working when a government API has a slow afternoon.

This is engineering context, not tax advice.

Clearance: ZATCA is in the request path

For a standard tax invoice under Phase 2, the sequence is:

1. Your system generates the invoice as XML in ZATCA's implementation standard.

2. You submit it to Fatoora for clearance.

3. Fatoora validates it against the XML implementation standard and runs additional referential checks.

4. On success, Fatoora adds the cryptographic stamp and the QR code to the XML and returns the cleared XML.

5. You give the buyer the cleared document — XML, or PDF/A-3 with the XML embedded.

Step 4 is the one people miss. For B2B invoices you do not generate the QR code. ZATCA's guideline states it plainly: the QR code string is generated by ZATCA at the time of clearance, along with its stamp, and taxpayers are expected just to visualise the QR code from the string they get back.

We have reviewed integrations that carefully construct a nine-tag TLV QR code for standard invoices and render it on the PDF. It is wasted work at best, and at worst it is a different QR code from the one in the cleared XML — two documents describing the same sale, disagreeing.

The architectural consequence is the real one: your invoice is not issuable until a remote system responds. Whatever your invoice-issuing flow is — a sales order confirmation, a project milestone, a month-end batch — it now contains a network call to an authority you do not control.

Reporting: ZATCA is behind you

For a simplified tax invoice:

1. Your system generates the XML.

2. Your own solution stamps it using its CSID and applies a Phase 2 QR code — nine tags, TLV, base64.

3. You hand the customer the invoice immediately, printed (or electronically by agreement).

4. You submit the XML to Fatoora for reporting within 24 hours of generation.

The customer is never waiting on ZATCA. A supermarket lane does not stop because Fatoora is slow. This is clearly deliberate: the clearance model would be unworkable at retail throughput, so the stamping authority moves into the taxpayer's own onboarded solution and the reporting becomes a follow-up obligation.

For engineering, reporting is the easier runtime problem and the harder durability problem. You now own a queue of invoices that must reach ZATCA inside 24 hours, and you own what happens when they do not.

Which invoices take which path

The default is the transaction type: standard for B2B, simplified for B2C. There is one exception worth encoding carefully.

You may issue a simplified invoice for a B2B transaction only where the value of taxable supplies is under SAR 1,000. Above that, a B2B sale needs a standard tax invoice and therefore clearance. B2C simplified invoices carry no such ceiling — a simplified invoice is fine for a consumer sale of any value.

So the routing rule in your code is not "is the customer a business", and it is not "is the amount over 1,000". It is both, in that order:

  • Business customer, taxable supplies ≥ SAR 1,000 → standard → clearance
  • Business customer, taxable supplies < SAR 1,000 → standard or simplified, your choice
  • Consumer → simplified → reporting

Make that decision explicit and log it against the invoice. The one thing you do not want at audit is an invoice whose path cannot be explained from the record.

The failure modes are different, so design them separately

Clearance is a synchronous dependency. Decide, before go-live, what your system does when Fatoora is slow or down. The options are genuinely constrained: you can block invoice issuance, or you can queue and issue later. You cannot issue an uncleared standard invoice to the buyer and fix it afterwards.

One response code deserves specific handling. 303 means clearance is switched off — and the required action is to submit the invoice via reporting instead. That is not an error path bolted on for completeness; it is ZATCA telling you to change flow mid-operation. A system that treats 303 as a generic failure and retries clearance will sit there retrying.

Similarly:

  • 400 — rejected. Correct the data and submit a new document. The rejected one keeps its counter value and hash.
  • 401 — check the authentication certificate and secret. Certificates expire; this will eventually happen on a weekend.
  • 413 — payload too large. Invoices cap at roughly 10MB, which real invoices reach only when someone embeds something they should not.
  • 429 — you are being rate limited. Batch invoicing needs to expect this.
  • 500 / 503 / 504 — the invoice was not received. Retry is correct here, unlike 400.

Reporting is a durability problem. The 24-hour window is generous per invoice and unforgiving in aggregate: a reporting job that silently dies on Friday afternoon breaches the window for every invoice issued since. Instrument the age of the oldest unreported invoice, not the success rate of the last batch. Success rate looks fine when nothing is being attempted.

What this means for the shape of your system

Three design positions that hold up in production:

Put an invoice-submission service between your billing system and Fatoora. Both flows need onboarding credentials, certificate handling, retry policy, the counter and the hash chain. None of that belongs in a POS terminal, and most of it is identical across the two paths. This matters even more when the billing system is one you did not write.

Model the invoice's ZATCA state explicitly. Not a boolean. At minimum: generated, submitted, cleared, accepted-with-warnings, rejected, reported, failed. Accepted-with-warnings is a real and common state — the document counts as accepted but is not considered fully compliant, and ZATCA's guidance is that warnings may become rejections in future. A system with no state for it will either treat warnings as success and never surface them, or treat them as failure and block valid invoices.

Keep the cleared XML, not just your own. The cleared document — with ZATCA's stamp and QR — is the authoritative artefact for a standard invoice. Store it as returned. Regenerating it later from your own data will not reproduce the stamp.

For the field-level detail behind the rejections, see the ZATCA XML and its validation errors; for the stamping and QR mechanics, cryptographic stamping, CSID and the TLV QR code.

Frequently asked questions

Do I generate the QR code for B2B invoices?

No. For standard tax invoices ZATCA generates the QR code string at clearance and returns it. You render it. You generate the QR code yourself only for simplified invoices.

What is the 24-hour window measured from?

Generation of the simplified invoice, not the end of the day or the close of the shift.

Can I clear invoices in a nightly batch?

Not for standard invoices. Clearance has to happen before the invoice goes to the buyer, so a nightly batch means a nightly invoice. Simplified invoices can absolutely be reported in batches within the 24-hour window.

What if clearance fails and the customer is waiting?

You cannot issue the uncleared invoice. Correct the error and submit a new document with the next counter value. If this happens often at a trade counter, the fix is upstream data quality, not a workaround.

Is a simplified invoice acceptable for a business customer?

Only where taxable supplies are under SAR 1,000. Above that, B2B needs a standard invoice.

What does 303 mean in practice?

ZATCA has switched clearance off, and you should submit via reporting instead. Your system needs this as a real branch, not a retry.

Do both flows need the hash chain and counter?

Yes. The tamper-resistant counter and the previous-invoice-hash chain apply to documents generally, not to one flow.

Sources

Related articles