🧾 ZATCA e-invoice
Updated
← Business process wiki
The Saudi e-invoice is not an HTTP button on a realization. The KSA package
creates a TaxDocument envelope and assembles everything Saudi itself: the
XML, the hash, the QR, the request headers, the channel addresses. Three things
stay with the host because they cannot live in a script: the wire (the
queue and the synchronous call by channel name), the key (signing without
handing out a PEM) and the atomic ICV/PIH counter
(IKeyedCounterService).
User: how to fill in the legal entity and the address. Developer: the PDFs, the contours, the ICV. The package: KSA localization. Reference: 21-SaudiArabia.
How it works#
- A buyer with VAT means Standard, without VAT means Simplified; Cleared and
Reported come only from the channel's answer, never from a mock. The
ApplyFatooraOutcomesjob pulls the statuses every minute. - The seller's VAT lives on
LegalEntityseparately from the CRN (a KSA package extension). - Country and district on
Address— the common address, not a KSA field in Core. - The ICV counter on the envelope, per legal entity, including rejected ones —
atomic through the keyed counter service (
zatca-icv), notmax+1over the documents. - A draft UBL 2.1 in
TaxDocument.Payload(the QR is embedded; XAdES when there is a PEM CSID); thefatoora-clearanceandfatoora-reportingqueues (a stub on the stand). The hash is C14N 1.0 minus the signature and the QR, computed by the KSA package. The QR always carries tags 1–6; 7–9 need a PEM CSID, and the host does the signing. After release the envelope is Issued; Cleared and Reported come from the channel's answer (ApplyChannelOutcomesAsync). - A credit note is stamped the same way as an invoice (QR, UUID, hash), in the after-post event.
- A debit note (
SalesDebitNote) is for additional VAT charges, not a copy of the invoice lines; UBL 383, the same stamp in the after-post event. - Credit and debit notes reference the original invoice in the UBL
(
BillingReferenceID and UUID) and carry an instruction note. - CSR, OTP → Compliance CSID, the six sample kinds
(
/api/rest/ZatcaComplianceSamples), then the Production CSID — web services of the KSA model, dev-only and requiring an explicit Execute grant. The secret lives in the integration credentials, not in git. - The UBL categories: STANDARD→S, ZERO_RATED→Z, EXEMPT→E, OUT_OF_SCOPE→O. E and
O take the reason code and text from the
TaxCategory.LocalizationSaudiArabiaextension. A zero rate with no treatment is still Z. - A Standard invoice cannot be handed to the buyer until the
TaxDocumentis Cleared (ISaudiEInvoice.BuyerReleaseBlockAsync;InvoiceZr,CreditNoteZrandDebitNoteZrcallIEInvoiceRelease, and the Saudi package wraps it; ZATCA print forms call the check directly). A Simplified one is released as soon as it is Issued.
What's not there yet#
- CI does not run against live
gw-fatoora; the stand path uses the Fatoora stub. - Credit and debit notes carry one VAT category for the whole note; invoices support mixed rates per line (see Saudi Arabia).
- Full schematron validation and C14N 1.1 against live Fatoora are not in the product.
Same topic for other readers: User · Developer
Where next#
Was this page helpful?