E-invoicing in Saudi Arabia is not a PDF feature. It is tax infrastructure enforced by ZATCA, the Zakat, Tax and Customs Authority. Since December 2021 Phase 1 requires electronic generation, and since 2023 Phase 2 waves require live clearance or reporting via API. If you build SaaS, ERP, POS, or custom e-commerce for Saudi clients, Fatoora integration determines whether your software is sellable.
This guide covers law, data model, onboarding, signing, error handling, and operations for production Fatoora integrations.
1. Legal background in plain language
Every VAT-registered business with taxable supplies over the threshold must issue e-invoices. This includes B2B standard tax invoices, B2C simplified invoices, plus credit and debit notes. Paper or plain PDFs without structured XML are no longer compliant.
Phase 1, enforced from 4 December 2021, is about generation. You must produce UBL 2.1 XML with mandatory fields and a QR code, plus a human-readable PDF/A-3 with embedded XML. No API call was required, but ZATCA could audit format.
Phase 2, called Integration, is wave-based by revenue. ZATCA notifies each taxpayer of their deadline, starting with the largest enterprises in 2023 and moving to SMEs through 2024 to 2026. After your wave date you must connect your EGS units to ZATCA. Standard invoices use clearance, simplified use reporting. Missing the deadline risks fines and blocked commercial activity.
Understand this split because architecture follows it. Clearance is synchronous and blocking. Reporting is near-real-time with a 24-hour SLA.
2. Standard vs simplified in depth
Standard tax invoice is B2B where buyer has a VAT number. Flow is create draft in your system, sign locally, POST to ZATCA clearance endpoint, receive stamped invoice with ZATCA signature, invoice hash, and QR, then deliver stamped version to buyer via email or portal. Only the stamped version is legally valid. You must not send the pre-clearance version as final.
Simplified invoice is B2C retail, POS, or e-commerce to individuals. Flow is issue immediately to customer with your QR, then report to ZATCA within 24 hours. ZATCA returns acknowledgment but does not block issuance. This allows offline POS to keep selling during internet outages, as long as the queue drains in time.
Credit notes for returns and debit notes for adjustments mirror the parent type. A B2B return needs clearance, a B2C return needs reporting. Keep linkage via BillingReference to original invoice UUID and ICV.
3. Data model you must get right
UBL fields that break most integrations are invoice counter, timestamps, VAT math, and party data.
Invoice counter ICV must be sequential per EGS with no gaps. If clearance fails validation, do not increment. Retry the same ICV and UUID. If you void, issue a credit note rather than deleting. Auditors check gaps.
UUID must be unique version 4 per invoice. Timestamps need date plus time with seconds in Saudi time, and server clock must be NTP synced within minutes of ZATCA time. Drift causes rejection.
Seller block needs registered name in Arabic and English as in commercial registration, VAT number of 15 digits starting with 3, and address with national address fields where available. Buyer block for B2B needs buyer VAT and name. For B2C, buyer can be minimal.
VAT math is the top rejection cause. Calculate per line quantity times unit price minus discount, compute VAT per line at 15 percent or exemption reason, sum lines then round half-up to two decimals in SAR. Test edge cases like 115 inclusive equals 100 plus 15, multi-rate baskets, and zero-rated exports with reason codes. Rounding must match ZATCA schematron to the halala.
QR is TLV base64 with tags 1 seller name, 2 VAT number, 3 timestamp, 4 total with VAT, 5 VAT amount, 6 hash and signature for Phase 2. Tag order matters. Encoding must be UTF-8 for Arabic names.
4. EGS onboarding step by step
An EGS is each logical invoicing device or branch system. A SaaS with 10 branches needs 10 EGS units.
Step one is OTP from Fatoora portal. Admin logs in with VAT account, selects EGS onboarding, receives 6-digit OTP valid about one hour. Step two is CSR generation with secp256k1 elliptic key. Generate private key locally, create CSR with organization, VAT number, and EGS serial. Never commit private key to git.
Step three is compliance CSID. POST CSR plus OTP to compliance endpoint and receive binarySecurityToken and secret for sandbox testing. Step four is compliance checks. Submit three to six samples covering standard invoice, simplified invoice, standard credit, simplified credit, plus edge like discount and exemption. Fix warnings about BR-KSA rules before proceeding.
Step five is production PCSID. Call production issuance with compliance request ID and receive long-lived certificate. Store certificate plus key in vault such as AWS Secrets Manager or Azure Key Vault, or HSM for high volume. Step six is renewal and revocation. Track expiry in your ops dashboard and rotate before deadline. Revoke on device replacement.
Keep sandbox, simulation, and production credentials strictly separate. Developers often mix tokens and waste days debugging 401 errors.
5. Signing pipeline in code
Do not hand-roll XML. Use official ZATCA SDKs for Java, .NET, or JavaScript. Pipeline is map order model to UBL object, canonicalize, hash with SHA256, sign with ECDSA private key, embed signature and QR, then validate locally against XSD plus schematron.
In Node, flow is build UBL JSON, convert to XML string, run SDK sign function with cert and key paths, receive signed XML and hash and base64 QR. In .NET, use SDK invoice signing with certificate store. Always log the ZATCA rule code on failure, for example BR-KSA-08 for VAT mismatch or BR-S-08 for simplified buyer.
Performance matters. Signing is CPU heavy. For POS with 50 invoices per minute, pre-warm SDK, reuse key handles, and queue signing workers separately from API workers.
6. Clearance and reporting APIs
Clearance endpoint accepts invoice hash, UUID, and base64 signed invoice with PCSID bearer token. Success returns 200 with cleared invoice, ZATCA hash, and QR to print. Validation failure returns 400 with rule codes. Server error returns 500 and should be retried with same UUID.
Critical rule is idempotency. Network timeout does not mean rejection. Before resubmitting, query by hash. Duplicate ICV with different content triggers audit flags.
Reporting endpoint is similar but non-blocking. POS should store locally first, show customer QR instantly, then background report. Alert if queue age exceeds 12 hours, page if over 20 hours, since SLA is 24 hours.
Build a unified outbox table with columns for UUID, ICV, type, status queued or cleared or reported or failed, attempts, last error, and ZATCA response. A background worker drains it with exponential backoff and jitter.
7. PDF and UX for Saudi users
PDF must be PDF/A-3 with embedded XML, show Arabic and English seller names, VAT numbers for both parties on B2B, line VAT breakdown, totals, QR large enough to scan from phone, plus stamped badge after clearance. Include payment terms, CR number, and support phone. For B2C, keep one-page receipt style with big total in SAR.
8. Operations, monitoring, and audit
Monitor clearance success rate target above 99.5 percent, p95 latency, queue age, and cert expiry days. Dashboard per client with wave deadline countdown. Backup keys daily encrypted offsite and archive invoices six years per VAT law plus PDPL retention rules.
Common production incidents are clock drift after VM migration, ICV gaps after manual DB edits, QR unreadable due to low print contrast, and PCSID expiry on holidays. Runbooks should cover each with rollback to offline simplified mode where legally allowed.
9. Timelines and costs
Simple single-branch POS takes two to three weeks including sandbox and simulation. Multi-branch ERP with credit notes and exemptions takes six to ten weeks. SaaS multi-tenant with per-client EGS takes eight to twelve weeks plus wave support.
Budget for ZATCA portal Arabic-only steps, client VAT admin delays in providing OTP, and testing with real Saudi VAT numbers. Offer Fatoora as a paid compliance module with yearly maintenance for cert rotation and rule updates.
Treat Fatoora as infrastructure. Get onboarding, signing, and queuing right once, and every future Saudi client becomes a configuration task rather than a project.





