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.
100baht →"100.00",100.5baht →"100.50". - A money field that has no value yet (e.g.
credited_amount,matched_amountnot yet credited) will benullor dropped from the JSON (omitempty) — the merchant must allow for the case where some money fields are absent ornull. - 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 sent | Result | Reason |
|---|---|---|
"" (empty) | 422 INVALID_AMOUNT — "amount is required" | Must not be empty |
"abc" / non-numeric | 422 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 range | 422 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
nullin some request money fields is interpreted as0(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.