Build ZATCA FATOORAH (فاتورة) Phase 2 E-Invoice XML
Skill: Convert invoice data into a ZATCA FATOORAH Phase 2 UBL 2.1 e-invoice with QR
Region: Saudi Arabia (المملكة العربية السعودية) Category: E-Invoicing — FATOORAH (فاتورة), Phase 2 (Integration) Does: Takes ordinary invoice data and produces the FATOORAH Phase 2 e-invoice — a UBL 2.1 / EN 16931-based XML (Standard Tax Invoice or Simplified Tax Invoice) carrying the UUID, the previous-invoice hash (PIH), the cryptographic stamp, and the TLV base64 QR code, then cleared or reported through the ZATCA platform. Standard: ZATCA E-Invoicing (UBL 2.1, EN 16931 aligned)
Phase 2 is rolled out in waves: Standard Tax Invoices (B2B/B2G) are cleared (real-time clearance with ZATCA before issuance) while Simplified Tax Invoices (B2C) are reported within 24 hours. The seller's VAT registration number (15 digits) is required and VAT is 15%. The XML must carry the UUID, PIH (hash of the previous invoice, base64), the cryptographic stamp from the onboarded CSID, and a TLV-encoded QR. Validate against the current ZATCA XML Implementation Standard before submission.
When this applies
- You are a VAT-registered business in a Phase 2 (Integration) wave issuing Standard (B2B/B2G) or Simplified (B2C) tax invoices, plus credit notes (
383) and debit notes (381). - Standard invoices are submitted to the ZATCA Clearance API and must be cleared (returned stamped) before being handed to the buyer.
- Simplified invoices are stamped locally and submitted to the Reporting API within 24 hours; the QR must be present on the printed/PDF copy.
- Each invoice chains to the prior one via the PIH, forming a tamper-evident sequence per device/solution unit.
Input data required
| Input | Used for |
|---|---|
Invoice number, issue date/time, invoice type code (388) + subtype |
header, cbc:InvoiceTypeCode + name |
| Invoice counter value (ICV) and document UUID | cbc:UUID, KSA-16 ICV |
| Previous invoice hash (PIH, base64 SHA-256) | KSA-13 PIH |
| Seller VAT number (15 digits), name, address, CRN | AccountingSupplierParty |
| Buyer name, address, VAT/ID (Standard only) | AccountingCustomerParty |
Currency (SAR) |
DocumentCurrencyCode |
| Line items: name, quantity, net price, VAT category & rate | InvoiceLine |
| VAT breakdown per category (15% standard, 0%, exempt) | TaxTotal |
| Cryptographic stamp + QR | cac:Signature, AdditionalDocumentReference QR |
Namespaces and identifiers
| Prefix | URI |
|---|---|
| default | urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 |
cac |
urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2 |
cbc |
urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2 |
ext |
urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2 |
cbc:ProfileID=reporting:1.0cbc:InvoiceTypeCode=388withnameset to the 6-digit subtype (e.g.0100000Standard,0200000Simplified — first positions flag B2B/B2C, third-party, nominal, exports, summary, self-billed).
Document structure to emit
Invoice
├── ext:UBLExtensions (UBL digital signature / cryptographic stamp)
├── cbc:ProfileID (reporting:1.0)
├── cbc:ID (invoice number)
├── cbc:UUID (document UUID)
├── cbc:IssueDate / cbc:IssueTime
├── cbc:InvoiceTypeCode name="0100000" (388)
├── cbc:DocumentCurrencyCode (SAR) / cbc:TaxCurrencyCode (SAR)
├── cac:AdditionalDocumentReference ICV (KSA-16), PIH (KSA-13), QR (base64 TLV)
├── cac:AccountingSupplierParty (VAT no., CRN, address)
├── cac:AccountingCustomerParty (Standard only)
├── cac:Signature (cryptographic stamp reference)
├── cac:TaxTotal (TaxAmount + TaxSubtotal per category)
├── cac:LegalMonetaryTotal
└── cac:InvoiceLine ...
QR (TLV) tags
The QR is a base64-encoded TLV string; for cleared Standard invoices the cryptographic stamp/public-key tags are added by/after clearance:
| Tag | Value |
|---|---|
| 1 | Seller name |
| 2 | Seller VAT registration number |
| 3 | Invoice timestamp (ISO 8601) |
| 4 | Invoice total (with VAT) |
| 5 | VAT total |
| 6 | Hash of XML invoice |
| 7 | ECDSA signature |
| 8 | Public key |
| 9 | ZATCA stamp signature (cleared invoices) |
VAT category codes
| Code | Meaning | Rate |
|---|---|---|
S |
Standard rate | 15% |
Z |
Zero-rated (e.g. exports, qualifying supplies) | 0% |
E |
Exempt | — |
O |
Out of scope | — |
Calculation rules
- SAR uses 2 decimal places (halalas).
- Line net = quantity × net unit price (
cbc:LineExtensionAmount). - Group lines by VAT category + rate →
TaxSubtotal:TaxableAmount= Σ nets;TaxAmount= taxable × rate (15% standard). cac:TaxTotal/cbc:TaxAmount= Σ subtotal VAT; a secondTaxTotal(no subtotals) carries the rounded total inTaxCurrencyCode.TaxInclusiveAmount=TaxExclusiveAmount+ VAT;PayableAmount= inclusive − prepaid.- PIH: for the first invoice of a chain use the base64 of
0(NWZlY2ViNjZmZmM4NmYzOGQ5NTI3ODZjNmQ2OTZj79...is the SHA-256 of "0"); thereafter the base64 SHA-256 of the previous signed XML. - ICV increments by 1 per invoice per solution unit.
Worked example (Simplified, single 15% line)
<?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>INV-2026-000123</cbc:ID>
<cbc:UUID>3cf5ee18-ee25-44ea-a444-2c37ba7f28be</cbc:UUID>
<cbc:IssueDate>2026-06-04</cbc:IssueDate>
<cbc:IssueTime>10:15:00</cbc:IssueTime>
<cbc:InvoiceTypeCode name="0200000">388</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>SAR</cbc:DocumentCurrencyCode>
<cbc:TaxCurrencyCode>SAR</cbc:TaxCurrencyCode>
<cac:AdditionalDocumentReference>
<cbc:ID>ICV</cbc:ID><cbc:UUID>123</cbc:UUID>
</cac:AdditionalDocumentReference>
<cac:AdditionalDocumentReference>
<cbc:ID>PIH</cbc:ID>
<cac:Attachment><cbc:EmbeddedDocumentBinaryObject mimeCode="text/plain">NWZlY2ViNjZmZmM4NmYzOGQ5NTI3ODZjNmQ2OTZjOWM3MjEyNzM0M2JlYjEyMzQ1Njc4OTBhYmNkZWY=</cbc:EmbeddedDocumentBinaryObject></cac:Attachment>
</cac:AdditionalDocumentReference>
<cac:AdditionalDocumentReference>
<cbc:ID>QR</cbc:ID>
<cac:Attachment><cbc:EmbeddedDocumentBinaryObject mimeCode="text/plain">ARRTYWxsYSBUcmFkaW5nIENvLgIPMzAxMTIyMzM0NDAwMDAzAxQyMDI2LTA2LTA0VDEwOjE1OjAwWgQHMTE1MDAuMDAFBjE1MDAuMDA=</cbc:EmbeddedDocumentBinaryObject></cac:Attachment>
</cac:AdditionalDocumentReference>
<cac:AccountingSupplierParty><cac:Party>
<cac:PartyIdentification><cbc:ID schemeID="CRN">1010101010</cbc:ID></cac:PartyIdentification>
<cac:PostalAddress><cbc:StreetName>King Fahd Rd</cbc:StreetName><cbc:CityName>Riyadh</cbc:CityName><cbc:PostalZone>12211</cbc:PostalZone><cac:Country><cbc:IdentificationCode>SA</cbc:IdentificationCode></cac:Country></cac:PostalAddress>
<cac:PartyTaxScheme><cbc:CompanyID>301122334400003</cbc:CompanyID><cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme></cac:PartyTaxScheme>
<cac:PartyLegalEntity><cbc:RegistrationName>Salla Trading Co.</cbc:RegistrationName></cac:PartyLegalEntity>
</cac:Party></cac:AccountingSupplierParty>
<cac:AccountingCustomerParty><cac:Party>
<cac:PartyLegalEntity><cbc:RegistrationName>Walk-in customer</cbc:RegistrationName></cac:PartyLegalEntity>
</cac:Party></cac:AccountingCustomerParty>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="SAR">1500.00</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="SAR">10000.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="SAR">1500.00</cbc:TaxAmount>
<cac:TaxCategory><cbc:ID>S</cbc:ID><cbc:Percent>15</cbc:Percent><cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme></cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>
<cac:TaxTotal><cbc:TaxAmount currencyID="SAR">1500.00</cbc:TaxAmount></cac:TaxTotal>
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="SAR">10000.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="SAR">10000.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="SAR">11500.00</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="SAR">11500.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="PCE">10</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="SAR">10000.00</cbc:LineExtensionAmount>
<cac:TaxTotal><cbc:TaxAmount currencyID="SAR">1500.00</cbc:TaxAmount><cbc:RoundingAmount currencyID="SAR">11500.00</cbc:RoundingAmount></cac:TaxTotal>
<cac:Item><cbc:Name>Office chair</cbc:Name>
<cac:ClassifiedTaxCategory><cbc:ID>S</cbc:ID><cbc:Percent>15</cbc:Percent><cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme></cac:ClassifiedTaxCategory>
</cac:Item>
<cac:Price><cbc:PriceAmount currencyID="SAR">1000.00</cbc:PriceAmount></cac:Price>
</cac:InvoiceLine>
</Invoice>
Validation checklist
-
cbc:ProfileID=reporting:1.0;InvoiceTypeCode388with correct 6-digit subtypename -
cbc:UUIDpresent and unique; ICV increments per solution unit - PIH carries the base64 hash of the previous invoice (base64 of "0"-hash for the first)
- Seller VAT number (15 digits) and CRN present; buyer details for Standard invoices
- Currency
SAR, amounts to 2 decimals; VAT category + rate per line (15% standard) -
TaxSubtotalper category reconciles with line nets;TaxInclusiveAmount= exclusive + VAT - Cryptographic stamp embedded (
UBLExtensions/cac:Signature); QR is base64 TLV with all required tags - Standard invoices cleared via the ZATCA Clearance API before issuance; Simplified reported within 24h
- Passes the ZATCA validation rules (EN 16931 / KSA business rules) before submission
Last updated: 2026-06-04 — confirm the active schema version, field codes, and ZATCA requirements against the current Zakat, Tax and Customs Authority specifications before use.