Mobile Money Trigger Numbers
In the sandbox, the payer’s mobile number (paymentDetails.payerMobileNumber) decides what happens to a payment. Any number not listed here succeeds.
You can send the number in local or international format: in Kenya, 0970000005 and +254970000005 give the same result. The same numbers work in every market, so set payerDetails.location to the country you’re testing.
The sandbox also ignores the operator, so every number works the same with any operator. To mirror a market, check the Approval flow column on its country page and use the matching section below. Flows where the customer dials a USSD code themselves can’t be tested in the sandbox yet.
Authorisation failures
The transaction ends in FAILED with authState.state: "failed" and emits transaction.failed. Terminal — to retry, start a new transaction.
System errors
These return authState.state: "error" rather than "failed" — the payment was not declined, something broke. Check canRetry and canPoll on the response before deciding what to do.
Transient faults
These misbehave for the first 2 seconds after the transaction is created, then behave normally. Use them to prove your retry and polling code recovers rather than giving up.
Delayed confirmations
These stay in AUTH_REQUIRED for a fixed delay, then authorise — a payer who is slow to approve. Pair a delay longer than your session expiry to exercise the late-debit path: the confirmation lands after the transaction has expired, and the automatic refund fires.
0970000018 respects a SANDBOX_DELAYED_CONFIRMATION_MS override on the environment, so an operator-run demo may use a shorter window than the 5 minutes shown here.
Why some refunds fail
A refund is paid back to the number the payment came from, and it goes through the payout sandbox. There, a number ending in 12, 14, 16, 18, 20 or 22 fails (see Payout Trigger Endings).
That’s why the refunds for 0970000018 and 0970000020 fail. To test a late debit and a successful refund end to end, use 0970000026.
OTP
Use 0970000021 to test a payment that asks the payer for a one-time code. The response has authState.authMethodType: "fields" with one otp field.
Send the code with POST /v1/payment/authorize (API reference):
If your account has a fallback processor, the fallback attempt fails straight away rather than asking for a second code.
Redirect
These numbers send the payer to a URL to approve the payment, as some wallets do. The response has authState.authMethodType: "redirect".
- Test page numbers only resolve when the payer clicks. If they ignore the page, the payment expires with the session. Use
0970000023to test wallets that must open outside an iframe. - No-page numbers need no clicks, so use them in automated tests. The result arrives through polling or your webhook.
After the payer decides, Hosted Checkout returns them to the checkout. With the Direct API, they go to the session’s redirectUrl with status=complete or status=failed. Always set redirectUrl, or the payer ends up on a placeholder page.
As with OTP, a fallback processor fails straight away rather than redirecting the payer a second time.
Success
Any number not listed here succeeds. The payment goes from PENDING to AUTH_REQUIRED and reaches COMPLETED about 10 seconds after you create it, with a processorReference.