When building a system that issues Phase Two-compliant electronic invoices in Saudi Arabia, it is not enough for the XML file to be structurally valid. It must also be logically and arithmetically correct. This is where the Validation Rules enforced by the Zakat, Tax and Customs Authority (ZATCA) come in. These rules are known as Business Rules and carry a unified prefix: BR-KSA BR-KSA in the Saudi requirements, and the prefix BR in the rules of the core European standard on which they are built.
Many developers confuse two distinct layers of validation: structural validation via the XSD schema, and logical validation via business rules. The first layer answers the question «is the structure sound?», and the second answers «is the content logical and correct?». This guide focuses entirely on the second layer: what business rules are, how they are written, their most common codes and error messages, and how your system passes them before the invoice reaches the Fatoora platform.
For a deep dive into the structural layer, see our dedicated guide on the Invoice Schema and its validation. Here we assume the invoice has already passed schema validation, and we build on top of that.
What exactly is the difference between schema validation and business rules?
Separating the two layers is not an academic detail. Each layer operates at a different level of the invoice, catches a different kind of error, and issues error messages with different wording. Understanding this separation determines where you place validation logic in your system.
Schema Validation relies on the XSD file. Its job is to inspect the document structure: are the elements present? Is their order correct? Does the data type in each field match (text, number, date)? Is the value within the allowed closed list? XSD does not understand the accounting meaning of the numbers. If you write a negative tax amount in a valid decimal format, it will pass XSD because it is a structurally sound «decimal number».
Business Rules Validation operates at the level of meaning. It takes the values that passed the schema and checks their logical relationships: does the sum of the lines equal the invoice total? Does the tax value equal the taxable base multiplied by the rate? Is the field that becomes mandatory for a specific tax category actually present? These are questions XSD cannot answer because they require calculation and comparison across multiple fields.
The bottom line in one sentence: the schema guarantees that the invoice is written correctly, and business rules guarantee that it is actually correct. An invoice may be written perfectly and still carry an arithmetic error that makes it rejected.
A quick comparison table between the two layers
This table summarizes the practical difference that matters to a developer when designing the validation pipeline in the system.
| Criterion | Schema Validation (XSD) | Business Rules Validation (BR-KSA) |
|---|---|---|
| Question | Is the structure valid? | Is the content logical and correct? |
| Tool | XSD file and XML parser | Rules engine (Schematron or programmatic logic) |
| Scope | One field at a time | Relationships across multiple fields |
| Example of what it catches | Missing element, wrong data type | Sum does not match, tax calculated incorrectly |
| Error code prefix | No unified code (parser message) | BR-KSA-XX or BR-CO-XX |
| Execution order | First | After passing the schema |
Where do business rules come from? Two complementary sources
The validation rules the Authority applies are not a random list. They come from two sources that work together, and your system must comply with both.
The first source is the European standard EN 16931 which defines the core semantic model of the electronic invoice. This standard carries a set of general rules with codes starting with BR BR- for core rules,BR-CO- for calculation (arithmetic consistency) rules,BR-S- for standard tax category rules,BR-Z- for the zero-rated category,BR-E- for the exempt category. The Saudi invoice is built on this foundation through the UBL 2.1.
The second source is the Kingdom-specific rules the Authority adds on top of the European standard, carrying the prefix BR-KSA. These rules address local requirements such as the format of the Saudi VAT registration number, the signature and stamp fields in Phase Two, QR code rules, invoice type, and identity fields specific to the Saudi market. BR-KSA-. These rules address local requirements such as the format of the Saudi VAT registration number, the signature and stamp fields in Phase Two, QR code rules, invoice type, and identity fields specific to the Saudi market.
When the Authority’s system rejects an invoice, the rejection usually comes accompanied by a rule code from one of these two sources. Your system’s job is to apply both rules internally, so the invoice does not reach the platform carrying an error that could have been caught locally.
BR: core rules (EN 16931)
BR-CO: calculation and totals rules
BR-S/Z/E: tax category rules
BR-KSA: the Authority’s Saudi-specific rules
The five core types of validation rules
Business rules are numerous, but they logically fall into five families. Understanding the family before the individual rule makes reading error messages faster, and helps you build a structured validation engine instead of a scattered list of conditions.
1. Conditional Mandatory rules
These rules make a specific field mandatory only when a certain condition is met. The field is optional in the general case, but becomes required when a specific value appears in another field.
The most common example: the tax exemption reason field. This field is not required in an ordinary invoice, but becomes mandatory the moment the tax category of one of the lines becomes «exempt» or «out of scope». The rule states: «if the tax category code equals E (exempt), then the exemption reason text must be present».
2. Calculation rules
This is the most important family and the one that causes the most rejections. It verifies that the totals are consistent across the invoice. It usually carries the prefix BR-CO BR-CO- in the European standard.
The logic is simple but strict: the sum of the line amounts must equal the invoice total before tax, the sum of the tax amounts per category must equal the total tax, and the total amount due must equal the total before tax plus tax minus any prepayments.
The most common error we see here is a rounding difference. If you round each line individually and then sum, you may get a total that differs by one halalah from the result the Authority expects. The rule usually allows a small rounding tolerance (often SAR 0.01), but exceeding this tolerance means an immediate rejection.
Let us clarify with a numeric example. Suppose an invoice with two lines: the first worth SAR 33.33 and the second worth SAR 33.34, both subject to the standard 15% rate. The tax on the first line is SAR 5.00 after rounding, and the tax on the second line is SAR 5.00 after rounding, so the total tax at the line level is SAR 10.00. But if you calculate the tax on the aggregate base of SAR 66.67 directly, you get SAR 10.0005, which rounds to SAR 10.00. Here they matched by coincidence. Change the values slightly and you will find a deviation that exceeds the tolerance. The lesson: calculate the tax at the aggregated category level, not at the individual line level, as this is what rule BR-CO-17 expects.
A second point that is often overlooked: the data type in the code. Using a floating-point (float) type in amount calculations introduces subtle precision errors that accumulate across dozens of lines. Use a precise decimal type (decimal or its equivalent in your language), and specify the number of decimal places explicitly at the final rounding. This alone eliminates a large proportion of BR-CO rejection cases.
3. Format rules
These rules verify that the field value follows a specific pattern. They differ from XSD rules because they may include logic XSD cannot express, such as a check-digit algorithm for a number.
The classic Saudi example is the VAT registration number. The rule is not content with it being a 15-digit text; it also requires that it starts with the digit 3 and ends with the digit 3, and that the digit just before the end is a valid branch code.
4. Date & Sequence rules
These verify the logical consistency of dates and invoice sequencing. The supply date must not be after the issue date by an unjustified margin, the payment due date must not precede the issue date, and the invoice counter must increment without gaps.
In Phase Two an additional dimension enters: linking the invoice to its predecessor via the unique identifier UUID and the hash of the previous invoice. Any break in this chain is caught here.
5. Code List rules
These verify that the field value belongs to an approved list of values. The currency code must be from the ISO 4217 list, the invoice type code must be from the list defined by the Authority (388 for a tax invoice, 383 for a debit note, 381 for a credit note), and the tax category code must be from the approved set (S, Z, E, O).
This family partially overlaps with XSD because the schema itself enforces some closed lists. But business rules add logic on top of it, such as linking the category code to the appropriate reason code.
Invoices that pass every validation rule without writing a single line of logic
Business rule and calculation constraints are applied locally before sending, so your invoice does not reach the Fatoora platform until it is free of BR errors. You issue the invoice, and we handle the rules.
Start your free trial and issue invoices free of validation errors
Practical examples of business rule codes and their error messages
The real benefit for the developer lies in knowing the code and its message together. When the Authority’s system rejects an invoice, the response comes as an array of errors, each error carrying a rule code and a message. The following table gathers the most common rules that appear in the Saudi production environment with an explanation of each.
| Code | Meaning | When it appears |
|---|---|---|
BR-CO-15 |
Total amount due does not match the equation | Total with tax ≠ total without tax + tax |
BR-CO-17 |
Tax value per category is incorrect | Tax value ≠ base × rate (outside the rounding tolerance) |
BR-S-08 |
The base subject to the standard category is zero or negative | Standard category S without a positive base |
BR-KSA-39 |
The seller’s VAT number has an incorrect format | Wrong length or pattern of the VAT number |
BR-KSA-EN16931 |
Conflict with a core standard rule | A Saudi value breaks an original EN 16931 rule |
BR-KSA-15 |
Invoice type is inconsistent with the content | The invoice type code does not match the attached fields |
How do you read a business rule error message?
The error message from the Fatoora platform comes in a structured format. Let us take a real example of a response to an invoice with an arithmetic error:
Read it from top to bottom. status tells you the invoice was rejected. code is the code of the broken rule, and it is your key to search the Authority’s rules document. category classifies the rule (here an arithmetic BR rule). message explains the rule as an equation statement. The fix here is clear: recalculate the total amount due so that it equals the base plus tax exactly.
status: validation status (rejected/warning)
code: rule code (e.g. BR-KSA-…)
category: error category
message: description of the error and how to correct it
How does your system pass validation rules programmatically?
The practical goal is not to rely on the platform’s rejection to discover your errors. A good system applies business rules locally before sending, saving network round trips and avoiding clearance delay. The Authority publishes its rules in Schematron format, which is machine-runnable and an extension of XPath that describes a rule as a logical expression on the XML tree.
A simplified Schematron expression for a calculation rule looks like this:
If you do not use a ready Schematron engine, you can translate the same logic into a function in your language. The important thing is to apply the same rounding tolerance the Authority applies:
The correct execution order in the issuance pipeline: issue the XML, validate the schema first, and if it passes run the business rules, and if they pass sign and send to the platform. Any rule you break locally stops the invoice before it touches the network.
Where do validation rules fall in the invoice journey?
In a clearance invoice (B2B), the Authority’s system applies business rules before it issues the clearance certificate. The invoice is not considered valid for delivery until it passes them. See Clearance in electronic invoicing for the details of this journey.
In a simplified invoice (B2C), the invoice is delivered to the customer immediately, then reported to the Authority within 24 hours, at which point the business rules are applied. This means a rule error in a B2C invoice may be discovered after it has been delivered to the customer, which makes local pre-validation even more important. See Reporting in electronic invoicing to understand this cycle.
The most common business rule errors and how to avoid them
From the reality of the Saudi production environment, most rejection cases concentrate in a limited number of rules. Knowing them in advance saves you hours of debugging.
1. Rounding difference in calculation
The most frequent cause of rejection by far. It arises when you round at the line level then sum, or when you use a floating-point (float) data type that loses precision. The solution: use a precise decimal (decimal) type in all operations, apply rounding at the end of the chain rather than in the middle, and adhere to the SAR 0.01 tolerance.
2. Missing conditional field
This happens when the tax category is exempt or zero-rated without attaching the exemption reason, or when the invoice is simplified without a QR code. The solution: link the mandatory logic to the category programmatically, so the field is enforced automatically when its condition appears.
3. VAT number in the wrong format
The number does not start with 3, or does not end with it, or is not 15 digits. The solution: apply the pattern check ^3[0-9]{13}3$ when entering the establishment’s data, not when issuing the invoice.
4. Tax category code that does not match the rate
Such as placing a standard category S with a zero rate, or a zero-rated category Z with a 15% rate. The solution: link the rate to the category code in a single data layer that does not allow a conflict.
The unifying principle behind all these errors is one: do not wait for the platform’s rejection. Build local validation so it catches the error at the moment of entry or issuance, because a rule caught locally costs a second, while a rule caught at clearance costs a network round trip and re-issuance.
Rounding difference in totals
Missing mandatory conditional field
Incorrect VAT number for the buyer
Tax category not matching the rate
Tax category rules: where logic meets Saudi tax
A special family of business rules deserves a pause because it is a frequent source of rejection: the tax category rules. Every line in the invoice carries a tax category code, and every code drags behind it a set of strict rules linking the rate to the base to the reason. The four categories approved in Saudi Arabia are: standard (S) at 15%, zero-rated (Z) at 0%, exempt (E), and out of scope (O).
The first rule is that the rate must match the category. The standard category S accepts only a 15% rate in the ordinary context, and the zero-rated category Z requires a rate of exactly 0%. If you place a line with code S and a 0% rate, the system rejects the invoice because the code and the rate conflict. This rule carries codes such as BR-S-05 and BR-Z-05 in the European standard.
The second rule is that the zero-rated, exempt, and out-of-scope categories require an exemption reason. It is not enough to set the rate to zero; you must attach the reason text and its code from the approved reason list. An invoice carrying an exempt line without a reason is rejected by rule BR-E-10 or its equivalent. The reason is that the Authority needs documentation of the exemption cause for audit purposes.
The third rule is that the base sum per category must equal the sum of the bases of the lines belonging to that category. If you have three standard lines, the standard base at the invoice level must equal the sum of the bases of these three lines exactly. This is a calculation rule that overlaps with the calculation family, and carries a code such as BR-CO-18.
The smart developer builds a single lookup table linking each category code to its allowed rate and to whether an exemption reason is mandatory. When the user enters a line, the rest is filled automatically from this table, so it becomes practically impossible to produce a conflict between the code, the rate, and the reason. This method extinguishes three families of BR errors at once before the invoice reaches the network.
Why did the Authority separate business rules from the schema?
You might wonder: why not merge all the rules into a single XSD file? The reason is that each layer has a different nature. The schema is structural, stable, and rarely changes, describing the shape of the document. Business rules are logical and may change with tax policy updates, such as adjusting a rate or adding a new exemption reason. Separating them lets the Authority update business rules without touching the document structure, and lets systems run the two layers with different, specialized tools. Furthermore, the XSD language is inherently incapable of expressing calculation and comparison across multiple fields, which is the essence of business rules.
How Qoyod handles the validation rules layer on your behalf
If you use Qoyod’s electronic invoicing software, the business rules layer is built into the issuance pipeline. Qoyod handles generating the invoice XML within the correct electronic invoice structure , then applies the calculation, format, and conditional-existence rules before signing and sending.
In practice, this means you do not write a Schematron expression, nor a validation function, nor deal with the rounding tolerance. You enter the invoice data, and Qoyod handles calculating the totals with decimal precision, enforcing the conditional fields per tax category, verifying the VAT number format, and setting the invoice type. The invoice does not leave the system toward the Fatoora platform until it is free of the known BR errors.
This layer complements the schema layer: Qoyod ensures the invoice is structurally sound (XSD) and logically sound (BR-KSA) together, so it reaches clearance ready to be accepted on the first attempt.
Where do you go after this guide?
Validation rules are the logical layer on top of the structure. To complete the technical picture:
- Invoice Schema and its validation: the structural layer via XSD that precedes business rules.
- UBL 2.1 standard: the foundation on which the European and Saudi standard rules are built.
- electronic invoice structure: the fields that validation rules operate on.
- Clearance: where business rules are applied to B2B invoices.
Frequently asked questions
What is the difference between Validation Rules and Schema Validation?
Schema Validation checks the structure via XSD: are the fields present, with correct data types and proper order. Validation Rules (business rules) check the logic: are the totals consistent, is the tax calculated correctly, and are the conditional fields present. The former precedes the latter in the execution pipeline.
What does the BR-KSA prefix in an error code mean?
BR is short for Business Rule, and KSA refers to the Kingdom-specific rules the Authority adds on top of the European standard EN 16931. Codes starting with BR-CO relate to calculation (arithmetic consistency), and BR-S, BR-Z, and BR-E relate to the standard, zero-rated, and exempt tax categories.
Which rule causes invoice rejection the most?
The calculation rules, specifically BR-CO-15 and BR-CO-17, because of rounding differences. When you sum lines rounded individually, the total may deviate by a halalah from the expected result. The solution is to use a precise decimal type and apply rounding only at the end of the chain.
Does passing schema validation mean passing business rules?
No. An invoice may be perfectly structured (passing XSD) and still carry a logical error such as a sum that does not match or tax calculated incorrectly. The two layers are independent, and both must be passed together.
Do I need to write Schematron rules myself?
If you build your system from scratch, yes, either by running the Schematron files the Authority publishes or by translating their logic into functions. If you use a compliant software such as Qoyod, the layer is built in and you do not need to write any rule.
When are validation rules applied to a simplified B2C invoice?
The simplified invoice is delivered to the customer immediately, then reported to the Authority within 24 hours, at which point the business rules are applied. Therefore it is strongly recommended to apply validation locally before delivery, so errors are not discovered after the invoice reaches the customer.