BR-CO-12Sum of document-level charges is missing

Mutabiq checks Saudi ZATCA Phase 2 e-invoice XML before you submit it: pre-validation against published ZATCA requirements, not an approval by the authority. This page explains one rule, BR-CO-12.

Validate 5 invoices free

Five checks a month on the Free plan. The file is checked in memory and is never stored.

The message ZATCA prints

[BR-CO-12]-Sum of charges on document level (BT-108) = Σ Document level charge amount (BT-99).

Also cited in this report

  • BR-CO-12

    [BR-CO-12]-Sum of charges on document level (BT-108) = Σ Document level charge amount (BT-99).

What Mutabiq reports

One entry for each way this rule can be reported.

Reported as
What kind of value was found — empty, not_15_digits and the like — never the value itself.

Sum of document-level charges is missing

Reported astotal_missingthe total is missing

What is wrong

The document carries at least one document-level charge - a cac:AllowanceCharge directly under the invoice with cbc:ChargeIndicator true - but cac:LegalMonetaryTotal has no cbc:ChargeTotalAmount. ZATCA rejects the document under BR-CO-12, which requires the charge total (BT-108) to equal the sum of the document-level charge amounts, rounded to two decimals; with the element absent there is nothing for the sum to equal.

What to check in your ERP

Write cbc:ChargeTotalAmount into the totals block whenever the document has a document-level charge. Only the cac:AllowanceCharge elements directly under the invoice with cbc:ChargeIndicator true count here; charges inside an invoice line do not.

Sum of document-level charges does not match the charges

Reported asnot_sum_of_chargesnot the sum of the charges

What is wrong

cbc:ChargeTotalAmount in cac:LegalMonetaryTotal is not the sum of the cbc:Amount of the document-level charges (cac:AllowanceCharge directly under the invoice with cbc:ChargeIndicator true), rounded to two decimals. ZATCA rejects the document under BR-CO-12. There is no tolerance: the comparison is exact. A charge total that is not zero on a document with no document-level charge fails too, because the sum it must equal is zero.

What to check in your ERP

Check where the charge total comes from. It adds up the document-level charges only, before VAT, and includes neither line-level charges nor allowances. If your system rounds each charge before adding them, compare it with the sum rounded once at the end.

Sum of document-level charges is present but empty

Reported astotal_blankthe total is present but empty

What is wrong

cac:LegalMonetaryTotal contains a cbc:ChargeTotalAmount element with no value, or only spaces. ZATCA rejects the document under BR-CO-12, which tests for this case before any arithmetic. BR-CO-13 reports the same empty element as a warning.

What to check in your ERP

Either write the charge total - 0.00 when the document has no document-level charge - or leave the element out. An empty element usually comes from a template that always writes the tag and fills it only when a charge exists.

The clause that runs

Quoted from the validation-rule stylesheet ZATCA publishes, at the file and line named below. The executed guard is what the check runs; the reported test is what it prints when it fails, and the two are not always the same.

Executed guard

exists (cbc:ChargeTotalAmount) and normalize-space(cbc:ChargeTotalAmount)=''

Reported test

xs:decimal(cbc:AllowanceTotalAmount) = (round(sum(../cac:AllowanceCharge[cbc:ChargeIndicator=false()]/xs:decimal(cbc:Amount)) * 10 * 10) div 100) or (not(cbc:AllowanceTotalAmount) and not(../cac:AllowanceCharge[cbc:ChargeIndicator=false()]))
Evaluated against
cac:LegalMonetaryTotal
Source
vendor/zatca/schematron/CEN-EN16931-UBL.xsl:449

As shipped in ZATCA SDK 3.4.8: the copy quoted here is, byte for byte, the file that release ships. The date in the file name is the name ZATCA gives the file; the rules in it are those of SDK 3.4.8.

A worked example

A synthetic document from the measured test corpus that trips this rule, shown where it differs from one that passed. Mutabiq's report names the class of the value, never the value itself.

Where it differs from a document that passed

  • This example
  • A document that passed
  <cbc:PaymentMeansCode>10</cbc:PaymentMeansCode></cac:PaymentMeans>This example: <cac:AllowanceCharge>This example:   <cbc:ChargeIndicator>true</cbc:ChargeIndicator>This example:   <cbc:AllowanceChargeReasonCode>CG</cbc:AllowanceChargeReasonCode>This example:   <cbc:AllowanceChargeReason>Cleaning</cbc:AllowanceChargeReason>This example:   <cbc:Amount currencyID="SAR">25.00</cbc:Amount>This example:   <cac:TaxCategory>This example:     <cbc:ID schemeID="UN/ECE 5305" schemeAgencyID="6">S</cbc:ID>This example:     <cbc:Percent>15.00</cbc:Percent>This example:     <cac:TaxScheme>This example:       <cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">VAT</cbc:ID>This example:     </cac:TaxScheme>This example:   </cac:TaxCategory>This example: </cac:AllowanceCharge><cac:TaxTotal>  <cbc:TaxAmount currencyID="SAR">15.00</cbc:TaxAmount>
Document
bad-80-document-charge.xml
Mutabiq's verdict
Not passed
Reported as
total_missingthe total is missing

Download this example (.xml)Check it in Mutabiq

This page's example, checked by the same rules your own upload goes through. No upload and no sign-in.

Rules evaluated against the same part of the document. One wrong value often reports several of them at once.

Check an invoice

Check your own invoice

© 2026 Hayatiq AI Solutions F.Z.E. All rights reserved.