The sandbox environment lets you test your integration without processing real money. All features work identically to production — the only difference is that no actual payments are made.
Sandbox vs Production
| Feature | Sandbox | Production |
|---|
| API Key | sk_test_xxx | sk_live_xxx |
| Real payments | No (simulation) | Yes |
| Transaction fees | None | Per plan pricing |
| Webhooks | Instant delivery | Real-time |
| KYB required | No | Yes |
Configuration
Use your test API key to automatically target the sandbox:
# All requests with sk_test_ keys go to the sandbox
curl https://api.simiz.io/v1/transactions \
-H "Authorization: Bearer sk_test_xxxxxxxxxxxx"
Use different environment variables for sandbox and production. Never use production keys during development.
Sandbox modes
The platform offers two sandbox modes, configurable from Admin → System Settings → Sandbox & Payments:
Local simulation (default)
In LOCAL_SIMULATION mode, sandbox payments are simulated entirely locally using magic phone numbers. No calls are made to any external provider.
This mode is ideal for development and automated testing as it is fast, deterministic, and requires no provider configuration.
Provider passthrough
In PROVIDER_PASSTHROUGH mode, sandbox payments are sent to the real payment provider’s sandbox (QuickEi, MamoniPay, etc.). This lets you test the full integration with the provider, including webhooks and real responses.
This mode is useful for validating real provider behavior before going to production.
The sandbox mode is a global platform setting. It only affects projects in sandbox environment — production payments always go through the real provider.
Test phone numbers
The magic numbers below work in local simulation mode only:
Orange Money (Cameroon)
| Number | Result | Delay | Description |
|---|
237690000001 | Success | ~5s | Payment completed |
237690000002 | Failed | ~3s | Insufficient balance |
237690000003 | Timeout | — | No response (stays pending) |
237690000004 | Failed | ~1s | Invalid number |
MTN MoMo (Cameroon)
| Number | Result | Delay | Description |
|---|
237670000001 | Success | ~5s | Payment completed |
237670000002 | Failed | ~3s | Insufficient balance |
237670000003 | Timeout | — | Service unavailable |
Wave (Senegal)
| Number | Result | Delay | Description |
|---|
221770000001 | Success | ~5s | Payment completed |
221770000002 | Failed | ~3s | Insufficient balance |
Any number not ending with 0001, 0002, 0003, or 0004 will be treated as a successful payment after ~8 seconds.
Testing webhooks locally
In sandbox mode, webhooks are triggered instantly. To receive them during local development, use a tunnel service:
# Terminal 1 — Start your server
npm run dev # http://localhost:3000
# Terminal 2 — Expose with ngrok
ngrok http 3000
# Forwarding: https://abc123.ngrok.io -> http://localhost:3000
# Set this as your webhook URL in the Dashboard:
# https://abc123.ngrok.io/api/webhooks/simiz
npx localtunnel --port 3000
# your url is: https://xyz.loca.lt
Manual webhook testing
From the Dashboard, you can trigger test webhook events manually:
- Go to Dashboard → Settings → Webhooks
- Click Send Test Event
- Select the event type (e.g.,
payment.succeeded)
- Verify your endpoint processes it correctly
Best practices
Test all scenarios. Don’t just test the happy path — verify your app handles failures, timeouts, and edge cases correctly.
- Test success, failure, and timeout scenarios
- Verify webhook handling for all subscribed events
- Use separate environment variables for sandbox and production
- Test with all supported payment methods
- Don’t rely solely on API responses — always test webhook flows
- Use provider passthrough mode to validate the full integration before going to production