Skip to content

BR-CL-03: Use an ISO 4217 currency code in every currencyID attribute

The currencyID of an amount is not a three-letter ISO 4217 code. Use the code of the invoice currency, such as GBP, in upper case.

EN 16931Fatal: the document is invalidCode lists

The short answer

BR-CL-03 fails when the currencyID attribute of an amount is not a code on the ISO 4217 alphabetic list. The finding location is the amount element; set the attribute to the three-letter code of the invoice currency, the same value as cbc:DocumentCurrencyCode.

The UKP in the recorded example looks like a code for pounds sterling but is not one; the ISO code is GBP. Two Peppol rules examine the same attribute, so one bad value produces three findings.

What the rule checks

It checks the currencyID of every cbc:Amount, cbc:BaseAmount, cbc:PriceAmount, cbc:TaxAmount, cbc:TaxableAmount and cbc:LineExtensionAmount, and of the other totals in cac:LegalMonetaryTotal, wherever they appear. Unlike the decimals limit, it covers the item price too.

The attribute is trimmed and then looked up in a fixed list of codes, case-sensitively. When tried, gbp, the numeric code 826, a pound sign and an empty attribute each failed.

Surrounding spaces are forgiven here but not elsewhere. When tried, a leading space before GBP passed this rule and was still reported by PEPPOL-EN16931-CL007 and PEPPOL-EN16931-R051, which compare the attribute exactly as written.

Any listed code passes, including one that differs from the document currency. Matching the invoice currency is the business of PEPPOL-EN16931-R051.

The attribute is required by the UBL schema. When tried, an amount without currencyID failed the XSD layer and this rule was never reached.

TermMeaningUBL element
-Currency of an amount (the currencyID attribute)currencyID on each amount element, for example cac:InvoiceLine/cac:Price/cbc:PriceAmount/@currencyID
BT-5Invoice currency codecbc:DocumentCurrencyCode

How an integration ends up here

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

  • A currency is typed by hand or held in a free-text field, producing values such as UKP or STG.
  • Currency codes are stored in lower case or as ISO numeric codes and written through unchanged.
  • Each kind of amount takes its currency from a different source, and one of them, such as a price list, spells the currency differently.
  • A currency symbol from the display layer is used as the attribute value.

How to fix it

  1. Use the finding location to see which amount carries the bad value, then find where your mapping fills its currencyID.
  2. Fill every currencyID from the same source as cbc:DocumentCurrencyCode, so the codes cannot drift apart.
  3. Write the upper-case ISO 4217 alphabetic code, trimmed. Translate numeric codes, symbols and names where the value enters your system.
  4. The only amount that may carry a different code is the VAT total in the VAT accounting currency, in its own cac:TaxTotal without a breakdown, and that code must match cbc:TaxCurrencyCode.

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 price is labelled UKP

<cac:InvoiceLine>
  <cbc:ID>1</cbc:ID>
  <cbc:InvoicedQuantity unitCode="C62">2</cbc:InvoicedQuantity>
  <cbc:LineExtensionAmount currencyID="GBP">25.00</cbc:LineExtensionAmount>
  <!-- item omitted from this fragment -->
  <cac:Price>
    <cbc:PriceAmount currencyID="UKP">12.5</cbc:PriceAmount>
    <cbc:BaseQuantity unitCode="C62">1</cbc:BaseQuantity>
  </cac:Price>
</cac:InvoiceLine>

Fragment of the corrected invoice: the price is in GBP like every other amount

<cac:InvoiceLine>
  <cbc:ID>1</cbc:ID>
  <cbc:InvoicedQuantity unitCode="C62">2</cbc:InvoicedQuantity>
  <cbc:LineExtensionAmount currencyID="GBP">25.00</cbc:LineExtensionAmount>
  <!-- item omitted from this fragment -->
  <cac:Price>
    <cbc:PriceAmount currencyID="GBP">12.5</cbc:PriceAmount>
    <cbc:BaseQuantity unitCode="C62">1</cbc:BaseQuantity>
  </cac:Price>
</cac:InvoiceLine>

Only the currencyID on cbc:PriceAmount differs: UKP in the failing invoice, GBP in the corrected one. Three findings share that location. BR-CL-03 is the EN 16931 code list check. PEPPOL-EN16931-CL007 is the Peppol layer check of the same attribute against ISO 4217, so a value that is not a listed code fails both. PEPPOL-EN16931-R051 is reported because UKP is not the document currency GBP; it would fire even for a valid code such as EUR. Correcting the attribute clears all three.

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 UBL Invoice and CreditNote. When tried, a credit note with UKP on the price reported the same three rules.
  • The list is the same ISO 4217 snapshot that BR-CL-04 applies to the document currency, so a code that has been withdrawn fails here as well.
  • The rule looks at one attribute at a time. It does not compare amounts with each other or with the document currency, so a mix of valid codes passes it.

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-03 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.