Skip to content

Sandbox Credentials & Test Numbers

Getting sandbox credentials

Create them yourself in the merchant portal, under Developers → API Applications, with environment Sandbox. No verification and no support ticket are needed — see Sandbox and Going Live.

Then exchange them for an access token exactly as you would in production (see Authentication):

curl -X GET "https://api.cloudpay365.com/api/v1/auth/token/" \
  -u "<YOUR_SANDBOX_CLIENT_ID>:<YOUR_SANDBOX_CLIENT_SECRET>"

Your sandbox wallet starts with a play balance of KES 1,000 and has its own account number — use that as merchant_id, not your live one. Reset the balance from the portal whenever you need to.

It is deliberately small. Payouts draw it down and are refused once it runs out, which is a real check you should see happen; collections credit it back up. This is separate from the …000002 test number below, which simulates the customer's balance failing rather than yours.

Choosing what happens

In sandbox, the destination decides the outcome. The last six digits of account_number — the payer's phone on a collection, the recipient's phone, bank account or till on a payout — select one of these:

Test destination Outcome What you should see
254700000000 Success Request accepted, then a successful result a few seconds later.
254700000001 Customer cancels the prompt Request accepted, then ResultCode 1032, status failed.
254700000002 Insufficient funds Request accepted, then ResultCode 1, status failed.
254700000003 Timeout Request accepted, and no callback ever arrives. The payment stays in flight.
254700000004 Ambiguous result The request itself fails. A payout lands in reconciliation_required and is not retried.
254700000005 Late success Request accepted, then a successful result after about two minutes.

Any other destination succeeds — including your own phone number, which is what most people try first.

Only the last six digits matter, so the country code and formatting are up to you: 254700000002, 0700000002 and +254 700 000 002 all produce insufficient funds. For bank and card payments, the same rule applies to the account number or PAN.

The amount is never an outcome selector. That is deliberate: fixtures tend to reuse one amount, and an amount-keyed sandbox would have you testing one path over and over without noticing.

What each outcome is for

Three of these deserve a specific mention, because they are the ones production will eventually hand you and the ones an integration usually gets wrong.

Timeout (…000003). No callback, ever. This is not a broken sandbox — it is the case where a provider accepted your request and then went silent. Your integration must not treat "no callback yet" as failure, and must not leave the payment unresolved forever. Use Transaction Status Query to find out where it actually stands.

Ambiguous (…000004). On a payout, the request fails without us ever learning whether the money moved. Hivemind Payments deliberately does not retry it against another provider — that is how a recipient gets paid twice — so it is parked for reconciliation and settled by a human. Your side should surface it as "pending investigation", never as failed, and never re-send it automatically.

Late success (…000005). The result arrives about two minutes after the request, long after your polling loop would have given up. If your code has already marked the payment failed by then, it will disagree with us about a payment that succeeded.

Next step

Test Scenarios by Payment Method walks each of these through end to end.