BR-CO-16: Amount due for payment (BT-115)
Severity: fatal · Syntax: CII, UBL
Official message
Amount due for payment (BT-115) = Invoice total amount with VAT (BT-112) -Paid amount (BT-113) +Rounding amount (BT-114).
What this means
The message sets BT-115 = BT-112 − BT-113 + BT-114. The UBL assertion branches on whether PrepaidAmount and PayableRoundingAmount exist, and rounds the differences to two decimal places. If both are absent, PayableAmount must equal TaxInclusiveAmount. Official text: Amount due for payment (BT-115) = Invoice total amount with VAT (BT-112) -Paid amount (BT-113) +Rounding amount (BT-114).
Typical cause
A prepayment or rounding exists in the accounts, but BT-113 or BT-114 is missing from the XML, or the rounding sign is reversed.
How to fix it
Calculate the named BT fields in the same currency and set the header amounts to the result of the assertion. The check helps you find the difference.
UBL
<cbc:TaxInclusiveAmount currencyID="EUR">119.00</cbc:TaxInclusiveAmount>
<cbc:PayableAmount currencyID="EUR">119.00</cbc:PayableAmount>CII
<ram:GrandTotalAmount>119.00</ram:GrandTotalAmount>
<ram:DuePayableAmount>119.00</ram:DuePayableAmount>
Business term
BT-115, BT-112, BT-113, BT-114
Related rules
Context and assertion
UBL cac:LegalMonetaryTotal
CII //ram:SpecifiedTradeSettlementHeaderMonetarySummation
UBL
(exists(cbc:PrepaidAmount) and not(exists(cbc:PayableRoundingAmount)) and (xs:decimal(cbc:PayableAmount) = (round((xs:decimal(cbc:TaxInclusiveAmount) - xs:decimal(cbc:PrepaidAmount)) * 10 * 10) div 100))) or (not(exists(cbc:PrepaidAmount)) and not(exists(cbc:PayableRoundingAmount)) and xs:decimal(cbc:PayableAmount) = xs:decimal(cbc:TaxInclusiveAmount)) or (exists(cbc:PrepaidAmount) and exists(cbc:PayableRoundingAmount) and ((round((xs:decimal(cbc:PayableAmount) - xs:decimal(cbc:PayableRoundingAmount)) * 10 * 10) div 100) = (round((xs:decimal(cbc:TaxInclusiveAmount) - xs:decimal(cbc:PrepaidAmount)) * 10 * 10) div 100))) or (not(exists(cbc:PrepaidAmount)) and exists(cbc:PayableRoundingAmount) and ((round((xs:decimal(cbc:PayableAmount) - xs:decimal(cbc:PayableRoundingAmount)) * 10 * 10) div 100) = xs:decimal(cbc:TaxInclusiveAmount)))CII
(xs:decimal(ram:DuePayableAmount[1]) = xs:decimal(ram:GrandTotalAmount[1]) - xs:decimal(ram:TotalPrepaidAmount[1]) + xs:decimal(ram:RoundingAmount[1])) or ((xs:decimal(ram:DuePayableAmount[1]) = xs:decimal(ram:GrandTotalAmount[1]) + xs:decimal(ram:RoundingAmount[1])) and not(ram:TotalPrepaidAmount)) or ((xs:decimal(ram:DuePayableAmount[1]) = xs:decimal(ram:GrandTotalAmount[1]) - xs:decimal(ram:TotalPrepaidAmount[1])) and not(ram:RoundingAmount)) or ((xs:decimal(ram:DuePayableAmount[1]) = xs:decimal(ram:GrandTotalAmount[1])) and not(ram:TotalPrepaidAmount) and not(ram:RoundingAmount))
Check a file now, free of charge
curl -F "file=@rechnung.xml" https://checkxrechnung.com/v1/validate
Questions
What does BR-CO-16 actually check?
The message sets BT-115 = BT-112 − BT-113 + BT-114. The UBL assertion branches on whether PrepaidAmount and PayableRoundingAmount exist, and rounds the differences to two decimal places. If both are absent, PayableAmount must equal TaxInclusiveAmount. Official text: Amount due for payment (BT-115) = Invoice total amount with VAT (BT-112) -Paid amount (BT-113) +Rounding amount (BT-114).
How do I fix BR-CO-16?
Calculate the named BT fields in the same currency and set the header amounts to the result of the assertion. The check helps you find the difference.
If BR-CO-16 passes, is the invoice legally compliant?
No. This page helps you read this one Schematron assertion. A pass is not a statement about tax law, portal acceptance, or bank overlays.