Sandbox
How the sandbox behaves, the test amounts, forced scenarios and the sandbox helper endpoints.
Generated from public-api.mdVersion 1.2.0Last updated 2026-09-20
#Sandbox Testing
#How Sandbox Works
Sandbox is the combination of a sandbox merchant account and the sandbox host:
- Call
https://sandbox-api.<domain>/v1/…(currentlyhttps://sandbox-api.paymenow.asia). - Use your sandbox credentials (
pk_demo_…/sk_demo_…).
Sandbox transactions are stored in separate tables, never reach a payment
provider, and return a mock QR payload (no qr_code_image). Balance credits and
debits behave realistically, so a sandbox withdrawal still needs sandbox funds.
Contact support to request sandbox credentials.
#Test Amounts
In sandbox, specific deposit/withdraw amounts resolve to a fixed outcome:
| Amount | Deposit outcome | Withdraw outcome |
|---|---|---|
100.00 | completed | completed |
500.00 | completed | completed |
1000.00 | completed | completed |
200.00 | pending | processing (default) |
999.99 | failed | failed |
| Any other | pending | processing |
The
/sandbox/test-amountshelper still lists888.88as atimeouttrigger. It is not implemented:888.88behaves like any other amount. Use theX-Sandbox-Scenario: timeoutheader instead.
Remember the hard minimums (50 THB deposit, 100 THB withdraw) apply in sandbox
too, so 100.00 is the smallest useful deposit test amount.
#Test Scenarios
Override the outcome with the X-Sandbox-Scenario header. The header takes
precedence over the amount, and is ignored for production merchants.
| Scenario | Deposit | Withdraw |
|---|---|---|
auto_approve | completed | completed |
auto_fail | failed | failed |
auto_pending | pending | processing |
timeout | Request hangs ~35 s, then 504 TIMEOUT | same |
invalid_account | (no effect) | 400 INVALID_ACCOUNT |
When a sandbox deposit lands in completed or failed immediately and a
webhook_url was supplied, the webhook fires just as in production — so webhook
handlers can be tested end to end.
Example:
curl -X POST https://sandbox-api.paymenow.asia/v1/payments/deposit \
-H "X-Sandbox-Scenario: auto_approve" \
-H "X-API-Key: your_sandbox_api_key" \
-H "X-Signature: ..." \
-H "X-Timestamp: ..." \
-H "Content-Type: application/json" \
-d '{"amount": 500.00, "currency": "THB", "reference_id": "TEST-001", "bank_code": "004", "bank_account_no": "1234567890", "bank_account_name": "Test Payer"}'#Sandbox helper endpoints
Served on the sandbox host only, with no authentication:
| Endpoint | Returns |
|---|---|
GET /sandbox/test | Confirms sandbox mode is active |
GET /sandbox/credentials | Static example credentials (illustrative, not usable) |
GET /sandbox/test-amounts | The test-amount table (see the 888.88 caveat above) |
Limited to 300 requests/minute per IP at the edge.
#Response Headers
| Header | Value | Description |
|---|---|---|
X-Environment | sandbox or production | Which side served the request |
X-Sandbox-Mode | true | Sandbox merchants only |
X-Request-ID | opaque string | Trace id, echoed from your X-Request-ID if sent |

