Amounts, roundings and totals
When you push e-commerce sales into an accounting system, the numbers have to hold together to the cent: the sum of your revenue lines, fees and VAT must match the order total, and the resulting entry must balance. This guide explains how e-commerce order amounts are exposed by the Unified API and the method we recommend to keep them correct once booked. The sections below cover the decimal precision of the amounts you receive, the rounding rule to apply, how to handle VAT, how to split a global discount, the e-commerce‑specific points on fees and refunds, and the final reconciliation check.This guide describes the recommended method, not a constraint enforced by the API. When you consume the e-commerce Unified API and write the result yourself into accounting, the rounding responsibility is on your side. If you post through Chift’s accounting Unified API, see also Invoice amounts validation.
🔢 1. Decimal precision
E-commerce amounts may be returned with more than 2 decimals in the API response — for exampleunit_price and untaxed_amount can carry up to 4 decimals, because net amounts are frequently derived from a gross total or a discount and that finer precision is preserved.
Treat every monetary value from the API as raw input. Do not assume it is already at 2 decimals, and do not compare two amounts for equality without rounding both first.
🧮 2. Rounding rule
Apply a single, consistent rounding rule to every amount before you book it: 2 decimals, round half up. Examples:- an
untaxed_amountof19.6694is booked as19.67 - a net computed as
2.5950413…is booked as2.60
Avoid the “banker’s rounding” (round half to even) that is the default in some languages and libraries, as it will drift against amounts computed the standard commercial way.
🧾 3. Handle VAT per rate
Reuse the tax amounts provided by the API rather than recomputing them. Each line (lines) and each fee (other_fees) exposes its own untaxed_amount, tax_amount, total, tax_rate and tax_id. Reusing these values avoids introducing a rounding error that the source system does not have. At order level you also have untaxed_amount, tax_amount and total.
If you must derive VAT from a gross (tax‑inclusive) amount and a rate, use the remainder method so that net + VAT always equals the exact gross:
gross = 3.14, tax_rate = 21
net = round(3.14 / 1.21, 2) = 2.60vat = 3.14 − 2.60 = 0.54.
tax_rate before computing net and VAT — never on a single global total, which would hide compensating rounding differences between rates. Note that tax_rate itself is returned rounded to 2 decimals (e.g. 21.0).
➗ 4. Splitting a global discount
The order exposesdiscount_amount at order level, while line and fee discounts appear in each element’s discounts array. When a discount applies to the whole order rather than to a single line, spread it across the VAT rates pro rata of each rate’s base. To avoid a missing cent, give the remainder to the last bucket instead of rounding it independently:
📦 5. Fees and refunds
Three e-commerce‑specific points determine whether your revenue matches the order total:- Include fees.
other_fees(for example shipping) each carry their owntax_rate/tax_idand base, and are part of the order total. Book them per rate like any revenue line. Thetotal_without_fees/untaxed_amount_without_feesfields let you separate goods from fees when needed. totalexcludes refunds and returns. Thetotal,tax_amountanduntaxed_amountfields are the order before refunds and returns. Thecurrent_total,current_tax_amountandcurrent_untaxed_amountfields are the amounts after returns and removals. Use the set that matches what you intend to book, and do not mix the two.- Treat refunds separately.
refunded_amount,detailed_refundsandreturnsdescribe money given back. Book refunds as their own entry (or reverse lines) per VAT rate — never net a refund inside the original sale’s VAT base.
The net (HT) of a line is
untaxed_amount, or equivalently total − tax_amount once both are rounded to 2 decimals. Pick one convention and apply it consistently across all lines.✅ 6. Reconcile and balance
After rounding each amount per rate to 2 decimals independently, a residual difference of a few cents can remain between the sum of your booked lines (net + VAT) and the ordertotal. Book that residue on a rounding account so the entry balances (debit = credit):
- a gain account for a positive difference (e.g.
758); - a loss account for a negative difference (e.g.
658).
A residue of a cent or two is normal rounding and belongs on the rounding account. A difference larger than ~1 € is not a rounding issue — it signals inconsistent source data (or the wrong
total vs current_total set). Stop and investigate rather than absorbing it.In short
Round every amount to 2 decimals half‑up, reuse the VAT provided by the API, reason per rate, split global discounts with the remainder on the last bucket, include fees and keep refunds/returns separate (watchtotal vs current_total), and close each entry with a reconciliation that sends any residual cent to a rounding account. This is what keeps your accounting totals equal to the original e-commerce amounts.