Skip to main content

Amounts, roundings and totals

When you push e-commerce sales into an accounting system, the numbers must match to the cent. The sum of your revenue lines, fees, and VAT must equal the order total, and the resulting entry must balance. This guide explains how the Unified API exposes e-commerce order amounts, 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 the API enforces. When you consume the e-commerce Unified API and write the result into accounting yourself, you are responsible for rounding. If you post through Chift’s accounting Unified API, see also Invoice amounts validation.

🔢 1. Decimal precision

The API response may return e-commerce amounts with more than 2 decimals. For example, unit_price and untaxed_amount can carry up to 4 decimals. The API frequently derives net amounts from a gross total or a discount, and it keeps that finer precision.
Treat every monetary value from the API as raw input. Do not assume it is already at 2 decimals. Do not compare two amounts for equality before you round both.

🧮 2. Rounding rule

The API delivers amounts with up to 4 decimal places. Apply a single, consistent rounding rule to every amount before you book it into accounting: 2 decimals, round half up. Examples:
  • an untaxed_amount of 19.6694 becomes 19.67
  • a computed net of 2.5950413… becomes 2.60
Avoid “banker’s rounding” (round half to even), which is the default in some languages and libraries. It drifts from amounts that use standard commercial rounding.

🧾 3. Handle VAT per rate

Reuse the amounts the API provides. Do not recompute them. The API always returns untaxed_amount (net) and tax_amount (VAT) at line, fee, and order level. Chift takes them from the e‑commerce software when the software provides them, and computes them with the method below when the software does not. Recomputing them yourself from a rate adds a rounding error that the reconciled value does not have. Each line (lines) and each fee (other_fees) exposes, for one rate:
  • tax_rate: the VAT rate (for example, 21).
  • untaxed_amount: the net (tax‑exclusive) amount, already discounted.
  • tax_amount: the VAT amount.
  • total: the tax‑inclusive amount (TTC).
  • tax_id: the tax identifier.
Book untaxed_amount on the revenue account and tax_amount on the VAT account, per rate. You can also check net = total - tax_amount once you round both to 2 decimals. The order level also exposes untaxed_amount, tax_amount, and total.
This is how Chift derives the net and tax when the e‑commerce software provides only a tax‑inclusive amount and a rate. Chift applies it for you and returns the result, so use the values directly. It is shown here to explain the amounts you receive:
Example: total = 3.14, tax_rate = 21
  • net = 3.14 / 1.21 = 2.5950…, returned at 4 decimals as 2.5950
  • vat = 3.14 - 2.5950 = 0.5450
Always reason per VAT rate (and, if you map revenue to several accounts, per account × rate). Aggregate your amounts by rate before you book them. Never collapse everything into a single global total, which would hide compensating rounding differences between rates. Note that the API returns tax_rate rounded to 2 decimals for lines and 3 decimals for fees (for example, 21.0).

➗ 4. Splitting a global discount

This split applies only when you consume the Unified API and book to accounting yourself. Chift’s Sync performs it automatically.
Each line and fee total and untaxed_amount already include their own discount. The order‑level discount_amount is the sum of those line and fee discounts plus any remaining global discount, and it is tax‑inclusive:
Only remaining_global_discount needs to be split across VAT rates. Because line and fee totals are already discounted, do not re‑apply discount_amount on top of them, or you double‑count. Compute the residual, then spread it pro rata of each rate’s tax‑inclusive total. To avoid a missing cent, give the remainder to the last bucket rather than round it separately:
Here rate_total is the tax‑inclusive total for that rate and items_total is the tax‑inclusive total of all lines and fees. Each share is tax‑inclusive. Get its net part by dividing by the rate:
This guarantees that the sum of the per‑rate discount shares equals the remaining global discount exactly.

📦 5. Fees and refunds

Three e-commerce‑specific points determine whether your revenue matches the order total:
  • Include fees. Each other_fees entry (for example, shipping) has its own tax_rate / tax_id and base, and belongs to the order total. Book them per rate, like any revenue line. The total_without_fees / untaxed_amount_without_fees fields let you separate goods from fees when needed.
  • total excludes refunds and returns. The total, tax_amount, and untaxed_amount fields hold the order before refunds and returns. The current_total, current_tax_amount, and current_untaxed_amount fields hold the amounts after returns and removals. Use the set that matches what you intend to book. Do not mix the two.
  • Treat refunds separately. refunded_amount, detailed_refunds, and returns describe money given back. Book refunds as their own entry (or as reverse lines) per VAT rate. Never net a refund inside the original sale’s VAT base.

✅ 6. Reconcile and balance

After you round each amount per rate to 2 decimals separately, a residual difference of a few cents can remain between the sum of your booked lines (net + VAT) and the order total. Book that residue on a rounding account so the entry balances (debit = credit):
  • a gain account for a positive difference (for example, 758);
  • a loss account for a negative difference (for example, 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 absorb it.

In short

Round every amount to 2 decimals half‑up, reuse the VAT the API provides, reason per rate, split global discounts with the remainder on the last bucket, include fees and keep refunds/returns separate (watch total 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.