Skip to content

Ironfang Finance - Rule reference

BR-37: Give each document-level charge a VAT category code

A root-level cac:AllowanceCharge with cbc:ChargeIndicator of true needs a cbc:ID in a cac:TaxCategory under the VAT scheme, or it is taxed nowhere.

EN 16931Fatal: the document is invalidAllowances and chargesVAT

On this page

The short answer

BR-37 fails when a cac:AllowanceCharge directly under the document root, with cbc:ChargeIndicator of true, has no VAT category code: no cac:TaxCategory carrying a cbc:ID under the VAT tax scheme. Add the category the charge is taxed in; in the corrected invoice the 3.50 charge is S at 20.

Each document charge is taxed in its own right and has to be added to the taxable amount of one VAT breakdown. Without a category it lands in none, which in the recorded example shows up as BR-S-08 beside this rule.

What the rule checks

For each root-level cac:AllowanceCharge that reads as a charge, the rule wants a cac:TaxCategory with a cbc:ID child and a cac:TaxScheme/cbc:ID of VAT, compared after trimming and upper-casing. When tried, vat in lower case passed.

The scheme is part of the test. When tried with GST as the scheme of the charge, BR-37 was reported on its own: the Standard rated breakdown check does not read the scheme of a charge, so it went on counting the 3.50 and passed.

Only the presence of the code element is tested here. When tried, an empty cbc:ID in the charge category got past BR-37 and was reported by BR-CL-17 and PEPPOL-EN16931-R008, and by BR-S-08, because an empty code is not S.

When tried, a charge with no cac:TaxCategory at all reported the same two rules as the recorded example.

Charges on a line are not covered. They have no category of their own and are taxed with the line, as part of its net amount.

TermMeaningUBL element
BG-21Document level chargescac:AllowanceCharge[cbc:ChargeIndicator = true]
BT-102Document level charge VAT category codecac:AllowanceCharge/cac:TaxCategory/cbc:ID
BT-103Document level charge VAT ratecac:AllowanceCharge/cac:TaxCategory/cbc:Percent

How an integration ends up here

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

  • Freight, packing or handling charges are added as a header amount by a module that knows nothing about VAT.
  • The charge mapping copies the reason and amount from the order, and the tax attributes stay behind on the order lines.
  • The source holds a rate for the charge but no category code, so the mapping writes cbc:Percent and the tax scheme and leaves out cbc:ID, as in the recorded example.
  • Tax attributes use a local scheme name in the source, and cac:TaxScheme/cbc:ID is written with that name instead of VAT.

How to fix it

  1. Establish how the charge is taxed, from the tax setup of the charge type or of the supplies it goes with.
  2. Add cbc:ID as the first child of the charge cac:TaxCategory, followed by cbc:Percent and cac:TaxScheme/cbc:ID of VAT. The category comes after cbc:Amount and cbc:BaseAmount.
  3. When one charge covers supplies taxed differently, split it into one charge per category and rate. The charge total stays the same.
  4. Add the charge to the taxable amount of its VAT breakdown and recompute the VAT there. BR-S-08 and the matching rules for other categories check that sum.

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 charge category has a rate and a scheme but no code

<cac:AllowanceCharge>
  <cbc:ChargeIndicator>true</cbc:ChargeIndicator>
  <cbc:AllowanceChargeReasonCode>CG</cbc:AllowanceChargeReasonCode>
  <cbc:AllowanceChargeReason>Example document charge</cbc:AllowanceChargeReason>
  <cbc:MultiplierFactorNumeric>10</cbc:MultiplierFactorNumeric>
  <cbc:Amount currencyID="GBP">3.50</cbc:Amount>
  <cbc:BaseAmount currencyID="GBP">35.00</cbc:BaseAmount>
  <cac:TaxCategory>
    <cbc:Percent>20</cbc:Percent>
    <cac:TaxScheme>
      <cbc:ID>VAT</cbc:ID>
    </cac:TaxScheme>
  </cac:TaxCategory>
</cac:AllowanceCharge>

Fragment of the corrected invoice: the charge is Standard rated, code S at 20

<cac:AllowanceCharge>
  <cbc:ChargeIndicator>true</cbc:ChargeIndicator>
  <cbc:AllowanceChargeReasonCode>CG</cbc:AllowanceChargeReasonCode>
  <cbc:AllowanceChargeReason>Example document charge</cbc:AllowanceChargeReason>
  <cbc:MultiplierFactorNumeric>10</cbc:MultiplierFactorNumeric>
  <cbc:Amount currencyID="GBP">3.50</cbc:Amount>
  <cbc:BaseAmount currencyID="GBP">35.00</cbc:BaseAmount>
  <cac:TaxCategory>
    <cbc:ID>S</cbc:ID>
    <cbc:Percent>20</cbc:Percent>
    <cac:TaxScheme>
      <cbc:ID>VAT</cbc:ID>
    </cac:TaxScheme>
  </cac:TaxCategory>
</cac:AllowanceCharge>

The corrected invoice opens the charge cac:TaxCategory with cbc:ID of S; in the failing invoice the category keeps its rate of 20 and its VAT scheme but has no code. The failing document also reports BR-S-08. Without a category the 3.50 charge no longer counts towards the Standard rated breakdown, whose calculated base drops to 56.00 of lines minus the 1.00 allowance, or 55.00, against a taxable amount of 58.50. Restoring the code clears both.

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. When tried, the credit note version of the recorded example reported BR-37 at cac:AllowanceCharge[2] together with BR-S-08.
  • The index in the finding location counts every root-level cac:AllowanceCharge, allowances included: the charge here is the second, after the document discount.
  • The breakdown rule that comes with it follows the category the charge should have had: BR-S-08 here, because the charge belongs in the Standard rated breakdown.
  • Once the code is S, the charge also needs a rate above zero, which BR-S-07 checks.

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 BR-37 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.