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

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

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

| Term | Meaning | UBL element |
|---|---|---|
| BG-21 | Document level charges | `cac:AllowanceCharge[cbc:ChargeIndicator = true]` |
| BT-102 | Document level charge VAT category code | `cac:AllowanceCharge/cac:TaxCategory/cbc:ID` |
| BT-103 | Document level charge VAT rate | `cac: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.

## 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

```xml
<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

```xml
<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

- The failing invoice reports **BR-37** and [BR-S-08](https://ironfang.com/docs/finance/rules/BR-S-08.md). The corrected document passes every layer with no findings.
  - [Download the failing XML](https://ironfang.com/finance/rule-examples/BR-37-invalid.xml)
  - [Download the corrected XML](https://ironfang.com/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`. 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.

## Related rules

- [BR-32 is the same requirement for document-level allowances](https://ironfang.com/docs/finance/rules/BR-32.md)
- [BR-S-08 adds Standard rated document charges to the taxable amount, and fails when this one has no category](https://ironfang.com/docs/finance/rules/BR-S-08.md)
- [BR-14 requires the total with VAT, where the charge and the VAT on it both end up](https://ironfang.com/docs/finance/rules/BR-14.md)
- [BR-CO-24 deals with charges on a line, which need a reason but take their VAT category from the line](https://ironfang.com/docs/finance/rules/BR-CO-24.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-28.1: source checked 2026-09-28, explanation last updated 2026-09-28.

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

## Links

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