How sandbox works
Sandbox is not a separate host. It is a separate credential.
The secret you sign with decides which environment you are in.
Set up a sandbox workspace
1
Create a sandbox key
In the dashboard, open Settings > API Keys and create a sandbox key. See Set up your account.
2
Keep it in its own configuration file
3
Expose your webhook endpoint
Run a tunnel, such as
ngrok http 3000, and set the public URL as your webhook URL in the dashboard.4
Confirm your credentials
Call
/api/whoami. A 200 means signing works, and the response returns "environment": "sandbox" so you can confirm which environment the secret selects.Simulate an inbound deposit
Virtual accounts have a sandbox-only endpoint that fakes an inbound transfer. The request body is optional: you can send anidempotency_key.
The endpoint is rejected in production. It is safe to leave in a test suite.
Test quote expiry
Quote expiry only shows up when a user hesitates, which is exactly when nobody is watching.1
Create a quote
Call Create payout quote and record
expires_at.2
Wait past expires_at
Do nothing until the timestamp passes.
3
Try to execute
Initialize the payout against the expired
quote_id and observe the error.4
Check your interface
Confirm it blocks the attempt, explains why, and offers a fresh quote.
Test webhook delivery and retries
A5xx, a timeout, and most 4xx responses are retried, up to the retry count set on your webhook. 400, 404, 410, 422, and 451 are final. Retries and duplicates has the full rules. Confirm your handler behaves under retries before you rely on it.
1
Return a failure on purpose
2
Trigger an event
Simulate a deposit and watch the retries arrive in your log.
3
Confirm the retry count and spacing
Compare what you see against the documented behavior in Retries and duplicates. By default the delays are about 1, 5, 15, and 60 minutes, so a full retry cycle takes over an hour.
4
Process the same event twice
Return
200 and replay the event. Confirm the second run changes nothing.Test the failure paths
Most integrations test the happy path and ship. These four errors are worth producing deliberately, because each one reaches production eventually.
The last row is the one people skip. Retries are finite, so an endpoint that is down long enough misses events permanently. Reconciliation is what recovers them. See Webhooks and event handling.
Edge cases worth reproducing
- A webhook arrives before your database has written the reference.
- Two webhooks for the same flow arrive in parallel.
- A payment arrives just after a quote expires.
- A user sends an asset you did not expect.
- The same reference is reused across two attempts.
- A signature header is missing or altered.
Build a repeatable script
Ad-hoc testing stops happening once the feature ships. Put the flow in a script instead:- Create a quote and store it.
- Execute against the quote.
- Simulate the deposit.
- Record every webhook received, with its event name and reference.
- Assert the final state matches what you expect.
Before you go live
1
Swap the secret, nothing else
The base URL and
CLIENT_ID do not change. Only CLIENT_SECRET does.2
Point the webhook URL at production
Update it in the dashboard and confirm the endpoint is reachable over HTTPS.
3
Confirm compliance is approved
Production requires completed verification. See Set up your account.
4
Run one small real transaction
Send the smallest amount the corridor allows and follow it end to end before you open the flow to users.