Reserved numbers mean nothing in production — they’re ordinary numbers there. Make
sure none of them survive into your production configuration.
Getting set up
Sandbox accounts are self-service. Register on the backoffice, generate a key, and point athttps://sandbox-api.kotanipay.com. See the Quickstart.
These work in every country we support
Reserved phone numbers are matched on their last nine digits only. Put your own corridor’s country code in front and you get the same outcome:
All four resolve to the same reserved outcome. So the tables below list the
nine-digit ending — prefix it with the country code for the corridor you’re
testing, in international format.
This applies to phone numbers only. The bank account numbers and shortcodes further
down are matched exactly as written.
Payment outcomes
Use as the customer phone number on a deposit, payout or onramp.
These behave like production, not like a mock. The transaction is accepted, sits
pending, then settles — firing the same webhook, moving the same balances and
writing the same timeline as a real one. A failed payout reverses the wallet debit,
because a real failed payout does.
Any number that isn’t reserved succeeds after the usual delay, so you only need a
reserved number when you want a particular outcome.
Worth testing
A payout that fails
A payout that fails
…700000010. Confirm you handle the FAILED webhook, surface the reason, and
notice the wallet debit is reversed — the balance returns to what it was.A transaction that never settles
A transaction that never settles
…700000020 stays pending forever. This is the one most integrations get
wrong: money is committed but no terminal webhook ever arrives. Make sure
something on your side eventually reconciles or escalates rather than waiting
indefinitely.A slow provider
A slow provider
…700000021 takes about a minute. Checks that you aren’t treating a
transaction as final just because the create call returned, and that your polling
backs off sensibly.Paying the wrong person
Paying the wrong person
…700000002 succeeds but is registered to a different name than
…700000001. Pair it with the validation numbers below to catch a mismatched
recipient before you pay.Deposits credit your wallet on the same reconciliation pass production uses, so the
balance moves within about a minute of the deposit settling rather than instantly.
Bank and card payments
These aren’t simulated. Bank and card providers run their own sandbox environments, so those transactions dispatch for real outside production and are tested against the provider’s own test credentials and test cards. Reserved numbers here would take that away.Validation outcomes
Different numbers, for Account Validation rather than payments. These return a fixed result without contacting a provider.Phone numbers
Same nine-digit rule as above — prefix with your corridor’s country code.Bank accounts
Paybill and till shortcodes
Checking a name before you pay
Send the name you expect and the response scores it against the real one. Names are compared token by token, so middle names, initials and ordering still match —Jane M Doe matches JANE MARY DOE.
Pair account 1000000002 with an expected name of Jane Doe to see a failed match:
the account is real and isValid stays true, but nameMatch.matched is false.
Resolved names and match scores require name lookup to be enabled on your account.
Without it you still get format and corridor validation, and
nameLookupStatus comes
back as NOT_ENABLED. Talk to your account manager to have it turned on.