Sandbox & test values

The sandbox is a fully isolated environment (separate database) running the Simulator rail. Use it to build and test without moving real money.

  • Base URL: https://api-sandbox.starpay.example
  • Keys: sk_test_… only (live keys are rejected here)

Magic values

The instrument you send drives a deterministic outcome:

Mobile money (msisdn)

Number Outcome
0240000000 Success
0240000001 Insufficient funds
0240000002 Times out — the rail never answers and the charge fails
0240000004 Times out after the request was sent — the charge stays pending and never settles in the sandbox, so you can exercise how your integration handles an answer that never comes

Card

Card number Outcome
4084 0840 8408 4081 Success
4084 0840 8408 4082 Declined

Recurring billing (Phase 3)

A successful sandbox card payment tokenizes automatically; the captured token drives recurring-cycle outcomes:

Value Outcome
tok_sim_ok Every recurring charge succeeds (captured from card …4081)
tok_sim_retry The first charge fails (insufficient_funds), the retry succeeds — exercises retry → recovery
tok_sim_fail Every charge declines — exercises dunning → exhaustion → cancellation

MoMo mandates (silent debits, opt-in on the subscribe page):

MSISDN Outcome
0240000000 Mandate approved; every silent debit succeeds
0240000001 Subscriber declines the mandate (subscription falls back to per-cycle prompts)
0240000003 Mandate approved but every silent debit declines — exercises past-due → dunning

Name enquiry

A test-mode name enquiry (POST /resolve/momo-name, POST /resolve/bank-name with a sk_test_ key, or the Verify step on the dashboard's Send money form in Test view) answers by the last four digits of the number or account you look up:

Ends in Outcome
0001 No match: the endpoints answer 404 not_found
anything else A fixed name: Ama Owusu for mobile money, Kwabena Mensah for a bank account

So 0240000001 is both the "no match" number here and the insufficient-funds number above.

Your own payout destinations are the exception: your settlement account and a campaign's beneficiary are always looked up on the live rail, in test mode too, because the name that comes back is saved as the account's verified holder. The values above do not apply to them.

Payouts name check

Payouts in the merchant dashboard compares the name the rail returns with the name you typed for each recipient. In test mode the simulator answers against the name you typed, again by the last four digits:

Ends in The rail answers So the names
0001 No account cannot be compared: the recipient is not found
0005 Yaw Boateng do not match
0006 Only the first word of the name you typed, skipping a title (Mr, Mrs, Dr, …) or a word under three letters match in part
0007 Nothing: the rail is unavailable cannot be checked yet
anything else The name you typed, exactly match

For example, a payout row to 0240000006 for "Akosua Mensah Owusu" comes back as "Akosua", one for "Dr Ama Owusu" as "Ama", and one for "K. Mensah" as "Mensah"; a one-word name such as "Kofi" comes back whole, so it matches. A name whose only long word follows a title ("Dr Kofi") comes back as that word and matches; a name with no word of three or more letters ("Jo Li") comes back as its first word and does not match. A row to 0240000005 comes back as "Yaw Boateng". The payout itself still follows the mobile money table above, so 0240000001 is also a payout that fails with insufficient funds.

These let you assert success and failure paths end-to-end before going live. Webhooks fire in the sandbox exactly as they do in production.