Test data
Everything below works only in sandbox (a cwk_test_… key). No real money moves, but webhooks, signatures, and request logs behave exactly like production.
M-Pesa test numbers
Set one of these as the customer phone on a test payment and the sandbox tester drives that outcome automatically:
| Phone | Outcome | Event |
|---|---|---|
+254700000001 | Payment succeeds | payment_intent.paid |
+254700000002 | User cancels | payment_intent.cancelled |
+254700000003 | Insufficient funds | payment_intent.failed |
+254700000004 | STK timeout | payment_intent.expired |
+254700000009 | Under review | payment_intent.requires_review |
Triggerable outcomes
From the console's Sandbox tester you can create a test payment and drive it to any outcome regardless of the method, which moves the intent and fires the matching webhook:
| Outcome | Event fired |
|---|---|
success | payment_intent.paid |
failed | payment_intent.failed |
underpaid | payment_intent.underpaid |
overpaid | payment_intent.overpaid |
expired | payment_intent.expired |
cancelled | payment_intent.cancelled |
review | payment_intent.requires_review |
You can also send a standalone test webhook of any type, and refund a sandbox payment to fire payment_intent.refunded.
Sandbox balances
Each sandbox merchant starts with fake, non-withdrawable seed balances that grow as test payments complete:
Use Reset sandbox data to clear all test payments, refunds, webhook deliveries, and logs and return to the seed balances. Live data is never touched.