Appearance
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.
| Value | Field 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 send | You get |
|---|---|
"1250", "1250.5", "1250.50", "0.01" | Accepted |
"1250.005" — a third decimal place | 400 AmountPrecisionExceeded |
| more than 18 digits before the decimal point | 400 AmountPrecisionExceeded |
1250.50 — a JSON number | 400 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.