How environments work
Fingo Pay uses a single base URL for both sandbox and production. The environment is determined entirely by the API key you send.Base URL (all environments)
| Sandbox | Production | |
|---|---|---|
| API key prefix | sk_test_*** | sk_live_*** |
| Real money | No | Yes |
| M-Pesa STK Push | Simulated | Live |
| Webhooks | Delivered (sandbox secret) | Delivered (production secret) |
| Idempotency-Key | Optional | Required for POST |
| Rate limits | Same (600 req/min) | Same (600 req/min) |
What is the sandbox?
The sandbox is a full simulation of the Fingo Pay API. It exposes the same endpoints, accepts the same request shapes, returns the same response structures, and delivers webhooks in the same format as production — but no real money moves and no real M-Pesa STK prompts are sent to phones. Use sandbox to build, test, and validate your integration before going live.- Instant processing. Sandbox transactions are processed immediately. There is no waiting for M-Pesa callbacks — outcomes are simulated and webhooks are fired within seconds.
- Isolated data. Sandbox transactions, accounts, and balances are completely separate from production. Nothing you do in sandbox affects live data.
- Pre-loaded balances. Sandbox accounts come with test balances so you can test charges, payouts, and balance queries without provisioning funds.
The sandbox behaves identically to production in terms of validation, error responses, and webhook signatures. If your integration works correctly in sandbox, it will work in production with minimal changes — just swap your API key and webhook secret.
Switching environments
Sandbox behaviors
Each API area behaves slightly differently in sandbox. The table below summarizes what is simulated and what remains the same.| API area | Sandbox behavior |
|---|---|
| M-Pesa C2B (STK Push) | Simulated. No STK prompt is sent to the phone. The transaction completes automatically based on forceStatus (default: success). |
| M-Pesa B2C | Simulated. Funds are not disbursed to the recipient. A webhook is fired with the simulated outcome. |
| M-Pesa B2B | Simulated. No real transfer occurs between tills or paybills. A webhook is fired with the simulated outcome. |
| Bank transfers | Simulated. No real bank transfer is initiated. |
| Balances | Sandbox accounts have pre-loaded test balances. Transactions debit and credit these balances as they would in production. |
| Webhooks | Delivered to your configured endpoint using your sandbox webhook secret. The signature format is identical to production. |
| Idempotency-Key | Optional in sandbox (required for POST requests in production). |
| Validation and errors | Identical to production. Invalid requests return the same error types and codes. |
Testing with forceStatus
In sandbox, you can force specific transaction outcomes using the metadata.forceStatus field. This lets you test success, failure, and timeout flows without waiting for real M-Pesa callbacks.
forceStatus value | Behavior |
|---|---|
success | Transaction completes successfully |
failed | Transaction fails with a simulated error |
timeout | Simulates customer no-response / STK Push timeout |
If you do not include
forceStatus in your sandbox request, the default outcome is success.Example: Successful charge
transaction.succeeded event with a simulated M-Pesa processor reference.
Example: Failed charge
transaction.failed event with a simulated error message.
Example: Timeout
transaction.failed event with a timeout message, simulating a customer who did not respond to the STK Push prompt.
Pre-go-live testing checklist
Verify each of the following in sandbox before switching to production.Successful charge flow
Create a C2B charge with
forceStatus: "success" and confirm your webhook endpoint receives a transaction.succeeded event. Verify that your system correctly updates the order or payment status.Failed charge flow
Create a C2B charge with
forceStatus: "failed" and then forceStatus: "timeout". Confirm your webhook endpoint handles both transaction.failed scenarios and that your system surfaces the failure to the user or triggers a retry flow.Payout flows
Test B2C and B2B payouts. Verify that webhooks are received and that your system reconciles by
merchantTransactionId and transactionId.Webhook signature verification
Confirm that your endpoint validates the
X-Fingo-Signature header using your sandbox webhook secret. Reject requests with invalid or expired signatures. See Webhooks for implementation details.Idempotency handling
Send the same POST request twice with the same
Idempotency-Key and verify you receive the original response. Then send a different body with the same key and confirm you receive a 409 conflict error. See Authentication and Idempotency for details.Error handling
Trigger common error scenarios — missing required fields (
400), looking up a non-existent transaction (404), and reusing a merchantTransactionId (409). Verify your integration handles each error type correctly. See Errors for the full reference.Sandbox limitations
The sandbox is designed for integration testing and validation. It does not replicate every aspect of the production environment.
- No phone interaction. M-Pesa STK Push prompts are not sent to real phones. Transaction outcomes are determined by
forceStatus. - No real money movement. Balances are simulated. No funds are transferred to or from any M-Pesa wallet or bank account.
- Instant processing. Sandbox transactions complete immediately. Production transactions depend on M-Pesa and bank processing times, which can range from a few seconds to several minutes.
- Scale behavior. While sandbox enforces the same rate limits (600 req/min), it does not replicate production-level latency or throughput characteristics under high load.