Skip to content

Sandbox and Going Live

You get two sets of API credentials: sandbox and production. They are separate applications with separate client IDs and secrets, issued from the merchant portal, and they behave identically apart from what happens at the far end.

Sandbox is not a different API. Same host, same endpoints, same request and response shapes, same errors, same webhooks. What changes is that no money moves, and that you choose what happens by choosing who you pay.

The two environments

Sandbox Production
Host and endpoints identical identical
Credentials your sandbox client ID and secret a separate pair
Wallet charged your sandbox wallet, play balance your real wallet
Outcome chosen by the destination — see Sandbox Credentials & Test Numbers whatever actually happens
Webhooks to your result_url real HTTP, same payload real HTTP
IP whitelisting not enforced enforced — requests from any other address are refused
Payouts before verification allowed blocked until your business is verified
Appears in your dashboards, statements and exports never yes

Two rows there are worth reading twice.

IP whitelisting is not enforced in sandbox. You can integrate from a laptop, from CI, from anywhere, without registering an address. It is enforced in production, and an application with no whitelisted address has every request refused — which is why adding one is on the go-live checklist below, rather than being something you discover on your first real payment.

Sandbox traffic is invisible everywhere else. It is not in your dashboard totals, your statements, your exports or your real balance. You cannot inflate your own numbers by testing, and you cannot lose test data by looking at a report.

Get sandbox credentials

  1. Sign in to the merchant portal and register if you have not already. You do not need to be verified.
  2. Go to Developers → API Applications and create an application with environment Sandbox.
  3. Copy the client ID and secret. The secret is shown in full to the account owner; treat it like a production one anyway — see Token Handling.

A sandbox wallet is created for you at the same time, with a play balance of KES 1,000. You can read it and reset it from the portal. Resetting restores the balance and leaves your test payments alone, because those are what the go-live checklist reads.

The balance is small deliberately — payouts spend it and are refused when it runs out, so you meet that check early rather than in production. Collections credit it back.

You can do this the day you register. Verification is not required to build and test an integration — only to take real money.

Going live

When your integration works in sandbox, create a second application with environment Production. It is issued only when all of the following are true, and the portal shows you which are outstanding at Developers → Go Live:

Requirement Why
Your business is verified (full KYB) The same line that unlocks payouts. Live credentials unlock with it.
One successful collection in sandbox You can take money.
One successful payout in sandbox You can send money.
Your webhook has returned a 2xx to a sandbox result Your callback endpoint exists, is reachable, and your code handled a real delivery. This is the one that most often catches a problem.
At least one whitelisted IP address Production refuses requests from anywhere else. Better found now than on your first live payment.

Going live does not disable your sandbox application. You keep both, permanently — you will want somewhere to test your next change after you are live. Point your test environment at the sandbox credentials and your production environment at the live ones; nothing else in your integration changes.

There is no way to have this waived. The checklist is the process.

Moving your integration over

Everything that differs between the two is configuration, not code:

  • the client ID and secret you exchange for a token,
  • the merchant_id you send in the request body — your sandbox wallet has its own account number, and it is deliberately not derived from your live one, so a hardcoded sandbox value sent to production fails with "wallet not found" rather than touching a real wallet,
  • your result_url, if your test and production handlers are different services.

If anything else has to change, something is wrong — tell us, because it means the two environments have drifted and that is our bug, not yours.

Next steps