Testing
What is confirmed about test traffic, rate limits, and why simulator numbers are not published.
Test environment status
There is no separate Ziba Pay sandbox hostname. Documented samples use the configured API base (https://payment-service-mh2d.onrender.com/api).
MTN target environment is mtnrwanda on proxy.momoapi.mtn.co.rw. Airtel country is RW, currency is RWF, and the Airtel host is openapiuat.airtel.africa. TransactPay host is payment-api-service.transactpay.ai.
MTN, Airtel, and TransactPay credentials are empty in this environment, so none of those providers can take a live payment.
Do not use invented simulator phone numbers. Local seed registers +250788000001 and +250788000002. They satisfy the registered-user check only after the database is seeded, and they are not live wallets.
Illustrative request shape
This JSON matches the implemented MTN body. The values are an illustrative example, not a transaction record and not a guaranteed test account.
curl -X POST "https://payment-service-mh2d.onrender.com/api/payment/mtn-momo-pay" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ZIBA_TOKEN" \
-H "Idempotency-Key: order-1042-mtn" \
-d '{
"amount": 1000,
"currency": "RWF",
"phoneNumber": "+250788000000",
"description": "Illustrative example"
}'Rate limits
Payment routes are limited to 15 requests per minute per IP, inside a global limit of 300 requests per 15 minutes. HTTP 429 means the caller should back off.
Status polling uses GET/payment/mtn/status/:reference with Authorization: Bearer. A new collection returns status "pending". Other order statuses keep the stored enum, including COMPLETED and FAILED.