> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chift.eu/llms.txt
> Use this file to discover all available pages before exploring further.

# Amounts, roundings and totals

> How to read POS order amounts, round them consistently, and keep your totals coherent when pushing sales and payments into an accounting system.

## Amounts, roundings and totals

When you push POS sales and payments into an accounting system, the numbers must match to the cent. The sum of your revenue lines, VAT, and payments must equal the order total, and the resulting entry must balance. This guide explains how the Unified API exposes POS order amounts, and the method we recommend to keep them correct once booked.

The sections below cover the [decimal precision](#1-decimal-precision) of the amounts you receive, the [rounding rule](#2-rounding-rule) to apply, how to [handle VAT](#3-handle-vat-per-rate), how to [split a global discount](#4-splitting-a-global-discount), the POS‑specific points on [tips and payments](#5-tips-and-payments), and the final [reconciliation](#6-reconcile-and-balance) check.

<Info>
  This guide describes the recommended method, not a constraint the API enforces. When you consume the POS 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](/unified-apis/accounting/guides-and-behaviours/invoice-amounts-validation).
</Info>

***

### 🔢 1. Decimal precision

The API response may return POS amounts with **more than 2 decimals**. For example, `unit_price`, `total`, or `tax_amount` can carry up to 3 decimals. The API often derives a net amount from a gross total or a quantity, and it keeps that finer precision.

<Info>
  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.
</Info>

***

### 🧮 2. Rounding rule

The API delivers amounts with up to **3 decimal places**. Apply a single, consistent rounding rule to every amount **before** you book it into accounting:

**2 decimals**, **round half up**.

Examples:

* a `unit_price` of `2.599` becomes `2.60`
* a computed net of `2.5950413…` becomes `2.60`

<Info>
  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.
</Info>

***

### 🧾 3. Handle VAT per rate

**Reuse the tax amounts the API provides. Do not recompute them.** The API always returns `tax_amount`. Chift takes it from the POS software when the software provides it, and computes it with the method below when the software does not. Recomputing it yourself from a rate adds a rounding error that the reconciled value does not have.

Each order groups its VAT in the `taxes` array. Each entry holds three fields for one rate:

* `tax_rate`: the VAT rate (for example, `21`).
* `tax_amount`: the VAT amount for that rate.
* `total`: the tax‑inclusive amount (TTC) for that rate.

Get the net (tax‑exclusive) amount by subtraction:

```text theme={null}
net = total - tax_amount
```

Example: `total = 12.10`, `tax_amount = 2.10`

* `net = 12.10 - 2.10 = 10.00`

Book `net` on the revenue account and `tax_amount` on the VAT account, per rate. Each order line also carries its own `total`, `tax_amount`, and `tax_rate`. Use the same subtraction to get the line net when you book at line level.

<Info>
  This is how Chift derives the tax when the POS software provides only a tax‑inclusive amount and a rate. Chift applies it for you and returns the result, so use the value directly. It is shown here to explain the amounts you receive:

  ```text theme={null}
  net = total / (1 + tax_rate / 100)
  vat = total - net
  ```

  Example: `total = 3.14`, `tax_rate = 21`

  * `net = 3.14 / 1.21 = 2.5950…`, returned at 3 decimals as `2.595`
  * `vat = 3.14 - 2.595 = 0.545`
</Info>

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.

***

### ➗ 4. Splitting a global discount

<Info>
  This split applies only when you consume the Unified API and book to accounting yourself. Chift's Sync performs it automatically.
</Info>

Each line item’s `total` already includes any line‑level discount. The order’s `total_discount` field is the sum of all line‑level discounts plus any remaining global discount, and it is **tax‑inclusive**:

```text theme={null}
order.total_discount = sum(line.discount.total for all lines) + remaining_global_discount
```

Only `remaining_global_discount` needs to be split across VAT rates. 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:

```text theme={null}
remaining_global_discount = order.total_discount - sum(line.discount.total for all lines)

for each rate except the last:
    share = round_half_up(remaining_global_discount * rate_total / items_total, 2)
    allocated += share
last rate:
    share = remaining_global_discount - allocated
```

Here `rate_total` is the tax‑inclusive total for that rate and `items_total` is the tax‑inclusive total of all order lines. Each `share` is tax‑inclusive. Get its net part by dividing by the rate:

```text theme={null}
net_share = round_half_up(share / (1 + tax_rate / 100), 2)
```

This guarantees that the sum of the per‑rate discount shares equals the remaining global discount exactly.

***

### 💶 5. Tips and payments

Two POS‑specific points determine whether your sales side matches your payments side:

* **Tips are separate from the order total.** `total` does **not** include `total_tip` (order) or `tip` (payment). Book them on a dedicated account. Do not add them to revenue.
* **Only count valid payments.** Exclude payments whose `status` is `Canceled` or `Failed` before you sum them.

The order `total` is **tax‑inclusive (TTC)**. Your coherence check on the payment side is:

```text theme={null}
sum(valid payments) + sum(valid tips) + unpaid client account (B2B) = order.total (+ total_tip)
```

This term appears only when an order is invoiced and settled later (B2B). For a fully paid order, it is zero.

***

### ✅ 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`).

<Note>
  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. Stop and investigate rather than absorb it.
</Note>

***

## 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, keep tips out of revenue, 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 POS amounts.
