Skip to content
UnknownPay
ไทย
Core Concepts

Money Format

Every money field on the wire is a baht string with exactly 2 decimals, e.g. "100.50" — never a number, never satang

Before connecting to UnknownPay over S2S, read this convention in full — every endpoint uses the same rule.

Iron rule: every money field on the wire (request and response) is a baht string with exactly 2 decimal places, e.g. "100.50"not a number (100.5) and not satang (10050). Only THB is supported in this version.

1. Response side (the system sends to the merchant)

  • Every money field is formatted as a decimal string with always 2 places, e.g. 100 baht → "100.00", 100.5 baht → "100.50".
  • A money field that has no value yet (e.g. credited_amount, matched_amount not yet credited) will be null or dropped from the JSON (omitempty) — the merchant must allow for the case where some money fields are absent or null.
  • A field that is a rate ends with _bps (basis points, an integer), not a money field — e.g. a percentage-based fee.
Pending confirmation — check which response money fields may be null/omitted, to list them completely in each endpoint's docs

2. Request side (the merchant sends to the system)

The system parses the baht string strictly. A value that fails parsing returns HTTP 422 with error code INVALID_AMOUNT in every case. The table below is what the system rejects:

Value sentResultReason
"" (empty)422 INVALID_AMOUNT — "amount is required"Must not be empty
"abc" / non-numeric422 INVALID_AMOUNT — "amount must be a decimal number"Must be a decimal number
"1e2" (scientific notation)422 INVALID_AMOUNT — "amount must be a plain decimal number"No e/E; must be a plain decimal
"-100.00" (negative)422 INVALID_AMOUNT — "amount must not be negative"Must not be negative
"100.123" (more than 2 places)422 INVALID_AMOUNT — "amount must have at most 2 decimal places"At most 2 decimal places
Value beyond the int64 range422 INVALID_AMOUNT — "amount is too large"Beyond the supported range

Notes a merchant should know:

  • Trailing zeros are accepted — e.g. "100.5000" is treated as equal to "100.50" (the real precision is at most 2 places) — the system looks at "real precision", not the number of characters.
  • The safe and recommended format is always 2 decimal places, e.g. "250.00".
  • A JSON null in some request money fields is interpreted as 0 (for fields mapped directly to the money type) — it is recommended to always send the value as an explicit string to avoid ambiguity.
  • Some "unlimited" cap/limit values use "0" to mean unlimited (depends on the endpoint) — see each endpoint's docs for detail.

::placeholder-note{value="specify per endpoint whether "0" means unlimited"} ::

If a merchant sends money in the wrong unit (e.g. sends 10050 intending 100.50 baht) the system interprets it as ten thousand and fifty baht immediately — this is a 100× bug. Always send the value as a baht string.