Error codes · EN 16931

BR-CO-25Fixable here

Payment due date or payment terms required when amount due is positive

This is the rejection, word for word: „[BR-CO-25] BR-CO-25 fires when the Amount due for payment (BT-115) is greater than zero but neither the Payment due date (BT-9, cbc:DueDate) nor the Payment terms (BT-20, cac:PaymentTerms/cbc:Note) is present. Peppol requires the buyer to know when to pay or under what terms — a positive amount with no payment timing is a fatal validation error.“

The rule's XPath is roughly `((. > 0) and (exists(//cbc:DueDate) or exists(//cac:PaymentTerms/cbc:Note))) or (. <= 0)`. Common failure modes: (1) The invoice is exported without a due date because the ERP stores the due date on the payment-schedule subrecord and the UBL mapping reads only the header. (2) The invoice has cac:PaymentTerms but the only child is cac:SettlementPeriod or cac:PaymentMeans — not cbc:Note — so the schematron's exists() check fails. (3) Net-zero invoices (totals correct but cbc:PayableAmount > 0 because a prepayment was not subtracted) trip the rule unexpectedly. (4) Credit notes with a positive PayableAmount due to refund logic — historically there was a known schematron issue on credit notes where DueDate at the root is not a valid element. (5) Empty cbc:Note (`<cbc:Note/>`) does not satisfy the rule on some validator implementations even though exists() returns true; the safer pattern is a non-empty literal.

What to have readyLine IDs (comma-separated)
What we doStep 1: Read BT-115 (cbc:PayableAmount). If it's ≤ 0, the rule cannot fire — investigate why the validator reports it. Step 2: If BT-115 > 0, decide whether to emit a Payment due date or Payment terms (or both): • If your ERP has a contractual due date, write it as `<cbc:DueDate>YYYY-MM-DD</cbc:DueDate>` directly under the cbc:InvoiceTypeCode-level part of the Invoice/CreditNote root. • If the contract is net-30 / net-15 / on receipt and no fixed date applies, emit `<cac:PaymentTerms><cbc:Note>Net 30 days from invoice date</cbc:Note></cac:PaymentTerms>` with a non-empty, human-readable note. Step 3: Make sure the cbc:Note text is not empty and not pure whitespace. Some validators reject `<cbc:Note></cbc:Note>` even though the element exists. Step 4: For credit notes, prefer cac:PaymentTerms/cbc:Note over cbc:DueDate — historically more reliable across validator implementations. Step 5: Recalculate BT-115 to make sure the sign matches the document type (positive on Invoice, sign convention on CreditNote). Step 6: Re-validate. BR-CO-25 should clear without affecting other rules.
If you enter it yourself in your invoicing software
Before
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
  <cbc:ID>INV-2026-0042</cbc:ID>
  <cbc:IssueDate>2026-05-26</cbc:IssueDate>
  <!-- no cbc:DueDate, no cac:PaymentTerms -->
  <cac:LegalMonetaryTotal>
    <cbc:PayableAmount currencyID="EUR">1190.00</cbc:PayableAmount>
  </cac:LegalMonetaryTotal>
</Invoice>
After
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
  <cbc:ID>INV-2026-0042</cbc:ID>
  <cbc:IssueDate>2026-05-26</cbc:IssueDate>
  <cbc:DueDate>2026-06-25</cbc:DueDate>
  <cac:PaymentTerms>
    <cbc:Note>Net 30 days from invoice date</cbc:Note>
  </cac:PaymentTerms>
  <cac:LegalMonetaryTotal>
    <cbc:PayableAmount currencyID="EUR">1190.00</cbc:PayableAmount>
  </cac:LegalMonetaryTotal>
</Invoice>
What the finding looks likeExample
FindingValue missing · BR-CO-25
From youLine IDs (comma-separated)
ThenPassed
ProofSHA-256 and /verify link after the check