Phase 2 in one paragraph
ZATCA’s e-invoicing regulation has two phases. Phase 1 (Generation) required compliant electronic generation and storage of invoices. Phase 2 (Integration) connects your invoicing solution to ZATCA’s FATOORA platform. ZATCA brings taxpayers into Phase 2 in waves based on revenue, and notifies each wave in advance. Once you’re in, standard tax invoices must be cleared by ZATCA before they reach the buyer, and simplified tax invoices must be reported within 24 hours.
This guide explains each technical element in the order you’ll meet it in a real project.
Step 1: Understand standard vs simplified invoices
| Aspect | Standard tax invoice | Simplified tax invoice |
|---|---|---|
| Typical use | B2B and B2G | B2C |
| ZATCA process | Clearance (before sharing) | Reporting (within 24 hours) |
| Who stamps | ZATCA adds its stamp on clearance | Your solution signs; ZATCA receives a report |
| Shared with buyer | Cleared XML (and a readable version) | Printed or electronic invoice with QR |
| If rejected | Invoice is not valid; must not be shared | Must be corrected and handled per ZATCA rules |
Credit and debit notes follow the type of the original invoice and must reference it.
Step 2: Generate UBL 2.1 XML
Every Phase 2 document is an XML file following UBL 2.1 with ZATCA’s data dictionary and business rules. Key elements include:
- UUID: a unique identifier for each invoice.
- Invoice type code and transaction flags: standard or simplified, plus flags such as third-party, nominal, export or summary where they apply.
- Seller and buyer details: VAT number, legal name, structured national address and other identifiers.
- Line items with quantity, price, VAT category, rate and amounts.
- VAT breakdown and totals with the rounding rules ZATCA validates.
- Billing references for credit and debit notes, plus a reason.
Most rejections in testing come from address structure, VAT category and exemption reason codes, and rounding differences between line and document totals.
Step 3: Hash, chain and count
Each invoice from a solution unit is linked to the previous one:
- Invoice hash: a SHA-256 hash of the canonicalised invoice XML.
- PIH (Previous Invoice Hash): the hash of the previous invoice from the same unit, embedded in the current invoice.
- ICV (Invoice Counter Value): an incrementing counter per unit that cannot be reset.
This chain is what makes tampering detectable, and it’s where many integrations break. If two users post invoices at the same moment and the system generates them in parallel, the chain forks. Your solution needs strict sequencing per unit, with locking, and durable storage of the last hash and counter.
Step 4: Get your CSID through onboarding
The Cryptographic Stamp Identifier (CSID) is the certificate ZATCA issues to each e-invoice generation solution (EGS) unit. Onboarding works like this:
- Generate keys and a CSR for the unit, containing the required organisation and unit details.
- Get an OTP from the FATOORA portal for the onboarding request.
- Request a compliance CSID through the compliance API using the CSR and OTP.
- Pass compliance checks by submitting sample documents for each invoice type you will issue (standard, simplified, credit and debit notes).
- Request the production CSID, which is used to sign live invoices and authenticate production API calls.
- Renew the production CSID before it expires.
Store private keys securely, never in plain text in the ERP database, and track each unit’s certificate expiry.
Step 5: Sign the invoice (cryptographic stamp)
The solution signs each invoice with the unit’s private key, producing an XAdES-style enveloped signature with the certificate details and signed properties embedded in the XML. ZATCA validates this signature on clearance and reporting.
Step 6: Build the QR code
The QR code is TLV-encoded (tag-length-value) and then Base64-encoded. In Phase 2 it carries:
- Seller name
- VAT registration number
- Invoice timestamp
- Invoice total (with VAT)
- VAT total
- Invoice hash
- Digital signature
- Public key
- For simplified invoices, ZATCA’s cryptographic stamp signature on the certificate
For simplified invoices your solution generates the QR at issue time. For standard invoices, the cleared invoice returned by ZATCA is what you share.
Step 7: Call the clearance and reporting APIs
- Clearance API: send the signed standard invoice. ZATCA validates it and returns the cleared invoice with its stamp, or errors. Only a cleared invoice may be shared with the buyer.
- Reporting API: send the signed simplified invoice within 24 hours. ZATCA validates and records it.
Responses may include warnings (accepted but should be fixed) and errors (rejected). Store the full response with each document.
Design for real-world conditions:
- Queues and retries with back-off when the API is slow or unavailable.
- Idempotency so a retry never results in a duplicate invoice.
- Clear status in the ERP: pending, cleared, reported, warning or rejected.
- Alerts for anything stuck or rejected.
Step 8: Test properly
Before go-live, test at least:
- Standard invoice, simplified invoice, and credit and debit notes for each.
- Zero-rated, exempt and out-of-scope lines with correct reason codes.
- Discounts at line and document level, and rounding edge cases.
- Foreign currency invoices, if you issue them.
- Concurrency: several users posting at once without breaking the hash chain.
- API failure: timeouts and retries without duplicates.
- CSID renewal process.
- Printed and PDF layouts with QR code and Arabic text.
Common integration problems
| Problem | Cause | Fix |
|---|---|---|
| Hash chain errors | Parallel invoice generation | Per-unit sequencing with locks |
| Address validation failures | Unstructured addresses in ERP | Structured national address fields |
| Rounding mismatches | Different rounding at line vs total | Consistent rounding rules in the generator |
| Expired certificates | No renewal tracking | Certificate inventory with alerts |
| Duplicates on retry | No idempotency | Unique references and status checks |
Phase 2 for POS and retail businesses
Retailers and restaurants issue mostly simplified invoices, often from many terminals and branches. That changes the engineering priorities:
- Many EGS units. Each POS terminal or branch system that generates invoices is typically onboarded as its own unit, with its own CSID, counter and hash chain. Plan onboarding, certificate storage and renewal for all of them.
- Offline periods. Terminals must keep selling when the network drops. The solution signs and prints invoices with QR codes locally, queues them, and reports them as soon as connectivity returns, within the 24-hour window.
- Volume. Thousands of small invoices a day need efficient batching, monitoring and alerting for anything approaching the reporting deadline.
- Returns. Refunds become credit notes linked to the original simplified invoice, which the POS must reference correctly.
Arabic text and invoice presentation
ZATCA rules require certain information in Arabic, and buyers expect a clear, readable invoice alongside the XML. In practice this means:
- Capturing the seller’s Arabic legal name and address once, and the buyer’s where required for standard invoices.
- Producing bilingual (Arabic and English) PDF or printed layouts that show the QR code and the required fields.
- Making sure your ERP’s fonts, character encoding and print templates handle Arabic properly, which older systems sometimes don’t.
These are small details that often surface late in testing. Include them in your test plan from the start.
Do you need to replace your ERP?
No. Most ERPs can stay as they are, with a ZATCA-compliant layer added next to them that captures invoices, generates and signs the XML, manages CSIDs and calls the APIs. We build exactly this for SAP Business One, Dynamics, Odoo, Zoho, Tally and custom systems. See our ZATCA Phase 2 integration service for how we deliver it.