Skip to main content

Overview

Every ZBD project includes a sandbox environment for testing the ZBD Widget integration end-to-end. Sandbox mode simulates the entire flow — funding users, initiating cashouts, and receiving webhooks — without moving real money through ACH or requiring real identity verification.
Sandbox API keys are separate from production keys. Make sure you’re using the right key for the right environment.
Sandbox API base URL: https://sandbox-api.zbdpay.com

What Sandbox Does

FeatureSandboxProduction
User creationCreates sandbox-scoped widget usersCreates production widget users
Balance fundingCredits test reward balance; no live pool is debitedTransfers publisher points from your live pool
KYC / IdentityControlled through sandbox KYC status helpers; no live Onfido reviewRequired for bank cashouts
Bank linking (Plaid)Full Plaid sandbox flowReal bank connections
ACH payoutSimulated when sandbox bypass is enabled; no real transferReal ACH via banking partner
WebhooksFire normally to your webhook_urlSame
Widget UIIdentical to productionSame

Getting Started

1. Get Your Sandbox API Key

In the ZBD Developer Dashboard, navigate to your project’s API tab and copy the Sandbox key.
Never use sandbox keys in production or production keys in sandbox. The endpoints will reject mismatched keys.

2. Create a Test User

curl -X POST https://sandbox-api.zbdpay.com/api/v1/cashout/sandbox/users \
  -H "apikey: YOUR_SANDBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "reference_id": "test-player-1",
    "email": "test@yourcompany.com"
  }'
Sandbox user creation uses a sandbox-only endpoint. Use the returned data.id as zbd_user_id when funding the user and as the user ID when setting KYC status. Use POST /api/v1/widget/users only for production widget users.

3. Fund the Test User

curl -X POST https://sandbox-api.zbdpay.com/api/v1/widget/users/fund \
  -H "apikey: YOUR_SANDBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "USER_ID_FROM_STEP_2",
    "amount": 5000,
    "currency": "USDZ",
    "idempotency_key": "UNIQUE_UUID"
  }'
In sandbox, funding transfers don’t debit a real pool. The balance is credited for testing purposes.

4. Create a Widget Session

curl -X POST https://sandbox-api.zbdpay.com/api/v1/widget/users/session \
  -H "apikey: YOUR_SANDBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@yourcompany.com",
    "webhook_url": "https://your-server.com/zbd/webhooks"
  }'

5. Open the Widget

Embed the returned widget_url in an iframe. In sandbox, the URL should point at https://widget.sandbox.zbd.gg. The widget behaves identically to production — same UI, same flows — but cashouts complete without real bank transfers.
When you reach bank linking in sandbox, you can use the Plaid sandbox institution Platypus First Bank with the credentials user_good / pass_good. If Plaid asks for a phone number step, you can bypass it in the sandbox flow.
When you reach KYC in sandbox, use a US address so the approval path can complete successfully.

Sandbox Controls

Use these sandbox-only controls on https://sandbox-api.zbdpay.com with apikey: YOUR_SANDBOX_API_KEY to put a test user or monetary account into a known state before opening the widget. For user rewards, use POST /api/v1/widget/users/fund and POST /api/v1/widget/users/deplete. The monetary-account helpers below are for state setup when you already have the monetary account ID.
ControlEndpointRequest body
Create sandbox userPOST /api/v1/cashout/sandbox/users{ "reference_id": "test-player-1", "email": "test@yourcompany.com" }
Set user KYC statusPOST /api/v1/principal-accounts/{zbd_user_id}/kyc-status{ "status": "approved", "country_code": "US" }
Add sandbox balancePOST /api/v1/monetary-accounts/{monetary_account_id}/fund{ "amount": 5000 }
Remove sandbox balancePOST /api/v1/monetary-accounts/{monetary_account_id}/deplete{ "amount": 5000 }
KYC status must be approved, rejected, or processing. Include country_code when setting approved. Balance helper amounts use currency minor units. For USD, 5000 means $50.00.
ACH return-code simulation and explicit payout failure-mode controls are still being wired for sandbox. Until those controls are available, use the webhook examples to prepare your handler for cashout.failed and cashout.returned events.

Sandbox Webhooks

Sandbox webhooks fire to your webhook_url with the same payload structure as production:
{
  "event_id": "evt_sandbox_123",
  "event_type": "cashout.initiated",
  "user_reference_id": "test-player-1",
  "amount_cents": 5000,
  "status": "initiated",
  "occurred_at": "2026-06-01T12:00:00Z"
}
In sandbox, the cashout.completed webhook can fire shortly after cashout.initiated since there’s no real ACH settlement delay. See Server Webhooks for the full event reference.

Moving to Production

When you’re ready to go live:
1

Complete Testing

Verify all flows work: funding, cashout, webhooks, error handling
2

Register Webhook URL

Set your production webhook endpoint in the dashboard
3

Switch API Key

Replace your sandbox API key with the production key
4

Fund Your Pool

Contact ZBD to fund your production CRB pool
5

Go Live

Deploy and monitor your first real cashouts
Production cashouts move real money. Make sure your webhook handler correctly processes cashout.completed, cashout.failed, and cashout.returned events before going live.