Test Mode Overview
UnknownPay provides a Test Mode (Sandbox) that works Stripe-style: you call the same business endpoints (e.g. POST /v1/deposits), but sign them with a test key instead of your live key. The system keeps test money and test data completely separate from live (the test ledger is a different namespace; test balances never mix with real balances), so you can rehearse the full end-to-end integration without touching real money.
"100.50" — never a number, never satang — on both the request and the response side.How test mode is enabled
The mode is determined by the API key prefix that signs the request — not by the URL or host:
Prefix of X-Api-Key | Mode | Effect |
|---|---|---|
unk_test_... | test | Every request runs in test mode, money/ledger isolated from live, and the /v1/test/* endpoints are unlocked. |
unk_live_... | live | Real money; calling /v1/test/* returns 404. |
The mode is always derived server-side from the key that verifies successfully. You do not (and cannot) send a mode flag yourself in the request.
Test keys are issued through the Portal/admin (rotate-secret with ?mode=test) — you receive a key_id pair (prefixed unk_test_) plus a show-once secret (see the steps in Portal Preparation).
Request signing (S2S) — identical to live
/v1/test/* uses the same S2S HMAC as the live money POSTs. You must send these headers (signing details are in Authentication):
| Header | Description |
|---|---|
X-Api-Key | Your key id (in test mode, prefixed unk_test_). |
X-Timestamp | Unix epoch seconds; must be within ±300 seconds or it is rejected (replay reject). |
X-Signature | HMAC-SHA256(secret, base) as hex. |
Idempotency-Key | Required for all three /v1/test/* endpoints (replaying the same key returns the same result). |
The base (canonical string) is:
<METHOD>\n<path+query>\n<X-Timestamp>\nSHA256_hex(<raw body bytes>)
401 UNAUTHORIZED. If Idempotency-Key is missing, you get 400 IDEMPOTENCY_KEY_REQUIRED. If you reuse the same Idempotency-Key with a different body, you get an error that the key was reused with a different request.Key limits and behavior
- Using a test endpoint with a live key →
404(theRequireTestModegate) —/v1/test/*is deliberately "invisible" to live keys. - Top-up cap: 1,000,000 baht per call (over →
422 AMOUNT_TOO_LARGE). - Rate cap on data-creating triggers:
simulate-transferandtop-upare capped at 60 calls/minute per merchant; over the limit →429 RATE_LIMITED("too many sandbox requests; slow down").resetis not capped. - Idempotency: all three endpoints require an
Idempotency-Key; replaying the same key with the same body returns the same result (24-hour window), scoped per(mode, merchant)→test:<merchant_id>.
Next steps
- Simulate Transfer — inject a bank transfer into a PENDING test deposit.
- Top-up & Reset — credit your test balance and wipe your test data.
- End-to-End Test Flow — the recommended full rehearsal that drives a
deposit.successwebhook.
