Test mode
Build and test the entire integration: payments, payouts, refunds, webhooks and failures, before anyone verifies anything, against numbers you own.
How it works
Create an app, take its key, and use the same base URL and the same endpoints. A test-mode payment is a real payment: a prompt appears on the phone you addressed, somebody approves or declines it, and the money actually moves. The webhooks, ledger entries and dashboard rows are produced by exactly the same code that produces the live ones.
Test mode is not a mock, and it costs real money
That is deliberate, and it is the opposite of how most test modes work. A simulated gateway only ever tells you what the simulator was written to believe. The states you actually spend your production life in: a prompt nobody answers, a wallet with no float, a network that times out and settles anyway: are the states a mock cannot produce.
Register your test numbers first
Test mode will only ever transact with numbers on your test list. Anything else is refused with a 400, before anything is sent.
This obstacle is the point
Choosing the outcome
You choose it the way your customers will: on the phone. Approve the prompt and the payment succeeds; decline it and it fails; ignore it and it sits pending until it expires. It is a real one, so there is nothing to configure.
| What you do | What your integration sees |
|---|---|
| Approve the prompt | pending → succeeded, with a payment.succeeded webhook |
| Decline the prompt | pending → failed, with a payment.failed webhook |
| Ignore it | pending until the prompt expires, then failed: minutes later, long after the customer closed the tab |
The third row is the valuable one, and it is the one you cannot get from a mock: leave the prompt alone and watch what your code does with a payment.failed that arrives after the checkout page has gone.
100 → the minimum, in both modes: and a sensible test amount
the amount does not decide the outcome; the phone doesWhat is identical to live
| The rails | The same endpoints, the same response codes, the same timing and the same real money. |
| Validation | Same minimum, same number format, same refusals. A request test mode accepts is one production accepts. |
| Webhooks | Same events, same signing, same retry schedule. Point them at a tunnel on your laptop. |
| Idempotency | Same replay behaviour, same unique index. |
| Fees and ledger | Calculated and posted the same way, against a test ledger. |
| Dashboard | Same screens and filters, with the mode switch at the top and a band across the page while you are in test. |
What is different
| Who you may address | Only your registered test numbers. Live mode has no such limit. |
| You cannot withdraw it | A test balance is real money on its own books, and withdrawing is what verification gates. Get verified and go live to take money out. |
| Separate books | Test payments never appear in a live total, a live balance or a live report. |
| No fee | We take nothing on a test payment. |
Going live
Get verified, create a live app, swap the key. That is the entire migration. The base URL, the request bodies, the webhook format and your handler code are unchanged, because there was never a second API to migrate from.
Flipping it is the whole migration