Key points
- Allowance (discount) reason codes are limited to a 19-code subset of UNCL5189; ZZZ is not in it.
- Charge reason codes use the full UNCL7161 list, for example FC freight, DL delivery, PC packing and ZZZ mutually defined.
- Every allowance or charge needs a reason text or a reason code, and document-level ones need their own VAT category.
- The rules that require code and text to match (BR-CO-05 to BR-CO-08) have a test of true(), so they never fire.
- Price-level allowances are allowed but price-level charges are not (PEPPOL-EN16931-R044).
In a Peppol invoice, a discount is an allowance (cbc:ChargeIndicator = false) and a surcharge such as freight is a charge (true). Allowance reason codes must come from a short Peppol subset of UNCL5189, with 95 (Discount) as the general-purpose code. Charge reason codes come from the full UNCL7161 list, such as FC (Freight service) or DL (Delivery). Either way, you may send reason text instead of a code.
Three levels of discount and charge
| Level | UBL location | Allowance | Charge | Affects |
|---|---|---|---|---|
| Document | /Invoice/cac:AllowanceCharge |
BG-20 | BG-21 | BT-107 / BT-108, VAT breakdown |
| Line | cac:InvoiceLine/cac:AllowanceCharge |
BG-27 | BG-28 | Line net amount BT-131 |
| Price | cac:Price/cac:AllowanceCharge |
BT-147 (price discount) | Not allowed | Net unit price BT-146 |
Allowance codes: the Peppol subset of UNCL5189
PEPPOL-EN16931-CL002: "Reason code MUST be according to subset of UNCL 5189 D.16B." BR-CL-19 enforces the same list. The 19 allowed codes, with names from the Peppol code list:
| Code | Name | Code | Name |
|---|---|---|---|
| 41 | Bonus for works ahead of schedule | 71 | Point of sales threshold allowance |
| 42 | Other bonus | 88 | Material surcharge/deduction |
| 60 | Manufacturer's consumer discount | 95 | Discount |
| 62 | Due to military status | 100 | Special rebate |
| 63 | Due to work accident | 102 | Fixed long term |
| 64 | Special agreement | 103 | Temporary |
| 65 | Production error discount | 104 | Standard |
| 66 | New outlet discount | 105 | Yearly turnover |
| 67 | Sample discount | ||
| 68 | End-of-range discount | ||
| 70 | Incoterm discount |
There is no ZZZ for allowances. Our test with ZZZ on a discount failed both BR-CL-19 and CL002. If nothing fits, send text only.
Charge codes: UNCL7161
PEPPOL-EN16931-CL003: "Reason code MUST be according to UNCL 7161 D.16B." The list is long. Codes UK businesses commonly need:
| Code | Name |
|---|---|
| FC | Freight service |
| DL | Delivery |
| SAA | Shipping and handling |
| PC | Packing |
| ABL | Additional packaging |
| SH | Special handling |
| AEO | Collection and recycling |
| FI | Financing |
| IS | Invoicing |
| ADR | Other services |
| ABK | Miscellaneous |
| ZZZ | Mutually defined |
Using an allowance code such as 95 on a charge failed BR-CL-20 and CL003 in our tests.
Rules every allowance and charge must pass
- Reason: BR-33 (allowance) and BR-38 (charge) require a reason text or a reason code. Our test with neither failed BR-33 and BR-CO-21.
- VAT category: BR-32: "Each Document level allowance (BG-20) shall have a Document level allowance VAT category code (BT-95)." BR-37 is the same for charges. Without one, our test also failed BR-S-08, because the VAT breakdown no longer added up.
- Percentages: R041 and R042 say base amount and percentage must come together. R040: "Allowance/charge amount must equal base amount * percentage/100 if base amount and percentage exists", with a tolerance of 0.02.
- Totals: document-level allowances and charges feed BT-107 and BT-108 (
AllowanceTotalAmount,ChargeTotalAmount) and the VAT breakdown for their category and rate.
The rules that never fire
BR-CO-05 to BR-CO-08 say the reason code and reason text "shall indicate the same type". They are published as fatal, but in the 3.0.21 artefacts their test is true(), so they always pass. We sent code 95 (Discount) with the text "Freight charge" and the invoice passed. Your receiver's AP system may still be confused, so keep code and text consistent.
A valid example
A 10% discount on £500 of goods plus £25 freight, both standard rated:
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:AllowanceChargeReasonCode>95</cbc:AllowanceChargeReasonCode>
<cbc:AllowanceChargeReason>Discount</cbc:AllowanceChargeReason>
<cbc:MultiplierFactorNumeric>10</cbc:MultiplierFactorNumeric>
<cbc:Amount currencyID="GBP">50.00</cbc:Amount>
<cbc:BaseAmount currencyID="GBP">500.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>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>true</cbc:ChargeIndicator>
<cbc:AllowanceChargeReasonCode>FC</cbc:AllowanceChargeReasonCode>
<cbc:AllowanceChargeReason>Freight</cbc:AllowanceChargeReason>
<cbc:Amount currencyID="GBP">25.00</cbc:Amount>
<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>
With one £500 line, the totals are: LineExtensionAmount 500.00, AllowanceTotalAmount 50.00, ChargeTotalAmount 25.00, TaxExclusiveAmount 475.00, and a single 20% breakdown with TaxableAmount 475.00 and VAT 95.00. This passed the BIS 3.0.21 rules.
The document-level elements go after cac:PaymentTerms and before cac:TaxTotal. UBL element order is enforced by the schema.
Price-level discounts
A trade discount on the unit price is shown as gross price minus a price allowance:
<cac:Price>
<cbc:PriceAmount currencyID="GBP">45.00</cbc:PriceAmount>
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:Amount currencyID="GBP">5.00</cbc:Amount>
<cbc:BaseAmount currencyID="GBP">50.00</cbc:BaseAmount>
</cac:AllowanceCharge>
</cac:Price>
Two Peppol rules apply. R044: "Charge on price level is NOT allowed. Only value 'false' allowed." R046: "Item net price MUST equal (Gross price - Allowance amount) when gross price is provided." Changing the allowance to 4.00 failed R046, and changing the indicator to true failed R044. BR-27 also says the net price "shall NOT be negative". For a line total that does not equal quantity × price, see PEPPOL-EN16931-R120.
UK VAT: which discounts reduce the taxable amount
Peppol only checks the arithmetic. HMRC decides the VAT value (VAT Notice 700, 7.3.2):
- Unconditional discounts: "the tax value is based on the discounted amount". Send as an allowance on the invoice.
- Prompt payment discounts: "the tax value is based on the actual amount paid". This is not an allowance on the invoice; it is usually stated in the payment terms or handled by credit note.
- Contingent discounts (for example, volume rebates earned later): VAT is on the full amount at first, and "you can adjust the amount of tax by issuing a credit note". See credit notes in Peppol.
If a document-level discount covers lines at different VAT rates, split it into one allowance per rate. One allowance can only carry one VAT category and rate. For delivery on mixed-rate invoices, HMRC's rules on whether delivery is a separate supply apply first.
What to do now
- Map each ERP discount and surcharge type to a code from the right list, or to text only.
- Give every document-level allowance and charge its own VAT category and rate.
- Never put a surcharge at price level.
- Test with the e-invoice validator.
Related: UK VAT category codes in Peppol, VAT rounding in Peppol.
Frequently asked questions
What is the Peppol reason code for a discount?
95 (Discount) is the general code in the UNCL5189 subset Peppol allows. Others include 100 Special rebate, 104 Standard and 105 Yearly turnover. You can also send reason text only, without a code.
Can I use ZZZ for a discount?
No. ZZZ (Mutually defined) is in the charge list UNCL7161 but not in the allowance subset of UNCL5189. Using it on an allowance fails BR-CL-19 and PEPPOL-EN16931-CL002.
What is the code for a delivery charge?
DL (Delivery) or FC (Freight service) from UNCL7161. SAA is Shipping and handling. Each document-level charge also needs a VAT category and rate.
Can I put a surcharge on the unit price?
No. PEPPOL-EN16931-R044 allows only allowances (ChargeIndicator false) at price level. Put the surcharge as a line charge or document-level charge instead.
Spotted a mistake? Report an error. einvoices.uk is an independent publication and is not affiliated with HMRC. Details of the mandate may change; check the sources and official GOV.UK guidance before acting.