Skip to content

Ironfang Finance - Rule reference

PEPPOL-EN16931-CL003: Use a code from the Peppol UNTDID 7161 list as the charge reason code

On a charge marked true, cbc:AllowanceChargeReasonCode must be a UNTDID 7161 code, such as DL for delivery. DEL is not one of them.

Peppol BIS BillingFatal: the document is invalidCode listsAllowances and charges

On this page

The short answer

PEPPOL-EN16931-CL003 fails when cbc:AllowanceChargeReasonCode in a charge whose cbc:ChargeIndicator reads exactly true is not on the Peppol UNTDID 7161 list. The recorded line charge was coded DEL; the code for a delivery charge is DL.

DEL looks plausible because it is a real code on another list: the UNTDID 4451 note subjects that BR-CL-08 checks. Charge reasons come only from UNTDID 7161, and BR-CL-20 applies that same list on the EN 16931 layer, so both rules report the value.

What the rule checks

Only charges whose indicator is the exact text true are in scope. When tried, true with spaces and 1, both valid booleans to the schema, kept a DEL code away from this rule: BR-CL-20 reported it in both cases, and PEPPOL-EN16931-R043 added a finding for 1.

The code is trimmed and then compared case-sensitively with the 178 codes of the list, which are the same as those of BR-CL-20.

Document and line charges are both covered. In the recorded example the finding points at cac:InvoiceLine[1]/cac:AllowanceCharge[2]/cbc:AllowanceChargeReasonCode[1].

The code is not compared with the charge text: in the corrected invoice, DL beside the text Example charge passed.

TermMeaningUBL element
BT-105Document level charge reason codecac:AllowanceCharge/cbc:AllowanceChargeReasonCode
BT-145Invoice line charge reason codecac:InvoiceLine/cac:AllowanceCharge/cbc:AllowanceChargeReasonCode (cac:CreditNoteLine in a credit note)

How an integration ends up here

Possible causes, from the shape of the rule rather than from measured usage:

  • A code from another UN/EDIFACT list is used because it reads like the service, such as DEL from the note subject list for a delivery charge.
  • Abbreviations from the source system, such as FRT for freight, are written as codes.
  • An allowance code is sent on a charge because one mapping serves both.
  • Codes are held in lower case and written unchanged.

How to fix it

  1. Find the charge from the finding location: a document charge under the root or a charge inside a line.
  2. Look the service up in the Peppol UNTDID 7161 list: DL Delivery, FC Freight service, PC Packing, ABL Additional packaging.
  3. Write the code in upper case in cbc:AllowanceChargeReasonCode, and write cbc:ChargeIndicator as true, so both layers see the charge.
  4. Keep charge codes in a table of their own, apart from allowance codes and note subject codes.

Validate your corrected invoice

Before and after

These are fragments, not complete documents. The complete synthetic documents they come from are linked below.

Fragment of the failing invoice: the line charge reason code is DEL

<cac:InvoiceLine>
  <cbc:ID>1</cbc:ID>
  <!-- note, quantity, amounts, order line reference and line allowance omitted from this fragment -->
  <cac:AllowanceCharge>
    <cbc:ChargeIndicator>true</cbc:ChargeIndicator>
    <cbc:AllowanceChargeReasonCode>DEL</cbc:AllowanceChargeReasonCode>
    <cbc:AllowanceChargeReason>Example charge</cbc:AllowanceChargeReason>
    <cbc:Amount currencyID="GBP">0.01</cbc:Amount>
  </cac:AllowanceCharge>
  <!-- item and price omitted from this fragment -->
</cac:InvoiceLine>

Fragment of the corrected invoice: the reason code is DL, Delivery

<cac:InvoiceLine>
  <cbc:ID>1</cbc:ID>
  <!-- note, quantity, amounts, order line reference and line allowance omitted from this fragment -->
  <cac:AllowanceCharge>
    <cbc:ChargeIndicator>true</cbc:ChargeIndicator>
    <cbc:AllowanceChargeReasonCode>DL</cbc:AllowanceChargeReasonCode>
    <cbc:AllowanceChargeReason>Example charge</cbc:AllowanceChargeReason>
    <cbc:Amount currencyID="GBP">0.01</cbc:Amount>
  </cac:AllowanceCharge>
  <!-- item and price omitted from this fragment -->
</cac:InvoiceLine>

Only the reason code of the line charge differs: DEL in the failing invoice, DL in the corrected one. The failing document also reports BR-CL-20, which applies the same UNTDID 7161 list on the EN 16931 layer, at the same element.

What the validator reported

Recorded on phive 12.1.0 / phive-rules-peppol 4.5.6 / Saxon-HE 12.10, the engine behind the free validator, using synthetic data. A recorded result is regression evidence for these documents; it is not a certification.

Where it applies

  • Applies to Invoice and CreditNote; DEL on a credit note line charge reported this rule and BR-CL-20 when tried.
  • A Peppol BIS Billing 3.0 rule. Allowances are checked against UNTDID 5189 by PEPPOL-EN16931-CL002 instead.
  • Whether a charge needs a reason at all is decided elsewhere, by BR-CO-22 for document charges and BR-CO-24 for line charges.

Scope and source

Written for Peppol BIS Billing 3.0.21 (May 2026), EN 16931 1.3.16, as applied to UBL 2.1 Invoice and CreditNote documents. Other profiles, syntaxes and releases can define this identifier differently. Guidance version 2026-09-28.1: source checked 2026-09-28, explanation last updated 2026-09-28.

The official definition of PEPPOL-EN16931-CL003 carries the normative wording and test. This page is our explanation of it, not a copy.

Guidance does not change the engine verdict. Fixing this finding does not mean the document passes every layer, and validation does not certify legal or tax compliance or transmit a document over Peppol.