Skip to content
AIMOCS

AIMOCS · Stack guides

Stack guide

ZATCA Phase 2 + Claude agent — the production stack for compliant e-invoicing

Connecting a Claude agent to Saudi Arabia's Fatoora portal sounds straightforward until you realise the LLM cannot generate the cryptographic stamp. This is the stack we wire around Claude so it does the natural-language work and the deterministic compliance layer does its job.

The stack

  • Anthropic Claude
  • Glama
  • Vercel
  • Supabase
  • Docker
  • MongoDB

Updated · 2026-05-30

01TL;DR
02The stack
  • L/01Intent + data extraction

    Claude takes natural-language input (a chat from WhatsApp, a voice request, a free-form order) and produces structured invoice data: customer ID, line items, totals, VAT, payment method. The LLM never writes the signed XML directly.

    • Anthropic Claude
  • L/02Tool gateway

    Glama exposes the POS, ERP, and customer-master tools to Claude over MCP. The agent reads product prices, looks up customer VAT numbers, and writes back order state through one uniform tool surface.

    • Glama
  • L/03EGS unit — the signing layer

    The Electronic Generation Solution is a Node.js (or any language) service running in a Docker container, deployable to Vercel or in-kingdom infra. It receives structured invoice data, generates UBL 2.1 XML deterministically, applies SHA-256 + ECDSA-P256 signature with the CSID private key, and POSTs to Fatoora clearance.

    • Docker
    • Vercel
  • L/04Per-merchant state

    Supabase stores per-EGS state: CSID certificate, onboarding step (OTP, compliance, prod-CSID), Fatoora portal URLs, last cleared UUID. One row per branch / EGS unit.

    • Supabase
  • L/05Immutable audit log

    MongoDB carries every invoice's full lifecycle: original input, extracted structured data, generated XML, hash, ZATCA response, any retries. Append-only. This is what auditors and ZATCA themselves ask for if a dispute lands.

    • MongoDB
03Why this stack

The LLM is not in the cryptographic path

The single most common Phase-2 failure we see is people trying to make Claude generate the signed XML directly. The signature must be deterministic and verifiable. Splitting the agent from the signer is the architectural decision that lets you ship.

One EGS per branch

ZATCA requires a separate CSID for each Electronic Generation Solution unit. A five-branch restaurant needs five EGS instances, five onboardings, five keychains. This is non-negotiable; bake it into the data model on day one.

Clearance, not reporting

B2B invoices use the clearance mode: every invoice is cleared by ZATCA before it can be issued. No batching. Build for synchronous response handling and graceful 5xx retries. B2C reports asynchronously within 24 hours — different code path.

Append-only logs are evidence

If a customer disputes a Fatoora-cleared invoice or ZATCA queries a flagged submission, the MongoDB audit log is the evidence. Mutability of any log entry breaks the chain.

04Where it shines
  • ◇/01

    WhatsApp ordering for restaurants where the order-to-invoice pipeline must be Phase-2-compliant from day one.

  • ◇/02

    Multi-branch retail and hospitality where each location is a separate EGS unit and CSID.

  • ◇/03

    B2B services (legal, agencies, consultancies) where the invoice flow can be initiated from email or chat.

  • ◇/04

    SME accounting systems extending a legacy invoicing flow with conversational input.

  • ◇/05

    Wave 24 SMEs (SAR 375K threshold) facing the 30 June 2026 integration deadline.

05Comparison

Claude agent + dedicated EGS unit (this stack)

Pros

  • · LLM does the natural-language work it is good at; signing is deterministic and verifiable.
  • · EGS can be redeployed without retraining or re-prompting the agent.
  • · Audit trail is one append-only log across LLM + crypto layers.
  • · Adds a Phase-2-compliant invoicing pipeline to existing ERPs without ripping them out.

Cons

  • · Two services to operate (agent + EGS) rather than one.
  • · CSID onboarding is a manual step per branch — cannot be fully automated by the agent.

LLM-only (Claude writes signed XML directly)

Pros

  • · Simpler architecture on paper.

Cons

  • · Fails ZATCA verification immediately — LLM output is non-deterministic, signatures are not reproducible.
  • · No way to audit which XML was actually signed versus what the LLM claimed.
  • · A single hallucinated invoice line item creates a regulatory liability.

ERP-native ZATCA module (SAP, Odoo, Foodics built-ins)

Pros

  • · Vendor handles certificate renewal and spec updates.
  • · No custom code to maintain.

Cons

  • · Locked into the ERP — adding an agent surface (WhatsApp, voice) requires bridging back through the ERP.
  • · Limited control over the customer-facing flow.
  • · Often a per-branch licensing surcharge.

Third-party "ZATCA-as-a-service" middleware

Pros

  • · Offloads certificate management.
  • · Fast initial setup.

Cons

  • · Adds a third party to the cryptographic chain — every invoice transits a vendor server.
  • · PDPL implications if customer data crosses the border.
  • · Ongoing per-invoice cost.
06Implementation notes
  1. 01

    Always run the EGS unit in the same timezone as ZATCA (Asia/Riyadh) or your signature timestamps will drift outside the accepted window.

  2. 02

    The CSID has an expiry — schedule the renewal flow before the first onboarding, not after the first 90 days.

  3. 03

    Fatoora sandbox URL is different from production. Keep them in environment variables, not hardcoded. We have seen production CSIDs sent to the sandbox by accident more than once.

  4. 04

    When Fatoora returns a 5xx, exponential backoff with a hard cap. Repeated retries on the same invoice with the same UUID can land you in a quarantine state with the portal.

  5. 05

    For Wave 24 SMEs (SAR 375K revenue threshold, deadline 30 June 2026), prioritise the simplest possible EGS — one branch, one CSID, one Docker container — over a polished agent surface. The deadline is the constraint, not the agent.

07Related
08Questions
  • Can the Claude agent generate the cryptographic signature?

    No. The signature must be deterministic and verifiable; an LLM is non-deterministic by design. The agent gathers data and structures the invoice; a separate signing service (the EGS) computes the hash and signs with the CSID private key. ZATCA's spec assumes this separation.

  • Do we need a separate CSID per branch?

    Yes. Each Electronic Generation Solution unit gets its own CSID. A five-branch restaurant means five OTP onboardings, five compliance CSIDs, five production CSIDs. Build the multi-EGS model into your data layer on day one.

  • Which AI providers can we use under Saudi PDPL?

    Providers with in-kingdom data residency are straightforward. For Anthropic via the public API, route only structured, non-PII fields through Claude and keep customer names and identifying detail in your in-kingdom database. The signing pipeline never sees prompt-style data.

  • What is the test environment URL?

    ZATCA provides a sandbox at sandbox.zatca.gov.sa/fatoora/onboarding. The production switch happens after a clearance test from your CSID is approved. Sandbox and production CSIDs are distinct certificates — keep them in separate keychains.

  • Can we batch invoices?

    No clearance batching for B2B invoices — each one must be cleared individually before it can be issued. B2C invoices can be reported asynchronously in batches up to 24 hours later. Plan for two code paths.

  • What happens if Fatoora rejects an invoice?

    ZATCA returns a structured error. The agent should not auto-retry — surface to a human. Common rejections (invalid VAT number, missing commercial registration, hash mismatch) need correction at the data source, not a retry of the same payload.

  • How does Phase 2 differ from Phase 1?

    Phase 1 (Generation) required electronic invoices with QR codes and could be issued offline. Phase 2 (Integration) requires real-time clearance from the Fatoora portal via API. Phase 2 means always-online — design for graceful handling of clearance latency.

  • What is the smallest ZATCA-compliant stack?

    For a single-branch SME: one Node.js EGS service running in Docker, one CSID, one Claude tool definition. Ongoing cost is dominated by the CSID renewal and minimal infra — well under SAR 500 a month. The compliance pipeline works without an agent; adding the agent is what makes the customer-facing surface conversational.

09Begin

We don't advise on AI. We run it for you.

Book a consultation

Proven on your data before you commit.