Skip to content
UnknownPay
ไทย
Sandbox

Test Mode Overview

Sandbox / Test Mode works Stripe-style — same business endpoints, signed with a test key, on a fully isolated test ledger

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.

Every money field on the wire is always a baht string with 2 decimals, e.g. "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-KeyModeEffect
unk_test_...testEvery request runs in test mode, money/ledger isolated from live, and the /v1/test/* endpoints are unlocked.
unk_live_...liveReal 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).

Diagram coming soon — Portal screen issuing/rotating a Test API key, with a key_id prefixed unk_test_
Pending confirmation — the exact Portal UI steps for issuing a Test key (which menu, which role)

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):

HeaderDescription
X-Api-KeyYour key id (in test mode, prefixed unk_test_).
X-TimestampUnix epoch seconds; must be within ±300 seconds or it is rejected (replay reject).
X-SignatureHMAC-SHA256(secret, base) as hex.
Idempotency-KeyRequired 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>)
If any header is missing, or the signature/timestamp does not pass, you get 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 (the RequireTestMode gate) — /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-transfer and top-up are capped at 60 calls/minute per merchant; over the limit → 429 RATE_LIMITED ("too many sandbox requests; slow down"). reset is 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>.
Pending confirmation — whether the sandbox base URL is the same domain as production or a separate domain (the mode comes from the key, not the host)

Next steps