Skip to content

Amounts ​

Every money field, on every request, response and webhook, is a decimal string in the wallet's currency. No money field is ever a JSON number.

json
{ "amount": "1250.00", "fee": "12.50", "tax": "0.00", "currency": "ETB" }

Keep amounts as strings from end to end. Parsing one into a binary float and printing it again is how 1250.10 becomes 1250.099999999999; use your language's decimal type if you need to add them up.

What you receive ​

Exactly two decimal places, always — including the trailing .00, and a leading - on a negative figure such as a reversal or a variance.

ValueField reads
1 250 ETB"1250.00"
12.50 ETB"12.50"
nothing"0.00"
−1 santim"-0.01"

A balance is rounded down, never up, so it is always an amount the customer can be paid out in full. Do no rounding of your own.

What you may send ​

Zero, one or two decimal places. "1250", "1250.5" and "1250.50" are the same amount.

You sendYou get
"1250", "1250.5", "1250.50", "0.01"Accepted
"1250.005" — a third decimal place400 AmountPrecisionExceeded
more than 18 digits before the decimal point400 AmountPrecisionExceeded
1250.50 — a JSON number400 BadRequest
"1.25e3", "+5", "007", " 5 ", "1,250.00", ".5", "12."400 BadRequest

A third decimal place is refused, not rounded away: an amount you send is the amount that moves. Quote the customer a two-decimal figure and send that same string.

Field names ​

No money field name ends in Minor or MinorUnits. amountMinor is amount, feeMinor is fee, taxMinor is tax, totalDebitedMinor is totalDebited, and a wallet balance reads current, held and available. The changelog lists the renames in full.

In the transaction binding ​

The transaction binding hashes the amount with exactly two decimal places, whatever the request body carries: a request sending "7500" binds over 7500.00. The kit's transactionBinding() and toTwoDecimalPlaces() do this for you.