Error codes

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.