Skip to content

Sandbox mode

The same API, a different database, and outcomes you choose.

Sandbox is not a separate product or a mock server. It is the same code, the same routes and the same validation, writing to a different database. What changes is where the money comes from: no operator is contacted, and the outcome is decided by the test number, card or account you use.

How the environment is chosen

By the key. There is no parameter, no header and no flag.

PrefixEnvironment
pk_test., sk_test., rk_test., hsk_test.Sandbox
pk., sk., rk., hsk.Live

A sandbox key cannot read live data, and the reverse is equally true, because the two live in separate databases. That is also why a payment you created in sandbox will never appear in your live Konsole, and why there is nothing to filter.

What is real

Real in sandboxMeaning
ValidationThe same rules, the same 422 messages
LimitsAmount floors and ceilings are enforced identically
Events and webhooksReal events, real signatures, real retries
IdempotencyThe same behaviour on a repeated key
Rate limitsThe same counters
BalanceA separate sandbox balance, credited by sandbox payments
Platform fees2% is charged on successful payments and transfers, producing fee.charged

The last one surprises people: a sandbox payment of 5,000 XAF credits less than 5,000 to your sandbox balance, exactly as a live one would.

What is simulated

SimulatedHow
The operatorThe test number decides the outcome, nothing is dialled
The card networkThe test card decides the outcome
3D SecureHosted checkout shows a simulated challenge you can pass or fail
The bankThe last two digits of the account decide the outcome
CryptoThe wallet address suffix decides the outcome, and a deposit address is generated
TimingA fixed delay rather than a real network

The delays are short and fixed, which is what makes an automated test suite possible.

OperationDelay before the terminal status
Payment3 seconds
Refund2 seconds
Transfer2 seconds

Outcomes are deterministic

This is the part worth internalising: nothing in the sandbox is random, with one narrow exception.

ObjectWhat decides the outcome
Payment, mobile moneyThe suffix of the payer number
Payment, cardThe exact card number
Payment, bankThe last two digits of the account
Payment, cryptoThe suffix of the wallet address
RefundThe original payment's card or phone
TransferThe beneficiary's test number or account

The exception: a refund on a payment with no payment method attached falls back to a 70% chance of success. In practice this only happens on payments created without a payer, which is not a flow you ship.

Transfers are deterministic too

A sandbox transfer to a mobile money beneficiary requires a recognised test number and refuses anything else with a 422 that lists the valid ones. There is no probability involved.

The sandbox balance

Payouts need money. Sandbox payments credit a sandbox balance, and transfers debit it, so the order of your test matters: create and complete a payment before testing a payout, or the transfer fails for insufficient funds exactly as it would in production.

A failed transfer returns the amount to the balance. The 2% platform fee is not returned, which mirrors live behaviour.

Crypto is off unless asked for

The crypto channel is disabled in sandbox by default. When it is enabled, a deposit address and a payment URI are generated per scenario, valid for 30 minutes, and the address itself is deterministic, so you can reproduce the same scenario twice.

What did you think of this content?