Automation MCP Server Features Blog Pricing Contact
Validation rule EN 16931 core

BR-CO-16

The last link of the totals chain: BR-CO-16 requires the amount due for payment (BT-115) to equal the total with VAT (BT-112) minus the paid amount (BT-113) plus the rounding amount (BT-114). Prepayments and deposits are where it earns its keep.

What BR-CO-16 checks

BR-CO-16 closes the totals chain: Amount due for payment (BT-115) = Invoice total amount with VAT (BT-112) minus Paid amount (BT-113) plus Rounding amount (BT-114). BT-115 is the number payment runs and dunning processes act on, so the core model insists it be derivable from the declared totals rather than a free-floating figure. In UBL it is the cbc:PayableAmount of the legal monetary total, with BT-113 in cbc:PrepaidAmount and BT-114 in cbc:PayableRoundingAmount.

Layer and formats

An en16931 core layer rule for every syntax and profile. Its input BT-112 is policed by BR-CO-15, so chain failures cascade into this rule; a lone BR-CO-16 failure means the payable amount itself, the prepaid amount, or the rounding delta is off.

Why it fails in practice

  • Prepayments applied to the wrong field. The deposit is subtracted from the gross total (breaking BR-CO-15) or from the line amounts instead of being declared in BT-113.
  • BT-115 taken from accounts receivable. The open-item amount in the ledger includes credits or fees the invoice document knows nothing about.
  • Rounding without declaring it. The payable amount is rounded for payment convenience, but the delta never lands in BT-114, so the equation misses by exactly that delta.

How to fix it

Derive BT-115 from the declared components:

<cac:LegalMonetaryTotal>
  <cbc:TaxInclusiveAmount currencyID="EUR">1154.30</cbc:TaxInclusiveAmount>
  <cbc:PrepaidAmount currencyID="EUR">500.00</cbc:PrepaidAmount>
  <cbc:PayableAmount currencyID="EUR">654.30</cbc:PayableAmount>
</cac:LegalMonetaryTotal>

In an InvoiceXML create request the fields are totals.duePayableAmount, totals.paidAmount and totals.roundingAmount. Supply the paid amount if there is one and leave the rest of invoice.totals out: the API computes the due amount server-side.

The raw rejection vs the InvoiceXML finding

The Schematron report:

<svrl:failed-assert id="BR-CO-16" flag="fatal"
    location="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]">
  <svrl:text>[BR-CO-16]-Amount due for payment (BT-115) =
    Invoice total amount with VAT (BT-112) -Paid amount (BT-113)
    +Rounding amount (BT-114).</svrl:text>
</svrl:failed-assert>

The InvoiceXML finding for the same failure:

{
  "rule": "BR-CO-16",
  "layer": "en16931",
  "line": null,
  "message": "The amount due for payment must equal the total with VAT minus prepaid amounts plus rounding. Check the due amount.",
  "btCodes": ["BT-115", "BT-112", "BT-113", "BT-114"],
  "fields": ["totals.duePayableAmount", "totals.grandTotalAmount", "totals.paidAmount", "totals.roundingAmount"],
  "raw": "[BR-CO-16] EN16931: Amount due for payment (BT-115) = Invoice total amount with VAT (BT-112) -Paid amount (BT-113) +Rounding amount (BT-114)."
}

Every field in the equation arrives as a dotted request path, so your UI can highlight all four inputs at once, and the message needs no translation layer. Clients localize by the stable rule key if they want their own copy.

Check or generate documents with correct totals

Validate a file in the UBL validator or the XRechnung validator. Generating with POST /v1/create/ubl or POST /v1/create/facturx removes the whole failure class: the chain from line sum to amount due is computed server-side. The model behind it is covered in EN 16931 explained.

  • BR-CO-10, the line sum (BT-106)
  • BR-CO-11, the allowance sum (BT-107)
  • BR-CO-13, the total without VAT (BT-109)
  • BR-CO-14, the VAT total against the breakdown (BT-110)
  • BR-CO-15, the total with VAT (BT-112)
  • BR-CO-16, the amount due (BT-115), this page

Frequently asked questions

What is the rounding amount (BT-114) for?

It lets the payable amount be rounded to a payment-friendly value, for example whole cents in currencies with rounding conventions. It is the delta added on top of BT-112 minus BT-113; it is not a place to hide arithmetic mismatches elsewhere in the chain.

How do I model a deposit or prepayment?

Put the amount already received into the paid amount (BT-113) and let BT-115 carry only what remains. The invoice still shows the full totals; only the amount due shrinks. Note that BT-113 is a settlement fact, not a discount: contractual reductions belong in allowances.

Can the amount due be zero or negative?

Zero is legitimate for a fully prepaid invoice: BT-113 equals BT-112 and BT-115 is 0.00. A negative amount due signals money flowing back and usually belongs in a credit note instead; several receivers reject negative BT-115 on an invoice type.

Can documents created via the API fail this rule?

Not in practice. Omit invoice.totals in a /v1/create/* request and BT-115 is derived server-side from the computed gross total and any paid amount you supply, with validation before delivery. The rule bites on documents arriving from other systems.