← Blog Guides 8 min read · 20 September 2026

E-invoicing for online stores in Saudi Arabia: getting every order invoiced without touching XML

A stream of online store orders on one side and signed e-invoices with QR codes on the other, with a connection step between them
The store records the sale. Something else has to sign the document and send it to the Authority — and it cannot start until your establishment is connected.

An order is paid at eleven at night, the confirmation email goes out, and nothing has reached the Zakat, Tax and Customs Authority. Your store recorded a sale; the e-invoice is a separate document that has to be built, signed with your establishment's certificate, given a compliant QR code and transmitted. It is owed on every paid order, and the gap between a live store and invoiced orders is where too many merchants sit.

What your store platform does, and what it does not

Shopify and WooCommerce hold everything an invoice needs: items, quantities, discounts, shipping, the money actually taken. Neither reports to ZATCA, and neither holds your establishment's certificate, your invoice counter or the hash chain linking each document to the one before it.

A working setup has one shape: the store announces a paid order, and an e-invoicing system turns it into a compliant document, signs it and sends it to the Authority. Ours does that through the Shopify app, the WooCommerce plugin or the REST API. Shopify invoices an order the moment it is marked paid; WooCommerce when it is marked paid, processing or completed, whichever comes first. Cash on delivery invoices when you mark it paid.

Almost every order is a simplified invoice

A simplified tax invoice is the consumer document: handed over immediately, reported to the Authority within 24 hours. A standard tax invoice carries the buyer's VAT number and address and must be cleared before it reaches them (the full comparison is here). A store's order table is mostly the first kind, and the amount decides as much as the buyer: under article 53 of the VAT Implementing Regulations a simplified invoice is permitted below SAR 1,000 whoever the buyer is, while a supply of SAR 1,000 or more to a VAT-registered buyer must carry a full tax invoice. Marking an order as a business purchase cannot promote a 460-riyal sale.

Neither integration makes a human choose per order. WooCommerce puts an optional "buying as a business" field in the checkout: a valid VAT number with a complete national address produces a cleared tax invoice, and below the threshold it stays simplified with the number printed on it. Shopify prints a buyer-typed number too, but clears a tax invoice only for a buyer you confirmed as an establishment in the panel, or a native Shopify B2B purchasing company.

Neither withholds an invoice: when the buyer's details cannot produce a valid tax invoice, the simplified one is issued anyway with a notice naming what was missing. A buyer VAT number that is present must be fifteen digits starting and ending with 3, or BR-KSA-44 rejects the document; missing address elements only warn, under BR-KSA-63.

What gets issued, per event

In the storeWhat is issuedWhy
A paid consumer orderSimplified tax invoiceReported within 24 hours
SAR 1,000+, valid buyer VAT number, full addressStandard tax invoice, clearedMandatory at that amount
The same buyer, below SAR 1,000Simplified, VAT number printedArticle 53 permits it
A full refundCredit note for the invoice valueAn invoice is never edited
A partial refundCredit note for the returned linesThe rest of the supply stands
A return that moves no moneyNothingThe sale did not change
An order cancelled before invoicingNothingNo document to correct
A test order, or a non-SAR orderNothing — skipped, with the reasonNot a completed SAR sale

Installing the app is not the last step

This is the failure that costs merchants most. Connecting your store and connecting your establishment are two different things. The store connection lets us see orders. The establishment connection is your onboarding with ZATCA: a certificate request, one OTP from the Fatoora portal, compliance checks, a production certificate in your name. Until that certificate exists there is nothing to sign an invoice with.

What happens in between is the trap. The store stays open, orders keep arriving, and each one fails for that single reason and is recorded as a failed order rather than an invoice — nothing is queued for later. A merchant who never came back to finish onboarding can go months believing invoicing is handled while not one document has been issued. We email the owner when orders are waiting, but check your invoices page after your first real sale.

Finishing the connection fixes everything from that point forward, and only from that point: past failures are not back-filled. On WooCommerce the order still lives in your own database, so the ZATCA Tools screen in WordPress offers a Retry per order. On Shopify the order arrived as a webhook that is gone once processed, so those are issued by hand. Onboarding itself is one OTP from the Fatoora portal, used once, from the right environment — the walkthrough has the details.

The invoice has to total what the customer paid

Saudi shelf prices include VAT, so store prices do too, and the invoice has to work backwards from a number that already contains the tax. That is where a halala goes missing, and a customer who paid 125.00 does not accept an invoice for 125.01.

Take two mugs at 45.00, a bag of coffee at 10.00 and 25.00 of delivery: 125.00 paid, tax included. Each line converts to its price before VAT, rounded half-up to the halala — the mugs 39.13 each (78.26 for the line), the coffee 8.70, delivery 21.74, giving 108.70. Multiply that rounded figure by 15% and you get 16.305, which rounds to 16.31 and an invoice for 125.01. Worked out once from the value before rounding it is 16.30, and 108.70 plus 16.30 is exactly 125.00 — ZATCA's XML Implementation Standard asks for final results to be rounded, not intermediate ones.

One constraint cannot be argued away: a line's net must equal quantity times unit price exactly, so some baskets have no two-decimal price that lands on the right total. The halalas that cannot be fitted are declared as a document-level allowance rather than added to what the customer owes. It is settled on our side, identically for a store order, a typed invoice and an API call.

A refund is a credit note, not an edit

An invoice that has been cleared or reported cannot be changed or deleted, so a refund becomes a second document referencing the first and carrying a reason — a note without one is rejected under BR-KSA-17. The note inherits the form of its invoice, so a note against a cleared tax invoice is itself cleared (credit and debit notes covers the rest).

The value follows the money actually returned. Continue the order above: the customer returns the coffee and 10.00 goes back to the card. The note carries 8.70 plus 1.30 of VAT, totalling 10.00 — where 15% of the rounded 8.70 would have reversed 1.31, more VAT than the invoice ever charged. A note never credits more than the invoice has left open. A refund for an order we never invoiced produces nothing: there is no original to reference, so the order is marked with that reason.

WooCommerce adds cases, because the plugin watches the order indefinitely: cancelling an invoiced order produces a full credit note, restoring it produces a debit note, and editing it issues the difference. Nothing is deleted; both documents stay as the audit trail.

Riyals only

We issue in SAR and nothing else. An order in another currency is recorded as skipped with that reason rather than converted, because the rate used would be printed on a tax document in your name. Sell to Saudi Arabia in riyals and those orders invoice automatically; the rest stay yours to handle.

What this does not do

It is not an accounting system: no ledger, no journals, no inventory, no payroll. It does not manage stock or fulfilment. There is no multi-currency and no recurring invoicing. If your platform already issues compliant signed invoices and reports them itself, you do not need us.

What it does is the narrow part: every paid order becomes a signed invoice with its QR code, cleared or reported as its type requires, the signed XML archived six years and downloadable, credit notes raised from refunds, rejections shown with the Authority's own code and a link to its guide, per-branch devices, and sales reports. Already running an ERP? Connecting it through the API is the smaller change, and the error reference explains what comes back. Free to start: 50 invoices or 30 days from the day you connect, whichever comes first, then from 49 SAR a month — start here. Then finish the connection before your next sale.

Frequently asked questions

Is Shopify ZATCA compliant? +
The question is about the invoice, not the platform. Shopify records the sale and takes the money; it does not sign a document with your establishment's certificate, chain it to the invoice before it, or transmit it to the Authority, and it does not claim to. The same is true of WooCommerce and of every other store platform. Compliance is decided by whatever issues the invoice for each order — a solution onboarded to ZATCA under your own VAT number. Installing a store platform never puts you in breach; leaving its orders uninvoiced does.
Do I need an invoice for every order? +
Every taxable supply needs one, and an order a customer paid for is a supply. In practice that means one simplified tax invoice per paid order, reported to the Authority within 24 hours of issue. What does not need one is anything that never became a sale: an abandoned cart, an order cancelled before payment, a test order through a fake gateway. A return that moves no money needs no document either — there is nothing to correct.
My store is connected but no invoices are appearing. What is wrong? +
Almost always the establishment itself never finished its ZATCA connection. Installing the app and completing onboarding are two separate steps: until your establishment holds a production certificate there is nothing to sign an invoice with, so each order arrives, fails for that one reason, and is recorded as a failure rather than an invoice. Finishing it takes one OTP from the Fatoora portal — the onboarding walkthrough covers where the code comes from and the mistakes that waste it. Orders that failed while you were unconnected are not invoiced retroactively on their own.
A customer wants an invoice with their company VAT number. What do I do? +
Capture the VAT number at checkout rather than after the sale. What you can issue then depends on the amount: below SAR 1,000 a simplified invoice is permitted for any buyer and their VAT number is printed on it, while a supply of SAR 1,000 or more to a VAT-registered buyer must carry a full tax invoice — which needs the buyer's complete national address, not just a VAT number. If a required field is missing we still issue the simplified invoice, because an unreported sale is worse than an under-specified one, and attach a notice naming what was missing. Standard versus simplified sets out the difference in full.
What happens when I refund an order? +
A refund in the store becomes a credit note against that order's invoice, carrying a reason and a reference to the original. A partial refund credits the returned lines only and the rest of the sale stands. Two cases produce nothing: a return that moved no money, and a refund for an order that was never invoiced through us — there is no original to reference, so the order is marked with that reason and you raise a note by hand if one is due. Credit and debit notes explains why an issued invoice is never edited.
Can I sell in dollars? +
You can sell in whatever your platform supports, but we issue documents in Saudi riyals only. An order whose currency is not SAR is recorded as skipped with that reason rather than converted at a rate we picked for you, because the rate used would end up on a tax document under your name. If you run one storefront for Saudi Arabia and another for elsewhere, the Saudi one invoices automatically and the rest do not.
Does the customer see anything different at checkout? +
No. The integration sits behind the sale: the buyer pays as they always did, and the invoice is issued from the order afterwards. What changes is what they receive — the invoice number and a PDF with its QR code, and on WooCommerce links in the order emails and the My Account page. The one visible addition is optional: a field asking whether they are buying on behalf of a company, which is the right moment to ask, because correcting the invoice type afterwards costs a credit note and a reissue.
Ready to connect your business?

Connecting is free and takes under five minutes.

Start for free