How to Integrate E-Commerce Platforms with ZATCA Fatoora portal?

How do e-commerce stores comply with ZATCA Phase 2 in Saudi Arabia?
Every online order must generate a simplified (B2C) e-invoice at checkout — a signed XML document carrying a cryptographic stamp (CSID) and a TLV/Base64 QR code — and report it to ZATCA's Fatoora Platform within 24 hours of issuance.
In practice, this means connecting your store's payment gateway webhooks to an invoicing engine that creates, signs, and syncs invoices automatically: one-click apps for Salla and Zid, or REST API integration for Shopify, WooCommerce, and custom storefronts. Manual invoicing cannot survive e-commerce volume — automation is the compliance strategy. Here's what this guide covers:
- What actually changed for online stores under Phase 2 — and the 24-hour rule that flash sales break.
- How to connect Salla, Zid, Shopify, WooCommerce, and custom platforms to Fatoora.
- The full technical lifecycle of an order, from checkout webhook to ZATCA acceptance.
- Edge cases that trip up every store: refunds, promo codes, COD, and BNPL (Tabby/Tamara)
- How does Wafeq automate all of it without slowing your checkout?
What Has Officially Changed for E-Commerce Invoicing Under ZATCA Phase 2?
Phase 1 asked stores to generate e-invoices. Phase 2 (the Integration Phase) asks them to prove it, order by order, on ZATCA's servers. For a digital store, two changes carry all the weight.
What's the Difference Between a Standard Tax Invoice (B2B) and a Simplified E-Receipt (B2C)?
Your store almost certainly issues both, and they follow different compliance paths:
- Simplified tax invoices (B2C) — the receipt for a consumer order. It must be issued at the point of sale with a Phase 2 QR code (nine data tags encoded in TLV format, wrapped in Base64, including the cryptographic stamp and invoice hash), signed by your device's Production CSID, and reported to ZATCA within 24 hours. The customer gets it instantly; ZATCA gets it within a day.
- Standard tax invoices (B2B) — issued when a business customer buys with a VAT registration number (wholesale orders, corporate procurement through your storefront). These follow the stricter clearance model: the XML must be submitted to and cryptographically stamped by ZATCA before the invoice is legally shareable with the buyer.
Learn about: Why Does the Invoice Title Sometimes Say "Simplified Tax Invoice" Instead of "Tax Invoice"?
Get 30% Off Wafeq yearly packages
Enter your email to receive your exclusive discount code. New users only!
The architectural implication:
The architectural implication:
Your checkout must detect the buyer type (a TRN field at checkout is the usual trigger) and route the document down the correct path automatically. A B2B order pushed down the B2C reporting path is a compliance defect, not a formatting choice.
Why Does the 24-Hour Reporting Window Break During Flash Sales?
Twenty-four hours sounds generous until you model a White Friday event. A store doing 200 orders on a normal day produces 200 invoices to report; the same store during a flash sale can produce 15,000 in six hours. Now the failure modes compound:
- Queue backlog — if invoices are generated in batches overnight rather than per-order, a sale-day backlog can push the oldest invoices past the 24-hour deadline before the queue drains.
- Server latency on both sides — your own backend is under peak load exactly when it must also sign XML and call ZATCA's APIs; retries pile onto an already stressed system.
- Silent partial failures — 3% of webhook deliveries failing during a traffic spike means hundreds of orders that simply never became reported invoices, discovered only at reconciliation.
This is why reporting latency should be monitored as an operational KPI — average time from payment capture to ZATCA acceptance, retry rates, and queue depth — alongside your conversion metrics.
We've detailed the exact dashboard to run in: Key KPIs to Track Your Success on the ZATCA Fatoora Portal.
How Do You Connect Salla, Zid, Shopify, or a Custom Store to Fatoora?
There are two integration models, and choosing correctly depends on where your store lives.
On Salla or Zid? Use One-Click App Store Onboarding
For the Saudi-native SaaS platforms, the heavy lifting is productized. Connecting Wafeq from the Salla or Zid app store links every order event to a compliant invoicing engine: the store pushes order data automatically, and the accounting layer handles CSID onboarding (the OTP-based device registration on the Fatoora Portal), XML generation, signing, QR injection, and 24-hour reporting.
Your team never touches an XML file. The merchant's real decisions are configuration-level: which ledger accounts map to sales, shipping, and gateway fees, and how refunds post.
B. On Shopify, WooCommerce, Magento, or Custom Code? Use REST APIs & Webhooks
Global platforms don't speak ZATCA natively — Shopify will not sign a UBL invoice for you. The proven architecture:
- Webhooks as the trigger. Subscribe to the payment-success event (orders/paid on Shopify, woocommerce_order_status_completed, or your gateway's capture callback). The paid order — not the created order — is the invoicing moment.
- A REST API as the invoicing engine. The webhook handler posts the order payload (lines, VAT, discounts, shipping, buyer type) to an e-invoicing API such as Wafeq's, which builds the UBL 2.1 XML, computes tax, signs with the store's CSID, generates the TLV QR, and reports to ZATCA.
- The response closes the loop. The API returns the compliant invoice (with QR) to attach to the customer's confirmation email, plus the ZATCA acceptance status for your logs.
What Does the Full Order-to-Fatoora Lifecycle Look Like Technically?
Follow one order through the pipeline, and every requirement finds its place:

How Do You Handle Refunds, Promo Codes, COD, and BNPL Correctly?
The happy path is easy. E-commerce compliance is won or lost on the edge cases.
A. What Happens When a Customer Refunds or Cancels an Order?
A reported invoice cannot be deleted or edited — ever. The only compliant correction is a credit note: a new signed document that references the original invoice's UUID and number, carries the returned amounts and their VAT, and is itself reported to ZATCA.
For e-commerce, this must be automated end-to-end: the refund webhook from your gateway should trigger credit note generation with the original-invoice linkage resolved automatically, including partial refunds (one returned item out of five).
The full referencing rules are in:How to handle credit notes in KSA e-invoicing: ZATCA rules.
Where Do Promo Codes and Shipping Fees Go in the XML?
A 20% sitewide coupon is not one number — in UBL 2.1 it must be represented so that taxable amounts remain consistent: discounts allocated at line level or as document-level allowances, with VAT computed on the post-discount taxable base, and every declared total reconciling with its lines to the halala. Shipping is a taxable supply line of its own (standard-rated for domestic delivery), not a magic number appended to the total. Systems that compute the discount in the cart but not in the XML produce the classic rounding-mismatch rejection.
How Do You Invoice Cash on Delivery (COD) Without Creating Phantom Tax Liabilities?
COD splits the order moment from the payment moment — and in Saudi e-commerce, a meaningful share of COD orders are refused at the door. Issue the invoice at dispatch and every refused package becomes a reported invoice whose sale never happened, requiring a credit note to unwind: phantom revenue, doubled document volume.
The clean pattern is to align invoice issuance with your recognition policy — trigger on delivery confirmation/payment capture where your fulfillment flow allows it, and where invoicing at dispatch is operationally necessary, make automatic credit-note generation on the return webhook non-negotiable so refused orders self-correct without manual accounting work.
How Do BNPL Providers Like Tabby and Tamara Affect the Invoice?
Buy-now-pay-later confuses teams because two different money flows exist: the customer's invoice and the provider's settlement. The tax invoice to the customer is for the full order value with full VAT — the customer owes the full price; Tabby or Tamara merely finances it.
The provider's merchant fee is a separate cost transaction between you and the BNPL provider (typically documented by the provider's own tax invoice to you, with its own input VAT treatment). Netting the fee out of the customer's invoice understates your output VAT — one of the most common BNPL bookkeeping errors. A correct integration books the gross sale on the e-invoice and the fee as a payable expense, reconciling both against the provider's settlement report.
How Does Wafeq Automate E-Commerce Invoicing Without Slowing Checkout?
The engineering constraint is unforgiving: compliance must add zero latency to the customer's checkout while guaranteeing every order becomes a reported invoice. Wafeq's architecture is built around that constraint:
- High-throughput, asynchronous processing. Payment webhooks are acknowledged instantly, and invoicing runs off the checkout path — flash-sale bursts of thousands of orders per hour queue and process without touching conversion.
- Offline buffering queues for ZATCA outages. If the Fatoora Platform is slow or unreachable during peak load, invoices are stored durably and retried automatically with backoff — the 24-hour window is managed by the queue, not by an engineer paged at midnight.
- Pre-validation before every submission. Each payload is screened against ZATCA's schema and business rules — mandatory fields, tax math, discount allocation, hash chain state — so errors are fixed at the source instead of arriving as rejections.
- Native connectors and open APIs. One-click apps for Salla and Zid; documented REST APIs and webhook endpoints for Shopify, WooCommerce, Magento, and custom stacks — with the same signing, QR, and reporting engine underneath.
- A single reconciliation surface. Every order, invoice, credit note, and ZATCA status in one ledger, so your month-end is a review, not an investigation.

Read Also: Why is the Fatoora Portal Rejecting Your Invoices? Practical Solutions for ZATCA Integration Errors
Phase 2 quietly made your invoicing pipeline part of your conversion funnel: a store that invoices manually will either slow its operations or fall out of compliance the first time volume spikes — and Saudi e-commerce is nothing but volume spikes. The stores that win peak seasons are the ones where every paid order becomes a signed, QR-stamped, ZATCA-reported invoice automatically, in the background, at any scale.
FAQs about E-Commerce & ZATCA Integration
Is an e-invoice required for every single online transaction in KSA?
Yes. Every taxable sale by a VAT-registered store must produce an e-invoice — a simplified invoice for consumer (B2C) orders, reported to ZATCA within 24 hours, or a standard invoice for business (B2B) buyers, which ZATCA must clear before being shared. There is no volume threshold or exemption for small orders.
How do I handle ZATCA e-invoicing for Cash on Delivery (COD) orders?
Align invoice issuance with your fulfillment reality: trigger the invoice on delivery confirmation or payment capture where your workflow allows, so refused packages never become reported sales. If your operation must invoice at dispatch, automate credit note generation on the return event so every refused COD order is corrected without manual intervention.
Can I connect a Shopify store directly to ZATCA Phase 2?
Not natively — Shopify does not generate ZATCA-compliant signed XML or manage CSIDs. The standard architecture connects Shopify's payment webhooks to a ZATCA-approved invoicing engine via REST API, which builds the UBL invoice, signs it, generates the QR code, and reports to Fatoora automatically.
How do promo codes affect VAT calculation on simplified e-invoices?
VAT is calculated on the discounted (post-coupon) taxable amount, and the discount must be represented inside the invoice XML — allocated across line items or as a document-level allowance — so that declared totals reconcile exactly with the lines. Applying the discount in the cart but not in the XML structure is a common cause of rounding-mismatch rejections.
What happens if ZATCA's servers go down during a flash sale?
Your obligation to report simplified invoices within 24 hours stands, so your system must queue unsubmitted invoices durably and retry automatically until acceptance. Platforms with offline buffering — like Wafeq — store every signed invoice and drain the queue when connectivity returns, keeping the sale flowing and the reporting window intact.
Stop choosing between checkout speed and compliance. Connect your store to Wafeq's API today in one click, with a clean REST integration — and make every order self-invoicing.
Stop choosing between checkout speed and compliance. Connect your store to Wafeq's API today in one click, with a clean REST integration — and make every order self-invoicing.















![How to prepare for ZATCA audits [Essential Records and Steps]](/_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fwafeq-docs.appspot.com%2Fo%2Fmedias%252Ff44c0072_%D9%83%D9%8A%D9%81%D9%8A%D8%A9%20%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D8%AF%D8%A7%D8%AF%20%D9%84%D9%84%D8%AA%D8%AF%D9%82%D9%8A%D9%82%20%D8%A7%D9%84%D8%B6%D8%B1%D9%8A%D8%A8%D9%8A%20%D9%81%D9%8A%20%D8%A7%D9%84%D8%B3%D8%B9%D9%88%D8%AF%D9%8A%D8%A9%20%5B%D8%A7%D9%84%D8%B3%D8%AC%D9%84%D8%A7%D8%AA%20%D9%88%D8%A7%D9%84%D8%AE%D8%B7%D9%88%D8%A7%D8%AA%20%D8%A7%D9%84%D8%A7%D9%94%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9%5D.png%3Falt%3Dmedia&w=3840&q=75)