BR-CO – Conditions and calculations
BR-CO-13: total without VAT (BT-109) does not add up
ErrorEN 16931 business rule (CEN)
The rule's own wording
[BR-CO-13]-Invoice total amount without VAT (BT-109) = Σ Invoice line net amount (BT-131) - Sum of allowances on document level (BT-107) + Sum of charges on document level (BT-108).Source: CEN EN 16931, version 1.3.16
Meaning of the rule
The net total of your invoice does not add up. The norm recalculates it like this: sum of all line net amounts, minus the sum of document level allowances, plus the sum of document level charges, rounded to two decimals. If the stated amount differs by even one cent, the invoice is rejected. Often the software rounds only at the end while the norm uses the rounded individual amounts, or a line amount was changed afterwards.
The fix in the XML
Set BT-109 in cbc:TaxExclusiveAmount to the line sum minus BT-107 plus BT-108, each with the rounded values shown in the invoice. Check BT-106, BT-107 and BT-108 individually first, then the total.
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">1000.00</cbc:TaxExclusiveAmount>
<cbc:AllowanceTotalAmount currencyID="EUR">75.50</cbc:AllowanceTotalAmount>
<cbc:ChargeTotalAmount currencyID="EUR">12.90</cbc:ChargeTotalAmount>
</cac:LegalMonetaryTotal><cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">937.40</cbc:TaxExclusiveAmount>
<cbc:AllowanceTotalAmount currencyID="EUR">75.50</cbc:AllowanceTotalAmount>
<cbc:ChargeTotalAmount currencyID="EUR">12.90</cbc:ChargeTotalAmount>
</cac:LegalMonetaryTotal>Questions and answers
Why is the amount right in the PDF but not in the XML?
Because the PDF is often produced with other rounding rules than the XML. Only the XML counts for the validation; both should come from the same rounded values.
Does the VAT belong in BT-109?
No. BT-109 is the amount without VAT; the gross amount stands in BT-112.
Other typical causes
- The software calculates with unrounded line amounts and rounds only the total.
- A line amount, allowance or charge was changed after the totals were built.
- Line discounts were deducted twice, in the line and at document level.
EN 16931 fields
- BT-109
- BT-106
- BT-107
- BT-108
- BG-22
See also
Check your invoice
The EN 16931 validator reports this rule with the line number and location – right in your browser, without upload.
The rule in detail
- UBL · Context (XPath)
cac:LegalMonetaryTotal- UBL · Schematron test
((cbc:ChargeTotalAmount) and (cbc:AllowanceTotalAmount) and (xs:decimal(cbc:TaxExclusiveAmount) = round((xs:decimal(cbc:LineExtensionAmount) + xs:decimal(cbc:ChargeTotalAmount) - xs:decimal(cbc:AllowanceTotalAmount)) * 10 * 10) div 100 )) or (not(cbc:ChargeTotalAmount) and (cbc:AllowanceTotalAmount) and (xs:decimal(cbc:TaxExclusiveAmount) = round((xs:decimal(cbc:LineExtensionAmount) - xs:decimal(cbc:AllowanceTotalAmount)) * 10 * 10 ) div 100)) or ((cbc:ChargeTotalAmount) and not(cbc:AllowanceTotalAmount) and (xs:decimal(cbc:TaxExclusiveAmount) = round((xs:decimal(cbc:LineExtensionAmount) + xs:decimal(cbc:ChargeTotalAmount)) * 10 * 10 ) div 100)) or (not(cbc:ChargeTotalAmount) and not(cbc:AllowanceTotalAmount) and (xs:decimal(cbc:TaxExclusiveAmount) = xs:decimal(cbc:LineExtensionAmount)))- CII · Context (XPath)
//ram:SpecifiedTradeSettlementHeaderMonetarySummation- CII · Schematron test
(xs:decimal(ram:TaxBasisTotalAmount[1]) = round((xs:decimal(ram:LineTotalAmount[1]) - xs:decimal(ram:AllowanceTotalAmount[1]) + xs:decimal(ram:ChargeTotalAmount[1])) * 10 * 10) div 100) or ((xs:decimal(ram:TaxBasisTotalAmount[1]) = round((xs:decimal(ram:LineTotalAmount[1]) - xs:decimal(ram:AllowanceTotalAmount[1])) * 10 * 10) div 100) and not(ram:ChargeTotalAmount)) or ((xs:decimal(ram:TaxBasisTotalAmount[1]) = round((xs:decimal(ram:LineTotalAmount[1]) + xs:decimal(ram:ChargeTotalAmount[1])) * 10 * 10) div 100) and not(ram:AllowanceTotalAmount)) or ((xs:decimal(ram:TaxBasisTotalAmount[1]) = round((xs:decimal(ram:LineTotalAmount[1])) * 10 * 10) div 100) and not(ram:ChargeTotalAmount) and not(ram:AllowanceTotalAmount))- CII · Context (XPath)
//ram:SpecifiedTradeSettlementHeaderMonetarySummation- CII · Schematron test
(xs:decimal(ram:TaxBasisTotalAmount) = round((xs:decimal(ram:LineTotalAmount) - xs:decimal(ram:AllowanceTotalAmount) + xs:decimal(ram:ChargeTotalAmount)) *10 * 10) div 100) or ((xs:decimal(ram:TaxBasisTotalAmount) = round((xs:decimal(ram:LineTotalAmount) - xs:decimal(ram:AllowanceTotalAmount)) *10 * 10) div 100) and not (ram:ChargeTotalAmount)) or ((xs:decimal(ram:TaxBasisTotalAmount) = round((xs:decimal(ram:LineTotalAmount) + xs:decimal(ram:ChargeTotalAmount)) *10 * 10) div 100) and not (ram:AllowanceTotalAmount)) or ((xs:decimal(ram:TaxBasisTotalAmount) = round((xs:decimal(ram:LineTotalAmount)) *10 * 10) div 100) and not (ram:ChargeTotalAmount) and not (ram:AllowanceTotalAmount))
Explanation written on 14 September 2026