ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

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 name attribute 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):

xmlzatca-phase2-ubl.xml
<?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/single within 24 hours. No ZATCA signature returned — the invoice delivered to the consumer is the local one.
textfatoora-flow.txt
┌────────────┐    ┌──────────────┐    ┌────────────┐
│ 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

  1. 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).
  2. 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.
  3. 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.
  4. 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.
  5. 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.