# BR-CL-20: Use a charge reason code from the UNTDID 7161 list

A charge reason code must be an upper-case UNTDID 7161 code, such as FC for freight or DL for delivery. Plain words such as FREIGHT are rejected.

- Layer: EN 16931
- Severity: fatal (the document is invalid)
- Topics: Code lists, Allowances and charges
- Official definition: https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-CL-20/
- Explanation last updated: 2026-09-24

## The short answer

`BR-CL-20` fails when `cbc:AllowanceChargeReasonCode` on a charge (`cbc:ChargeIndicator` of `true`) is not a code from UNTDID 7161, the list of charges and services. Put the code for the service being charged in its place, for example `FC` (Freight service) where the recorded example wrote `FREIGHT`, or drop the code and describe the charge in `cbc:AllowanceChargeReason`.

`PEPPOL-EN16931-CL003` checks the same element against the same list at the Peppol layer, so both are reported and both clear together.

## What the rule checks

The rule covers every `cbc:AllowanceChargeReasonCode` in a `cac:AllowanceCharge` that reads as a charge, at document level and on lines. When tried, `FREIGHT` on the line charge of the rich invoice was reported at `cac:InvoiceLine[1]/cac:AllowanceCharge[2]`.

Surrounding whitespace is trimmed, and the rest is compared case-sensitively. Lower-case `fc` failed when tried, and `FC` passed.

One code per element. `FC DL` was rejected when tried, since any value with an inner space fails.

Allowance codes do not count here. The UNTDID 5189 code `95` on the document charge failed just as a word would.

An empty `cbc:AllowanceChargeReasonCode` fails the list check as well, and brings `PEPPOL-EN16931-R008` for the empty element.

The reason text is not read. `BR-CO-06`, which should compare charge code and text, always passes in this release.

| Term | Meaning | UBL element |
|---|---|---|
| BT-105 | Document level charge reason code | `cac:AllowanceCharge/cbc:AllowanceChargeReasonCode` |
| BT-145 | Invoice line charge reason code | `cac: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:

- The charge type from the source system, such as `FREIGHT`, `POSTAGE` or `HANDLING`, is written straight into the code element.
- The code is sent in lower case because the mapping table was typed that way or a formatter lower-cases identifiers.
- One lookup table serves allowances and charges, so a numeric allowance code lands on a charge.
- Several services are billed as one charge and their codes are joined into one value.

## How to fix it

1. From the finding location, identify the charge: `cac:AllowanceCharge[2]` under the root in the recorded example, or an entry inside a line.
2. Find the UNTDID 7161 entry for the service in the list Peppol publishes. Some entries from it: `FC` Freight service, `DL` Delivery, `PC` Packing, `CG` Cleaning.
3. Write the code in upper case, exactly as listed, in `cbc:AllowanceChargeReasonCode`, and keep any local description in `cbc:AllowanceChargeReason`.
4. Where two services are charged, send two `cac:AllowanceCharge` elements with one code each, and keep the charge total and the VAT breakdown in step.
5. If no code describes the charge, omit the code and send the text only.

## 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 document charge has the word FREIGHT as its reason code

```xml
<cac:AllowanceCharge>
  <cbc:ChargeIndicator>true</cbc:ChargeIndicator>
  <cbc:AllowanceChargeReasonCode>FREIGHT</cbc:AllowanceChargeReasonCode>
  <cbc:AllowanceChargeReason>Example document charge</cbc:AllowanceChargeReason>
  <!-- percentage, amount, base amount and tax category omitted from this fragment -->
</cac:AllowanceCharge>
```

Fragment of the corrected invoice: the reason code is CG, a code on the UNTDID 7161 list

```xml
<cac:AllowanceCharge>
  <cbc:ChargeIndicator>true</cbc:ChargeIndicator>
  <cbc:AllowanceChargeReasonCode>CG</cbc:AllowanceChargeReasonCode>
  <cbc:AllowanceChargeReason>Example document charge</cbc:AllowanceChargeReason>
  <!-- percentage, amount, base amount and tax category omitted from this fragment -->
</cac:AllowanceCharge>
```

In the failing invoice the document charge has `FREIGHT` as its reason code, and in the corrected invoice `CG`, which is on the list. The failing document also reports `PEPPOL-EN16931-CL003`, because the Peppol layer holds its own copy of the UNTDID 7161 check and rejects the same element. `CG` means Cleaning, so it only illustrates a valid value; for a freight charge the matching code is `FC`, which passed when tried in the same place.

### What the validator reported

- The failing invoice reports **BR-CL-20** and `PEPPOL-EN16931-CL003`. The corrected document passes every layer with no findings.
  - [Download the failing XML](https://ironfang.uk/finance/rule-examples/BR-CL-20-invalid.xml)
  - [Download the corrected XML](https://ironfang.uk/finance/rule-examples/invoice-rich.xml)

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` alike; `FREIGHT` on the document charge of a credit note reported this rule and `PEPPOL-EN16931-CL003` when tried.
- Allowance codes are checked against UNTDID 5189 by `BR-CL-19`. Which of the two lists applies follows `cbc:ChargeIndicator`.
- Whether a document-level charge has any reason at all is a separate question, answered by `BR-CO-22`.

## Related rules

- [BR-CL-19 is the code list check for allowance reason codes](https://ironfang.uk/docs/finance/rules/BR-CL-19.md)
- [BR-CO-22 requires a document-level charge to have a reason code or text](https://ironfang.uk/docs/finance/rules/BR-CO-22.md)
- [BR-CO-12 checks the charge total, which a split charge must still match](https://ironfang.uk/docs/finance/rules/BR-CO-12.md)

## 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-24.1: source checked 2026-09-24, explanation last updated 2026-09-24.

[The official definition of BR-CL-20](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-CL-20/) 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.

## Links

- [This rule as a web page](https://ironfang.uk/docs/finance/rules/BR-CL-20)
- [Free Peppol invoice validator](https://ironfang.uk/tools/peppol-validator)
- [Rule index](https://ironfang.uk/docs/finance/rules.md)
- [Ironfang Finance API docs](https://ironfang.uk/docs/finance)
- The same rule is available to MCP clients as the tool `finance.rule.get` on https://mcp.ironfang.uk/mcp
