Saudi Arabia ZATCA Simplified Tax Invoice (UBL)
Saudi e-invoice: ZATCA simplified tax invoice (FATOORA, UBL)
A Saudi simplified tax invoice (B2C) for FATOORA, checked against the UBL 2.1 schema and the EN 16931 and KSA rules of ZATCA's SDK.
About
A simplified tax invoice is usually issued by a business to a consumer. It has InvoiceTypeCode 388 (381, 383 or 386 for credit and debit notes and prepayments) with a name starting 02, and is submitted to ZATCA within 24 hours of its issue.
ZATCA validates it against the UBL schema, a subset of the EN 16931 rules and the KSA rules (BR-KSA-*). For simplified invoices these require a cryptographic stamp (BR-KSA-60), and for every invoice a QR code and the hash of the previous invoice.
E-invoicing in Saudi Arabia: the rules in short and how to check an invoice →
Good to know
- Rules run only when the document matches the schema. Documents over 50 MB are checked against the schema only.
- The rules are the two stylesheets of ZATCA's SDK 3.4.6: its copy of the EN 16931 rules and the KSA rules, both under the LGPL.
- BR-KSA-98 warns when a simplified invoice is more than 24 hours old, measured against the time of the check: it shows on the example, which dates from 2022.
- The schema is UBL 2.1 with one change: the certificate serial number in the signature (X509SerialNumber) is read as an integer of any length, as libxml2 reads integers of up to 24 digits only.
- The example is the simplified tax invoice of ZATCA's SDK 3.4.6, as phive-rules keeps the SDK's samples.
Files
14 files · 2.7 MB · Download all (.zip)-
maindoc/UBL-Invoice-2.1.xsd main
-
common/UBL-CommonAggregateComponents-2.1.xsd
-
common/UBL-CommonBasicComponents-2.1.xsd
-
common/UBL-CommonExtensionComponents-2.1.xsd
-
common/UBL-QualifiedDataTypes-2.1.xsd
-
common/UBL-UnqualifiedDataTypes-2.1.xsd
-
common/UBL-ExtensionContentDataType-2.1.xsd
-
common/CCTS_CCT_SchemaModule-2.1.xsd
-
common/UBL-CommonSignatureComponents-2.1.xsd
-
common/UBL-SignatureAggregateComponents-2.1.xsd
-
common/UBL-SignatureBasicComponents-2.1.xsd
-
common/UBL-xmldsig-core-schema-2.1.xsd
-
common/UBL-XAdESv132-2.1.xsd
-
common/UBL-XAdESv141-2.1.xsd
The validator loads all of these with their folder structure, so includes and imports resolve as published.
Business rules
Schematron · run in this order-
ZATCA e-invoicing rules (Saudi Arabia) SDK 3.4.6
The rules run after the schema check, only when the document matches the schema, and in your browser like the schema check (with SaxonJS by Saxonica). Each finding names its rule, such as BR-CO-15, and the line it points at; each rule has a page with what it checks.
Example document
sa-zatca-simplified-invoice.xml · 14 KB · passes the schema and the rules
In CI and from code
The same schema by its name, sa-zatca-simplified-invoice, through the API.
npx @xmlvalid/cli validate "**/*.xml" --schema sa-zatca-simplified-invoice
- uses: xmlvalid/validate-action@v1
with:
files: "**/*.xml"
schema: sa-zatca-simplified-invoice
api-key: ${{ secrets.XMLVALID_API_KEY }}
curl https://xmlvalid.com/api/v1/validations \
-H "Authorization: Bearer $XMLVALID_API_KEY" \
-F document=@sa-zatca-simplified-invoice.xml \
-F schema=sa-zatca-simplified-invoice
Free accounts get 100 API validations a month. On Pro, a URL monitor can check a published document against this schema every hour and email you when it breaks. More CI setups