# BR-05: Add the invoice currency code

The document has no `cbc:DocumentCurrencyCode`, or it is blank. State the currency the invoice is issued in as a three-letter ISO 4217 code.

- Layer: EN 16931
- Severity: fatal (the document is invalid)
- Topics: Core fields
- Official definition: https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-05/
- Explanation last updated: 2026-09-24

## The short answer

`BR-05` fails when the document root has no `cbc:DocumentCurrencyCode`, or has one that is empty or holds only whitespace. Add the element with the ISO 4217 code of the currency the invoice is issued in, such as `GBP`.

Expect a long list of findings from this one omission. Peppol compares the `currencyID` of every amount with this element, so while it is missing `PEPPOL-EN16931-R051` is reported once per amount, even where the attribute is correct.

## What the rule checks

The rule runs once on the `Invoice` or `CreditNote` root and looks for a `cbc:DocumentCurrencyCode` child whose text is not blank once whitespace is stripped. An absent element, an empty one and one holding only spaces all fail it.

Only the presence of a value is tested here. Whether that value is a real currency code is left to `BR-CL-04`: when tried, `gbp` passed this rule and was reported by `BR-CL-04` instead.

The UBL schema treats the element as optional, so a document without it passes the XSD layer and the gap is left to the EN 16931 layer. When tried, an empty element and one holding a single space each reported `BR-CL-04`, `BR-CO-15` and `PEPPOL-EN16931-R008` besides this rule, and `PEPPOL-EN16931-R051` on every amount.

The `currencyID` attributes on the amounts do not stand in for the element. The recorded example still carries `GBP` on all thirteen amounts and fails.

| Term | Meaning | UBL element |
|---|---|---|
| BT-5 | Invoice currency code | `cbc:DocumentCurrencyCode` |

## How an integration ends up here

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

- The currency is held on the customer or ledger record, and the export reads it from the invoice header, where it is null.
- A system that only ever invoices in one currency has no currency field at all, and the template writes `currencyID="GBP"` on the amounts as a literal without an element for the document currency.
- The serialiser skips null values, or writes an empty element for them, and the currency field was null for this invoice.
- The code is written to `cbc:TaxCurrencyCode`, the VAT accounting currency, instead of `cbc:DocumentCurrencyCode`.

## How to fix it

1. Take the currency from the transaction: the currency the prices were agreed in and the amounts are expressed in. Do not fall back to the seller home currency if the invoice was raised in another.
2. Write it as the upper-case ISO 4217 alphabetic code to `cbc:DocumentCurrencyCode` directly under the root: after the type code and any `cbc:Note` or `cbc:TaxPointDate`, and before `cbc:TaxCurrencyCode`, `cbc:AccountingCost` and `cbc:BuyerReference`. When tried, the element placed after `cbc:BuyerReference` failed the XSD layer.
3. Check that every amount carries the same code in `currencyID`, character for character. Only the VAT total in a separate accounting currency may differ.
4. Make the currency a required field where invoices are created, so an invoice without one cannot reach the export.

## Before and after

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

Fragment of the failing invoice: no currency code between the type code and the buyer reference, while the amounts still say GBP

```xml
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:BuyerReference>BUYER-REF-001</cbc:BuyerReference>
<!-- parties and tax total omitted from this fragment -->

<cac:LegalMonetaryTotal>
  <cbc:LineExtensionAmount currencyID="GBP">25.00</cbc:LineExtensionAmount>
  <cbc:TaxExclusiveAmount currencyID="GBP">25.00</cbc:TaxExclusiveAmount>
  <cbc:TaxInclusiveAmount currencyID="GBP">30.00</cbc:TaxInclusiveAmount>
  <!-- allowance, charge, prepaid and rounding totals omitted from this fragment -->
  <cbc:PayableAmount currencyID="GBP">30.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
```

Fragment of the corrected invoice: the currency code is present, and the amounts are unchanged

```xml
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>GBP</cbc:DocumentCurrencyCode>
<cbc:BuyerReference>BUYER-REF-001</cbc:BuyerReference>
```

The corrected invoice has `cbc:DocumentCurrencyCode` with the value `GBP` between the type code and the buyer reference; the failing one has no such element, and nothing else differs. The failing document also reports `PEPPOL-EN16931-R051` thirteen times, once for each amount in the tax total, the monetary totals and the line: that Peppol rule requires each `currencyID` to equal the document currency code, and with no code to compare against even the correct `GBP` attributes fail. Adding the element clears all fourteen findings.

### What the validator reported

- The failing invoice reports **BR-05** and [PEPPOL-EN16931-R051](https://ironfang.uk/docs/finance/rules/PEPPOL-EN16931-R051.md). The corrected document passes every layer with no findings.
  - [Download the failing XML](https://ironfang.uk/finance/rule-examples/BR-05-invalid.xml)
  - [Download the corrected XML](https://ironfang.uk/finance/rule-examples/invoice-minimal.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 UBL `Invoice` and `CreditNote` alike; the element has the same name and position in both. When tried, a credit note without it reported `BR-05` and `PEPPOL-EN16931-R051` on every amount, just as the invoice does.
- While the code is missing, `BR-CO-15` has no document currency to find the VAT total by and passes whatever the totals say. When tried with a total with VAT one pound too high, `BR-CO-15` stayed silent, and of the totals checks only `BR-CO-16` reported anything. Validate again after adding the code before trusting the totals.
- Writing the currency to `cbc:TaxCurrencyCode` instead does not help. That element declares a separate VAT accounting currency; when tried, it left `BR-05` and every `PEPPOL-EN16931-R051` finding in place and added `PEPPOL-EN16931-R054` and `PEPPOL-EN16931-R055`.

## Related rules

- [BR-CL-04 checks that the currency code, once present, is a valid ISO 4217 code](https://ironfang.uk/docs/finance/rules/BR-CL-04.md)
- [PEPPOL-EN16931-R051 compares the currencyID of each amount with this code, and fails on every amount while it is missing](https://ironfang.uk/docs/finance/rules/PEPPOL-EN16931-R051.md)
- [BR-CO-15 locates the VAT total by the document currency, so it cannot check the total with VAT until this code exists](https://ironfang.uk/docs/finance/rules/BR-CO-15.md)
- [BR-CL-03 checks the currency code written on each amount](https://ironfang.uk/docs/finance/rules/BR-CL-03.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-05](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-05/) 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-05)
- [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
