Testing
Run the whole 221 Pay lifecycle in test mode, with no real money, then go through the production checklist.
In test mode, no real money moves. 221 Pay simulates the operator: every payment is confirmed automatically within seconds (except the simulated-outcome numbers, below), every payout succeeds. Webhooks, balances, refunds and payouts work as in live mode.
A sk_221_pay_test_… key selects the simulator and test data. A sk_221_pay_live_…
key selects real operators and separate data after live mode is enabled for
the project. Both keys use the same base URL.
Recognise test mode
curl -s "$API_URL/v1/balances" -H "Authorization: Bearer $API_KEY" | jq '{livemode, gateway_mode}'livemode: false and simulated: test mode. livemode: true and real: live
mode. If live mode is not connected, the call fails with
503 PAYMENTS_UNAVAILABLE. See
Authentication.
Full journey
Create a payment
Create a payment as described in Payments. Any valid
mobile number in the rail's country works, for example 77 123 45 67 for
sn_wave. The simulator answers in place of the customer's phone.
Wait for confirmation
A few seconds later, the payment becomes confirmed, fee and net are set
and payment.succeeded goes to the subscribed endpoints.
curl "$API_URL/v1/payments/$PAYMENT_ID" -H "Authorization: Bearer $API_KEY"Test the other outcomes
In test mode, a payment is confirmed; fees and treasury are simulated. The
customer_phone number imposes another outcome when it ends with:
| Number ending | Outcome at the first status read | error_code |
|---|---|---|
0002 | failed | provider_failed |
0003 | expired | expired |
For example 77 123 00 02 on sn_wave. The simulated payment page changes
nothing about it, and live mode ignores these numbers.
unknown is tested by sending signed events to the application's endpoint: see
the cURL example in Webhooks.
Verify a payout number
In test mode only, the code 000000 validates a payout number or a bank
account (POST /v1/payout-destinations/{id}/verify), without reading the
account owner's mailbox. An expired code is still refused. Live mode refuses
000000. See Payouts.
Webhooks in test mode
Events are signed and redelivered as in live mode. The URL must be reachable from the Internet; for a local server, use an HTTPS tunnel.
Before production
- Project live mode activated,
sk_221_pay_live_…key created with thepaymentsscope only and stored in the server's secret manager. - Detection of current and
221pay_keys (pattern in Authentication), plus oldersk_221_keys, in the code repository and logs. -
gateway_modeisreal. - Every
POSTcarries anIdempotency-Keystable per order, reused on retry. -
customer_phonesent with every payment. - Webhook signature verified on the raw body, deduplication on
id. -
failed,expiredandunknownstatuses handled, with no automatic second payment. - Identity verified and payout number registered.