# PEPPOL-EN16931-R040: Fix an allowance or charge amount that does not match its base amount and percentage

When an allowance or charge states both a base amount and a percentage, its amount must be base times percentage over 100, within 0.02.

- Layer: Peppol BIS Billing
- Severity: fatal (the document is invalid)
- Topics: Allowances and charges
- Official definition: https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-peppol/PEPPOL-EN16931-R040/
- Explanation last updated: 2026-09-20

## The short answer

`PEPPOL-EN16931-R040` fails when a `cac:AllowanceCharge` carries both `cbc:BaseAmount` and `cbc:MultiplierFactorNumeric`, and `cbc:Amount` is more than 0.02 away from base amount x percentage / 100. Find which of the three values is wrong in the source data and correct that one.

`cbc:MultiplierFactorNumeric` is a percentage: 10 means ten per cent. It is not a multiplier such as 0.1.

## What the rule checks

The rule runs on every `cac:AllowanceCharge` directly under the document root and directly under a line. Allowances and charges are treated the same way; `cbc:ChargeIndicator` plays no part. The allowance inside `cac:Price` is not covered.

If either `cbc:BaseAmount` or `cbc:MultiplierFactorNumeric` is absent, this rule has nothing to check and passes. An allowance or charge with neither element, only a fixed `cbc:Amount`, is fine.

When both are present, the expected amount is base amount x percentage / 100. The product is not rounded. The rule passes when `cbc:Amount` is within 0.02 of it, and the limit is inclusive: exactly 0.02 out passes, anything over fails.

Confirmed with the validator on an amount of 3.50 at 10 per cent: a base of 35.20 (expected 3.52, 0.02 out) passes; a base of 35.21 (expected 3.521) fails; a base of 35.30 (expected 3.53) fails. The same holds below the amount, and for a line-level allowance.

A percentage of 0 with a base amount expects an amount of 0, so a non-zero amount fails.

| Term | Meaning | UBL element |
|---|---|---|
| BG-20 | Document level allowances | `cac:AllowanceCharge[cbc:ChargeIndicator = false]` |
| BG-21 | Document level charges | `cac:AllowanceCharge[cbc:ChargeIndicator = true]` |
| BG-27 | Invoice line allowances | `cac:InvoiceLine/cac:AllowanceCharge[cbc:ChargeIndicator = false]` |
| BG-28 | Invoice line charges | `cac:InvoiceLine/cac:AllowanceCharge[cbc:ChargeIndicator = true]` |

## How an integration ends up here

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

- The percentage is sent as a fraction, 0.1 for ten per cent, so the expected amount is a hundredth of what was intended.
- The base amount is taken from a different figure than the one the discount was calculated on, for example the gross line value instead of the value after an earlier discount.
- The amount was negotiated or edited by hand after the percentage was applied, and the percentage and base were left as they were.
- Several percentage discounts are compounded in the source system but sent as one allowance with the first percentage only.
- The amount is rounded per unit and multiplied up, which drifts more than 0.02 from a single calculation on the whole base.

## How to fix it

1. Take the failing `cac:AllowanceCharge` from the finding location and compute `cbc:BaseAmount` x `cbc:MultiplierFactorNumeric` / 100 with decimal arithmetic.
2. Decide which value is wrong by going back to the commercial terms. If the percentage or base is wrong, correct it and leave the amount alone.
3. If the amount is wrong, correct it and then recalculate everything that depends on it: the line net amount for a line-level entry, or the allowance or charge total, the VAT breakdown and the document totals for a document-level entry.
4. If the amount is a fixed sum that was never derived from a percentage, send `cbc:Amount` on its own and drop both `cbc:BaseAmount` and `cbc:MultiplierFactorNumeric`. Dropping only one of them fails `PEPPOL-EN16931-R041` or `PEPPOL-EN16931-R042` instead.

The recorded example is a document-level charge of 3.50 on a base of 35.00.

```text
Failing: 35.00 x 20 / 100 = 7.00, amount sent 3.50, difference 3.50
Corrected: 35.00 x 10 / 100 = 3.50, amount sent 3.50, difference 0.00
Allowed difference: up to and including 0.02
```

## Before and after

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

Fragment of the failing invoice: 20 per cent of 35.00 is 7.00, but the charge amount is 3.50

```xml
<cac:AllowanceCharge>
  <cbc:ChargeIndicator>true</cbc:ChargeIndicator>
  <cbc:AllowanceChargeReasonCode>CG</cbc:AllowanceChargeReasonCode>
  <cbc:AllowanceChargeReason>Example document charge</cbc:AllowanceChargeReason>
  <cbc:MultiplierFactorNumeric>20</cbc:MultiplierFactorNumeric>
  <cbc:Amount currencyID="GBP">3.50</cbc:Amount>
  <cbc:BaseAmount currencyID="GBP">35.00</cbc:BaseAmount>
  <!-- tax category omitted from this fragment -->
</cac:AllowanceCharge>
```

Fragment of the corrected invoice: 10 per cent of 35.00 is the 3.50 that was charged

```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>
  <!-- tax category omitted from this fragment -->
</cac:AllowanceCharge>
```

Only `cbc:MultiplierFactorNumeric` differs: 20 in the failing document, 10 in the corrected one. The failing document reports only `PEPPOL-EN16931-R040`, because the amount of 3.50 still agrees with the charge total and the rest of the totals. Had the amount been changed instead, the charge total would have stopped matching: with the amount at 3.53 and nothing else touched, the validator reports `BR-CO-12` as well as this rule.

### What the validator reported

- The failing invoice reports **PEPPOL-EN16931-R040**. The corrected document passes every layer with no findings.
  - [Download the failing XML](https://ironfang.uk/finance/rule-examples/PEPPOL-EN16931-R040-invalid.xml)
  - [Download the corrected XML](https://ironfang.uk/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 UBL `Invoice` and `CreditNote`, at document level and on `cac:InvoiceLine` or `cac:CreditNoteLine`. Confirmed on credit notes at both levels.
- The allowance inside `cac:Price` is outside this rule. A percentage added there draws warnings `UBL-CR-635` and `UBL-CR-671` and no finding from this rule.
- The pinned test reads a missing `cbc:Amount` as 0, but the full pipeline never gets that far: a `cac:AllowanceCharge` without `cbc:Amount` is refused by the XSD layer and the later layers are skipped.
- The rule does not check that the base amount is the right base, only that the three numbers agree with each other.

## Related rules

- [PEPPOL-EN16931-R041 fails when a percentage is sent without a base amount](https://ironfang.uk/docs/finance/rules/PEPPOL-EN16931-R041.md)
- [PEPPOL-EN16931-R042 fails when a base amount is sent without a percentage](https://ironfang.uk/docs/finance/rules/PEPPOL-EN16931-R042.md)
- [BR-CO-12 checks the charge total once a document-level charge amount changes](https://ironfang.uk/docs/finance/rules/BR-CO-12.md)
- [BR-CO-11 checks the allowance total once a document-level allowance amount changes](https://ironfang.uk/docs/finance/rules/BR-CO-11.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-20.

[The official definition of PEPPOL-EN16931-R040](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-peppol/PEPPOL-EN16931-R040/) 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/PEPPOL-EN16931-R040)
- [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
