Prevent and handle rounding differences in UBL invoices: PayableRoundingAmount, VAT rounding and VAT-inclusive prices.
One of the most frustrating error messages when sending e-invoices is a rounding difference. The VAT totals do not match the line amounts, or the invoice total deviates by a cent from the calculated sum. The result: the invoice is rejected during validation. This article explains where rounding differences come from and how to prevent or resolve them.
Rounding differences arise from the combination of three factors: multiplication, division and rounding to two decimal places. A few examples:
Unit price with many decimals. A price of 3.333... euros per unit x 3 units = 9.999 euros. Rounded, that is 10.00 euros. But if you first round the unit price to 3.33 and then multiply: 3.33 x 3 = 9.99. A one cent difference.
VAT per line versus VAT per total. If you calculate and round VAT per invoice line and then add them up, the sum may differ from VAT calculated over the total. At 21% VAT on 33.33 euros, that is 7.00 euros (rounded). But 21% of 3 x 33.33 = 21% of 99.99 = 21.00 euros. While 3 x 7.00 = 21.00 euros as well. In this case it matches, but with other amounts it may not.
VAT-inclusive prices. Some sectors (retail, hospitality) work with prices including VAT. The net amount must then be calculated back, which introduces an additional rounding moment.
EN 16931-1:2017 (current production version) requires that all amounts are rounded to 2 decimal places, regardless of currency.
The revision EN 16931-1:2026 (CEN approval 13 March 2026, urn:cen.eu:en16931:2026) replaces this with a currency-dependent number of decimal places: the number of decimal places = the "minor unit" column of ISO 4217 for the currency used. Peppol implementation via OpenPeppol is expected as BIS Billing 4.0 (indicatively 2027). Until that version is in production, the current 2-decimal rule applies.
Exceptions in 2026 (fixed, regardless of currency):
Impact eConnect: outbound invoices are always in euros (minor unit 2) — no change. Inbound invoices may contain currencies with minor unit up to 4 — processing must handle up to 4 decimal places. See also EN 16931-1:2026 major changes for the complete overview.
The UBL standard has a special element for rounding differences: PayableRoundingAmount in the LegalMonetaryTotal block. This element absorbs small rounding differences, so the PayableAmount can be a round number:
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="EUR">99.99</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="EUR">99.99</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="EUR">120.99</cbc:TaxInclusiveAmount>
<cbc:PayableRoundingAmount currencyID="EUR">0.01</cbc:PayableRoundingAmount>
<cbc:PayableAmount currencyID="EUR">121.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>
The 0.01 euro difference is explicitly stated. Validation rules allow a PayableRoundingAmount, provided the difference is small enough (typically a maximum of 1 euro, depending on the profile).
XPath: Invoice/LegalMonetaryTotal/PayableRoundingAmount.
Example 1 (rounding up): TaxInclusiveAmount is 9.99 euro, the desired payable amount is 10.00 euro. Then PayableRoundingAmount = 0.01 euro and PayableAmount = 10.00 euro.
Example 2 (no PayableAmount change): with a 4-decimal price calculation, a sub-micro difference can arise, for example 8.2646 × 1.21 = 10.000166. In that case PayableAmount remains unchanged and no PayableRoundingAmount is needed.
VAT calculation in a UBL invoice works per VAT rate, not per line. All line amounts with the same VAT rate are summed to form the tax base (TaxableAmount), and VAT is calculated on that. This prevents rounding per line and subsequently getting a cumulative rounding difference.
The formula is:
TaxableAmount = sum of LineExtensionAmount per VAT category
- AllowanceTotalAmount per VAT category
+ ChargeTotalAmount per VAT category
TaxAmount = TaxableAmount x Percent / 100 (rounded to 2 decimal places)
Important: always calculate VAT on the total tax base per rate, not per line. Per-line VAT calculation is the most common cause of rounding differences.
With VAT-inclusive prices, the net amount must be calculated back. The standard approach is:
gross / (1 + VAT percentage/100)LineExtensionAmount is this net amountPayableRoundingAmount<!-- Price including VAT: EUR 12.10 per unit, 3 units -->
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="EA">3</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="EUR">30.00</cbc:LineExtensionAmount>
<cac:Price>
<cbc:PriceAmount currencyID="EUR">10.00</cbc:PriceAmount>
</cac:Price>
</cac:InvoiceLine>
In this example, the VAT-inclusive price is 12.10 euros. The net amount is 10.00 euros per unit (12.10 / 1.21). Times 3 = 30.00 euros. VAT: 21% of 30.00 = 6.30 euros. Total: 36.30 euros. That matches exactly 3 x 12.10 euros. But with prices that do not divide neatly, a difference arises.
eConnect validates every invoice for internal consistency. If there is a small rounding difference within tolerance, the invoice is accepted. For larger deviations, you receive a clear error message indicating where the difference lies.
The automatic XML repair function of eConnect can in some cases add a missing PayableRoundingAmount if the difference is smaller than the tolerance threshold. But it is always better to handle rounding correctly in your own software.
TaxExclusiveAmount + TaxAmount must equal TaxInclusiveAmount. And TaxInclusiveAmount minus PrepaidAmount plus PayableRoundingAmount must equal PayableAmount.Calculate VAT per rate (not per line), work internally with more than two decimal places and only round when filling in the XML elements. If despite good rounding a small difference remains, absorb it with the PayableRoundingAmount element.
It is a special UBL element that absorbs small rounding differences in invoice totals. The difference is explicitly stated, so the invoice still validates. Most profiles allow a maximum of 1 euro.
In some cases the automatic XML repair function can add a missing PayableRoundingAmount if the difference is within the tolerance threshold. But it is always better to handle rounding correctly in your own software.
Check your invoice