Money and fees

Money crosses every boundary as a string. Not a number, not a float, not cents-as-an-integer you have to know the scale of. A string you can print, log, compare and store without wondering what happened to it.

The shape

json
{ "currency": "NGN", "value": "10150.00" }

Always two decimal places, always a plain decimal string, never scientific notation. Inside Nineveh it is abigint of minor units; at rest it is DECIMAL(19,2). It is never a float anywhere, because 0.1 + 0.2 is a bug you cannot apologise your way out of when it is somebody’s rent.

Do not parse it into a float. Number("10150.00") is fine to display and catastrophic to add up. Use a decimal library, or integer minor units, on your side too.

Who takes what

Three amounts come off a credit, and they are different in kind:

FieldTypeMeaning
institution feethe bank'sSet at the account authority. Nineveh collects it on the bank's behalf and holds it as a pass-through until settlement clears it.
product feeyoursYour rule, your revenue. Lands in your product-fee wallet.
platform chargeNineveh'sA small fixed amount per credit, accrued against you in a separate journal. It never touches the holder's net.

Gross-up or net

Two ways to price, and the difference is who pays the fees. A product may use gross-up: the tenant owes ₦10,000, so the payer is asked for ₦10,150 and the tenant’s balance moves by exactly ₦10,000.

text
GROSS_UP — the payer covers the fees
  target net       10,000.00
  + institution       100.00
  + product            50.00
  = ask the payer  10,150.00     → balance moves 10,000.00

NET — the fees come out of what arrived
  received         10,000.00
  − institution       100.00
  − product            50.00
  = balance moves   9,850.00

Which one you use is a product decision with a customer-facing consequence, so it is configured on the product and shown on every credit. Both are exact: fixed fees, no percentage rounding, and the breakdown always sums back to the gross.

Rounding

There is none to argue about. Fees are fixed amounts in minor units and the arithmetic is integer, so a breakdown is exact by construction rather than by convention. If a percentage fee is ever introduced, the rounding rule will be stated here before it ships.

Balances

A balance is the sum of the postings against an account, computed when you ask. Nothing increments a stored total. This is why the number the console shows, the number the API returns and the number an auditor would calculate are the same number — there is only one, and it is derived.

http
GET /v1/wallets/hld_01J9.../balance

200 {
  "available": { "currency": "NGN", "value": "26000.00" },
  "asOf": "2026-09-12T09:41:22.118Z"
}

A wallet statement is the same postings, ordered by value date with a running balance — the date the money landed, not the date the row was written.