# BR-45: Add the taxable amount to each VAT breakdown

Every `cac:TaxSubtotal` needs a `cbc:TaxableAmount`: the net amount on which the VAT in that breakdown is calculated.

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

## The short answer

`BR-45` fails for each `cac:TaxSubtotal` that has no `cbc:TaxableAmount` child. Add it as the first child of the subtotal, holding the net total for that category and rate: the line net amounts, plus document-level charges, minus document-level allowances, in the document currency.

Expect the arithmetic rules for the breakdown to fail beside it. They start from the taxable amount and cannot pass while it is missing.

## What the rule checks

The rule runs on every `cac:TaxSubtotal` inside a `cac:TaxTotal` and passes when a `cbc:TaxableAmount` element is present. The finding location is the subtotal that lacks one.

UBL treats the element as optional, so a missing taxable amount passes the XSD layer and is first reported here. An empty `cbc:TaxableAmount` is a different case: it is not a valid amount, and when tried it failed the XSD layer, so this rule and the rest of the business rules never ran.

Any value satisfies this rule, zero included. When tried, a taxable amount of 0.00 on a 20% breakdown with 5.00 of tax cleared `BR-45` and still reported `BR-CO-17`, `BR-S-08` and `BR-S-09`.

The category makes no difference to this rule. An exempt breakdown without a taxable amount reported it together with `BR-E-08`, the exempt taxable amount check, when tried.

| Term | Meaning | UBL element |
|---|---|---|
| BG-23 | VAT breakdown | `cac:TaxTotal/cac:TaxSubtotal` |
| BT-116 | VAT category taxable amount | `cac:TaxTotal/cac:TaxSubtotal/cbc:TaxableAmount` |

## How an integration ends up here

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

- The breakdown is built from a VAT summary that stores only rate and tax, and the net amount per rate is never carried across.
- The taxable amount is optional in the mapping and is dropped when null, for example on a breakdown created by a manual VAT adjustment.
- A zero taxable amount is treated as having no value and suppressed by the serialiser.

## How to fix it

1. For each `cac:TaxSubtotal`, read its category and rate from `cac:TaxCategory`.
2. Sum the `cbc:LineExtensionAmount` of the lines in that category and rate, add the root-level charges and subtract the root-level allowances in the same category and rate, using decimal arithmetic.
3. Write the result as `cbc:TaxableAmount`, with the document currency in `currencyID`, as the first child of the subtotal and before `cbc:TaxAmount`.
4. Check the subtotal `cbc:TaxAmount` against the restored figure, since `BR-CO-17` and the category rule compare it with taxable amount x rate / 100.

## 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 VAT breakdown has a tax amount but no taxable amount

```xml
<cac:TaxTotal>
  <cbc:TaxAmount currencyID="GBP">5.00</cbc:TaxAmount>
  <cac:TaxSubtotal>
    <cbc:TaxAmount currencyID="GBP">5.00</cbc:TaxAmount>
    <cac:TaxCategory>
      <cbc:ID>S</cbc:ID>
      <cbc:Percent>20</cbc:Percent>
      <cac:TaxScheme>
        <cbc:ID>VAT</cbc:ID>
      </cac:TaxScheme>
    </cac:TaxCategory>
  </cac:TaxSubtotal>
</cac:TaxTotal>
```

Fragment of the corrected invoice: the taxable amount of 25.00 opens the breakdown

```xml
<cac:TaxTotal>
  <cbc:TaxAmount currencyID="GBP">5.00</cbc:TaxAmount>
  <cac:TaxSubtotal>
    <cbc:TaxableAmount currencyID="GBP">25.00</cbc:TaxableAmount>
    <cbc:TaxAmount currencyID="GBP">5.00</cbc:TaxAmount>
    <cac:TaxCategory>
      <cbc:ID>S</cbc:ID>
      <cbc:Percent>20</cbc:Percent>
      <cac:TaxScheme>
        <cbc:ID>VAT</cbc:ID>
      </cac:TaxScheme>
    </cac:TaxCategory>
  </cac:TaxSubtotal>
</cac:TaxTotal>
```

The corrected invoice has `<cbc:TaxableAmount currencyID="GBP">25.00</cbc:TaxableAmount>` at the start of the subtotal; nothing else differs. The failing document reports three more rules, all because the base figure is gone. `BR-CO-17` and `BR-S-09` multiply the taxable amount by the rate to check the 5.00 of tax, and without a taxable amount there is no product to compare. `BR-S-08` compares the Standard rated taxable amount with the 25.00 line and finds no amount on the breakdown side. Restoring the element clears all four.

### What the validator reported

- The failing invoice reports **BR-45**, [BR-CO-17](https://ironfang.uk/docs/finance/rules/BR-CO-17.md), [BR-S-08](https://ironfang.uk/docs/finance/rules/BR-S-08.md) and [BR-S-09](https://ironfang.uk/docs/finance/rules/BR-S-09.md). The corrected document passes every layer with no findings.
  - [Download the failing XML](https://ironfang.uk/finance/rule-examples/BR-45-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`. A credit note missing the taxable amount reported the same four rules when tried.
- Reported by the EN 16931 layer; the Peppol layer passes the recorded example.
- Which arithmetic rules come along depends on the category of the breakdown: `BR-S-08` and `BR-S-09` for Standard rated, `BR-E-08` for exempt, and the matching rules for the other categories.
- The tax total in a VAT accounting currency has no subtotal, so it has no taxable amount and is not checked here.

## Related rules

- [BR-CO-17 checks each breakdown tax amount against the taxable amount and rate](https://ironfang.uk/docs/finance/rules/BR-CO-17.md)
- [BR-S-08 checks the Standard rated taxable amount against the lines, allowances and charges](https://ironfang.uk/docs/finance/rules/BR-S-08.md)
- [BR-S-09 repeats the tax calculation for Standard rated breakdowns](https://ironfang.uk/docs/finance/rules/BR-S-09.md)
- [BR-E-08 checks the exempt taxable amount and comes with this rule on an exempt breakdown](https://ironfang.uk/docs/finance/rules/BR-E-08.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-45](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-45/) 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-45)
- [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
