Test Mode
Validate your payment, payout, webhook, and reconciliation flows safely before enabling production traffic.
Introduction
Test mode should validate more than request syntax. It should prove that your backend, event handling, retries, and reconciliation logic behave correctly before any real funds are involved.
Sandbox Validation
Exercise payment and payout creation with controlled low-risk inputs.
Webhook Readiness
Confirm that webhook deliveries match your expected asynchronous lifecycle handling.
Reconciliation Confidence
Compare status polling, event delivery, and internal ledger references before launch.
Required Headers
X-Public-Key: YOUR_PUBLIC_KEY
X-Timestamp: UNIX_TIMESTAMP
X-Signature: HMAC_SHA256_SIGNATUREWhat to Validate in Test
- payment initiation
- payout initiation
- webhook reception
- retry handling
- transaction status reconciliation
- internal ledger correlation through
external_id - the payer's return to your
return_url/cancel_url, for redirect operators
Suggested Checklist
- initiate a payment with a small amount
- store the returned
track_id - verify webhook delivery
- compare webhook state with
GET /payments/status/{track_id} - test failure handling and retry behavior
- confirm KYC status before enabling live usage
Test numbers
In sandbox, the outcome of a payment is decided by the payer's number. No real debit, no prompt on a real handset.
| Number | Operator | Outcome |
|---|---|---|
+237670000001 | MTN Cameroon | SUCCESS |
+237670000002 | MTN Cameroon | FAILED |
+237670000003 | MTN Cameroon | stays PROCESSING |
+237670000004 | MTN Cameroon | fails, insufficient funds |
+237690000001 | Orange Cameroon | SUCCESS |
+237690000002 | Orange Cameroon | FAILED |
+237690000003 | Orange Cameroon | stays PROCESSING |
+237690000099 | Orange Cameroon | fails, insufficient funds |
+2250700000001 | Ivory Coast | SUCCESS |
+2250700000002 | Ivory Coast | FAILED |
+2250700000003 | Ivory Coast | stays PROCESSING |
+2250700000004 | Ivory Coast | fails, insufficient funds |
Any other number is rejected in sandbox. That is deliberate: it stops a flow from looking healthy when it simulated nothing.
Redirect operators: the test payment page
Bank card, Orange, Wave and Djamo send the payer to a page. In sandbox, redirect_url points at a Genuka Pay test page standing in for the operator, with two buttons: Pay and Cancel.
What that changes:
- The payment does not settle on its own. It stays
PROCESSINGuntil somebody clicks — like a real Wave payment, which waits for the payer. - Pay applies the outcome your test number asked for:
+2250700000004still fails with insufficient funds, it just fails where a real payment would. - Cancel fails the payment with the code
PAYMENT_DECLINED. - Either way you land on your
return_url/cancel_urlwithstatusandreference, through exactly the same code as production.
This is the only way to test your return URL
Always send return_url when testing a redirect operator. Without it the test page sends you to the Genuka Pay homepage — which is precisely what your customer would get in live.
Example Sandbox Payment
curl -X POST "{{BASE_URL}}/api/v1/payments" \
-H "X-Public-Key: YOUR_PUBLIC_KEY" \
-H "X-Timestamp: UNIX_TIMESTAMP" \
-H "X-Signature: HMAC_SHA256_SIGNATURE" \
-H "Content-Type: application/json" \
-d '{
"amount": 100,
"currency": "XAF",
"payer_phone": "+237670000001",
"external_id": "test_payment_001"
}'Before Going Live
- complete KYC verification
- confirm current limits through
GET /kyc/limits - configure production webhook endpoints
- rotate credentials if required by your deployment workflow
- start with low-risk amounts and monitor closely
Launch principle
Sandbox readiness is about operational confidence, not just successful HTTP responses. If your webhook, retry, or reconciliation logic is still ambiguous, you are not done testing.
How is this guide?
Last updated on