Surcharges and discounts in a UBL invoice

AllowanceCharge in UBL invoices: the difference between document and line level, VAT calculation and XML examples.

Almost every organisation works with discounts or surcharges on invoices. A volume discount, shipping costs, an early booking discount, environmental charges: these are all amounts that affect the final invoice total. In a UBL invoice, they are recorded via the AllowanceCharge element, and this can be done at two levels. The difference between these levels is essential for keeping the invoice calculation correct.

Two levels: document and line

UBL supports surcharges and discounts in two places:

Document level: the AllowanceCharge element is placed directly under the root element of the invoice, before the VAT totals. Document-level discounts reduce the total invoice amount. Document-level surcharges increase it. They are included in the VAT calculation.

Line level: the AllowanceCharge element is placed within an InvoiceLine. Line-level discounts and surcharges are already reflected in the LineExtensionAmount of that line. They affect the line price, not the invoice total as such.

The difference is subtle but important. A discount at document level is separately visible in the invoice totals (in AllowanceTotalAmount). A discount at line level is reflected in the line amount and therefore invisible in the totals.

AllowanceCharge at document level

Each document-level discount or surcharge contains at minimum these elements:

<cac:AllowanceCharge>
  <cbc:ChargeIndicator>false</cbc:ChargeIndicator>
  <cbc:AllowanceChargeReasonCode>95</cbc:AllowanceChargeReasonCode>
  <cbc:AllowanceChargeReason>Volume discount Q1 2026</cbc:AllowanceChargeReason>
  <cbc:Amount currencyID="EUR">150.00</cbc:Amount>
  <cac:TaxCategory>
    <cbc:ID>S</cbc:ID>
    <cbc:Percent>21.00</cbc:Percent>
    <cac:TaxScheme>
      <cbc:ID>VAT</cbc:ID>
    </cac:TaxScheme>
  </cac:TaxCategory>
</cac:AllowanceCharge>

The ChargeIndicator determines whether it is a surcharge (true) or a discount (false). The AllowanceChargeReasonCode is a code from the UNCL5189 list (for discounts) or UNCL7161 (for surcharges). Commonly used codes include:

CodeTypeMeaning41DiscountBonus for early payment42DiscountIntroductory discount60DiscountManufacturer's discount95DiscountDiscount100DiscountSpecial agreementABLSurchargePackaging costsFCSurchargeFreight chargesAEWSurchargeEnvironmental surcharge

Tip: if none of the standard codes fits exactly, use code 95 (discount) or the most relevant surcharge code, and describe the reason in AllowanceChargeReason.

Effect on invoice totals

Document-level discounts and surcharges are reflected in the LegalMonetaryTotal:

<cac:LegalMonetaryTotal>
  <cbc:LineExtensionAmount currencyID="EUR">1000.00</cbc:LineExtensionAmount>
  <cbc:AllowanceTotalAmount currencyID="EUR">150.00</cbc:AllowanceTotalAmount>
  <cbc:TaxExclusiveAmount currencyID="EUR">850.00</cbc:TaxExclusiveAmount>
  <cbc:TaxInclusiveAmount currencyID="EUR">1028.50</cbc:TaxInclusiveAmount>
  <cbc:PayableAmount currencyID="EUR">1028.50</cbc:PayableAmount>
</cac:LegalMonetaryTotal>

The calculation: 1,000 (line total) minus 150 (discount) = 850 excluding VAT. Plus 178.50 VAT (21% of 850) = 1,028.50 including VAT.

AllowanceCharge at line level

At line level it works differently. The discount or surcharge is already reflected in the LineExtensionAmount. The AllowanceCharge element on the line serves as clarification:

<cac:InvoiceLine>
  <cbc:ID>1</cbc:ID>
  <cbc:InvoicedQuantity unitCode="EA">100</cbc:InvoicedQuantity>
  <cbc:LineExtensionAmount currencyID="EUR">850.00</cbc:LineExtensionAmount>
  <cac:AllowanceCharge>
    <cbc:ChargeIndicator>false</cbc:ChargeIndicator>
    <cbc:AllowanceChargeReasonCode>95</cbc:AllowanceChargeReasonCode>
    <cbc:AllowanceChargeReason>Volume tier discount</cbc:AllowanceChargeReason>
    <cbc:Amount currencyID="EUR">150.00</cbc:Amount>
    <cbc:BaseAmount currencyID="EUR">1000.00</cbc:BaseAmount>
  </cac:AllowanceCharge>
  <cac:Item>
    <cbc:Name>Widget standard</cbc:Name>
    <cac:ClassifiedTaxCategory>
      <cbc:ID>S</cbc:ID>
      <cbc:Percent>21.00</cbc:Percent>
      <cac:TaxScheme>
        <cbc:ID>VAT</cbc:ID>
      </cac:TaxScheme>
    </cac:ClassifiedTaxCategory>
  </cac:Item>
  <cac:Price>
    <cbc:PriceAmount currencyID="EUR">8.50</cbc:PriceAmount>
  </cac:Price>
</cac:InvoiceLine>

The LineExtensionAmount here is 850 euros: 100 units x 10 euros = 1,000 euros, minus 150 euros volume tier discount. The BaseAmount in the AllowanceCharge shows the original amount before discount. The PriceAmount (8.50) is the effective unit price after discount.

Note: the LineExtensionAmount must always be the net amount after discount/surcharge. The AllowanceCharge on the line is informational. Do not deduct it again from the line amount, as that would make the invoice incorrect.

VAT calculation with multiple discounts

When an invoice contains both line discounts and document discounts, the VAT tax bases are calculated as follows:

  1. Per invoice line: the LineExtensionAmount (already including line discounts)
  2. Per VAT category: sum of all line amounts in that category
  3. Minus document discounts in that same category
  4. Plus document surcharges in that same category
  5. The result is the TaxableAmount in the TaxSubtotal

VAT is calculated on that net tax base. This is why it is essential that each document discount and surcharge carries a VAT category: the system needs to know which rate the discount belongs to.

Pro-rata allocation with multiple VAT rates

When a document-level AllowanceCharge applies to an invoice with lines in different VAT rates (for example 9% and 21%), the discount or surcharge amount must be allocated pro-rata across the VAT categories. This means: proportionally to each category's share of the total taxable amounts.

For example, if an invoice contains 2,000 euros of lines at 21% VAT and 1,000 euros of lines at 9% VAT, a document discount of 300 euros must be split into two separate AllowanceCharge elements: 200 euros at 21% (two thirds) and 100 euros at 9% (one third). The tax base per category is then calculated correctly.

AllowanceCharge at price level

In addition to document and line level, UBL has a third place for discounts: within the Price element of an invoice line. This mechanism shows the difference between the gross price and the net unit price.

<cac:Price>
  <cbc:PriceAmount currencyID="EUR">8.50</cbc:PriceAmount>
  <cbc:BaseQuantity unitCode="EA">1</cbc:BaseQuantity>
  <cac:AllowanceCharge>
    <cbc:ChargeIndicator>false</cbc:ChargeIndicator>
    <cbc:Amount currencyID="EUR">1.50</cbc:Amount>
    <cbc:BaseAmount currencyID="EUR">10.00</cbc:BaseAmount>
  </cac:AllowanceCharge>
</cac:Price>

In this example, the gross price (BaseAmount) is 10.00 euros. After deducting 1.50 euros discount, the net unit price (PriceAmount) of 8.50 euros remains.

At price level, only ChargeIndicator=false (discount) is allowed. Surcharges (ChargeIndicator=true) are not permitted here. Additionally, validation rule BR-28 applies: the gross price (BaseAmount) may not be negative. If you want to apply a surcharge to the unit price, process it as an AllowanceCharge at line level or include the increased price directly as PriceAmount.

Discount exceeding the item price

A special case occurs when a line discount (AllowanceCharge at line level) exceeds the item price. Peppol validation rule R120 checks whether LineExtensionAmount = (Quantity × PriceAmount ÷ BaseQuantity) + surcharges − discounts. R120 does not explicitly prohibit negative amounts; validation fails when this calculation is not balanced. When the discount exceeds the price, there is a high chance the calculation will not add up.

This scenario occurs in practice with credit notes that have large discounts. The solution: use the net credit amount (the difference between price and discount) directly as PriceAmount and omit the AllowanceCharge element on the line. You can record the original price and the applied discount for reference in the Item/Name field or in a Note element on the invoice line.

Note: this workaround is intended for situations where the discount exceeds the price. For regular discounts that remain below the price, simply use the AllowanceCharge element on the line.

Combining with early payment discounts

An early payment discount (skonto) is something entirely different from an invoice discount. An invoice discount via AllowanceCharge is unconditional and directly reduces the invoice amount. An early payment discount is conditional (dependent on the payment term) and is not reflected in the invoice amount. See the article on early payment discounts for details.

Tip: if you are unsure whether your AllowanceCharge is correctly included, run the invoice through the free eConnect Validator. It checks whether the VAT tax bases are correctly calculated after deduction of discounts and surcharges.


Validate your invoice