Saudi Arabia — ZATCA and FATOORA
ZATCA rolled out the e-invoicing mandate in two steps: Phase 1 “Generation” in December 2021, then Phase 2 “Integration” deployed in waves since January 2023, with an extended UBL 2.1 format, mandatory XAdES signature and TLV QR code.
Regulatory timeline
- VAT Law Royal Decree M/113 of 28/05/1438 H (2017). Introduction of VAT in Saudi Arabia on 1 January 2018, raised to 15% in July 2020.
- ZATCA Resolution 0010 of 12 December 2020. Establishes the electronic invoicing framework with a two-phase rollout.
- 4 December 2021. Phase 1 Generation goes live. Every VAT-registered resident must issue structured electronic invoices with QR code (minimal UBL 2.1 or PINT XML).
- ZATCA Resolution 2-7-3 of 24 May 2022. Announces Phase 2 Integration with FATOORA, wave-based rollout from January 2023.
- 1 January 2023. Phase 2 starts with Wave 1: resident enterprises with 2021 turnover > SAR 3bn.
- April 2023. Wave 2 (turnover > SAR 500M).
- Waves 3 to 19, 2023-2026. ZATCA publishes the next wave each quarter at a lower turnover threshold (typically announced 6 months ahead of go-live).
- Wave 19 (announced mid-2026). Extension to resident taxpayers with 2024-2025 turnover > SAR 750,000.
Technical schema
The format is UBL 2.1 with a SA Profile adding several specific blocks:
-
InvoiceTypeCode encoded on two axes: the UN/CEFACT code (388 for
standard invoice, 381 for credit note, etc.) and a
nameattribute of 7 digits encoding 4 binary flags (B2B/B2C, export, summary, etc.). - UUID, ICV (Invoice Counter Value) and PIH (Previous Invoice Hash) for the integrity chain — each invoice is linked by hash to the previous one, forming an immutable chain.
- UBL Extension carrying the XAdES-EPES signature, the base64 TLV QR code, and the cryptographic stamp timestamp.
- PartyIdentification CRN (Commercial Registration Number) and PartyTaxScheme CompanyID in the Saudi format (15 digits starting with 3).
Minimal Phase 2 B2B ZATCA invoice (signature and QR omitted for readability):
<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2">
<cbc:ProfileID>reporting:1.0</cbc:ProfileID>
<cbc:ID>SME00000001</cbc:ID>
<cbc:UUID>3cf5ee18-ee25-44ea-a444-2c37ba7f28be</cbc:UUID>
<cbc:IssueDate>2026-05-16</cbc:IssueDate>
<cbc:IssueTime>10:30:00</cbc:IssueTime>
<cbc:InvoiceTypeCode name="0211010">388</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>SAR</cbc:DocumentCurrencyCode>
<cbc:TaxCurrencyCode>SAR</cbc:TaxCurrencyCode>
<cac:AdditionalDocumentReference>
<cbc:ID>ICV</cbc:ID>
<cbc:UUID>10</cbc:UUID>
</cac:AdditionalDocumentReference>
<cac:AdditionalDocumentReference>
<cbc:ID>PIH</cbc:ID>
<cac:Attachment>
<cbc:EmbeddedDocumentBinaryObject mimeCode="text/plain">NWZlY2ViNjZmZmM4...</cbc:EmbeddedDocumentBinaryObject>
</cac:Attachment>
</cac:AdditionalDocumentReference>
<cac:AccountingSupplierParty>
<cac:Party>
<cac:PartyIdentification>
<cbc:ID schemeID="CRN">1010001234</cbc:ID>
</cac:PartyIdentification>
<cac:PartyTaxScheme>
<cbc:CompanyID>310122393500003</cbc:CompanyID>
<cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme>
</cac:PartyTaxScheme>
<cac:PartyLegalEntity>
<cbc:RegistrationName>ediverse Demo Co. Ltd.</cbc:RegistrationName>
</cac:PartyLegalEntity>
</cac:Party>
</cac:AccountingSupplierParty>
</Invoice>Submission flow
In Phase 2 there are two distinct flows:
-
B2B clearance: the invoice is sent to FATOORA via
POST /invoices/clearance/single. FATOORA validates, signs and returns the cleared invoice (with the ZATCA signature in addition to the seller's). The seller delivers this version to the buyer, not the original. -
B2C reporting: the invoice is issued locally and sent to
FATOORA in asynchronous reporting via
POST /invoices/reporting/singlewithin 24 hours. No ZATCA signature returned — the invoice delivered to the consumer is the local one.
┌────────────┐ ┌──────────────┐ ┌────────────┐
│ SA Seller │───>│ FATOORA │───>│ SA Buyer │
│ (ERP + │ │ (ZATCA) │ │ (ERP) │
│ E-2 unit) │ │ B2B clearance│ │ │
└────────────┘ └──────┬───────┘ └────────────┘
│
▼
┌─────────────────┐
│ B2B: clearance │ ← cryptographic stamp
│ signed response │ + QR code (TLV)
│ B2C: reporting │
│ within 24h │
└─────────────────┘Validation
- ZATCA Sandbox: sandbox.zatca.gov.sa — test environment for Phase 2.
- FATOORA Compliance and Enablement Toolbox (SDK) — Python and C# tools published on the ZATCA developer portal to validate compliance.
- ZATCA documentation: zatca.gov.sa — Systems Developers.
- TLV QR Decoder — ZATCA utility to validate the QR code structure (9 mandatory TLVs).
Common pitfalls
- ICV + PIH integrity chain. Every invoice issued by an e-invoice solution must include the ICV (counter) and the PIH (hash of the previous invoice). A break (non-sequential ICV or incorrect PIH) blocks the entire following chain. Multi-unit architectures must isolate counters per EGS (E-Invoice Generation Solution).
- Strict TLV QR code. The 9 TLVs must appear in the order set by ZATCA. A missing field or a wrong Length encoding fails the check on both the FATOORA side and on consumer-side readers.
- B2C reporting within 24 hours. The 24-hour deadline starts from the issuance date, not from the end of the accounting day. A nightly job reporting more than 24h after the day's first invoice is non-compliant.
-
Two-axis InvoiceTypeCode. The pair
InvoiceTypeCode+name="NNNNNNN"is subtle: the name encodes Self-billed, Third-party, Nominal, Exports, Summary as bit flags. Confusing UN/CEFACT 388 vs 380 or a wrongly encoded name is the most frequent error during Phase 1 → Phase 2 migration. - ZATCA certificate onboarding. Signing requires a certificate issued by ZATCA through a three-step onboarding API (CSID compliance, CSID production, request signing). Losing or rotating the certificate without an up-to-date CSR halts issuance: keep a scheduled rotation in place.
Cross-links
- PEPPOL — for semantic comparison with PINT (the ZATCA profile partially derives from PEPPOL).
- Article — ZATCA and Saudi e-invoicing — dedicated blog analysis.
- Article — E-invoicing country deep dive 2026.
- Official sources: zatca.gov.sa/E-Invoicing, sandbox.zatca.gov.sa.