Charge a customer over Mobile Money. The customer receives a prompt on their phone to authorise the payment, so the charge always starts as pending and settles asynchronously.
!Requires write access
The API key must have
write access. Read-only keys receive 403 insufficient_scope.Endpoint
POST
/v1/collect/momoiSupported networks
Pass the
network field using one of these codes: MTN · TELECEL (formerly Vodafone) · AT (AirtelTigo) · GMONEY. Legacy codes VDF, ATL and TGO are still accepted and mapped automatically. See institution codes.subscriber_number accepts either the local format 0240000000 or the international format 233240000000 — we normalise it for the provider. amount is decimal GHS — no pesewa padding. See test numbers.
›Wallets are name-verified first
Before any debit we run the provider's mandatory name lookup on the wallet. If the number cannot be resolved you get
422 account_not_found and no transaction is created. On success the resolved account_name is returned and stored with the transaction. This applies to every upstream provider; the lookup wording in reason differs between OGateway, 360Pay and JuniPay.!Upstream rejections return 502
If the provider accepts the request shape but refuses the charge, the transaction is recorded as
failed and the endpoint answers 502 with the provider's own reason in reason. Retry with the same Idempotency-Key.Request
| Field | Type | Description |
|---|---|---|
amountrequired | number | Amount in GHS. Accepts number or numeric string, e.g. 10.50. |
subscriber_numberrequired | string | Customer phone number, "0240000000" or "233240000000". |
networkrequired | enum | One of MTN, TELECEL, AT, GMONEY. |
desc | string | Description shown in your dashboard. Max 100 chars. |
customer_email | string | Optional email captured with the transaction. |
Send an Idempotency-Key header to make retries safe — see Idempotency.
shell
curl -X POST https://api.webrabbitmedia.com/v1/collect/momo \
-H "Authorization: Bearer wr_test_..." \
-H "Content-Type: application/json" \
-H "HTTP-Referer: https://your-app-site.com" \
-H "X-Webrabbitmedia-Title: Your App Name" \
-H "Idempotency-Key: 8f4b7c1e-invoice-a104" \
-d '{
"amount": 10.50,
"subscriber_number": "0240000000",
"network": "MTN",
"desc": "Invoice A104",
"customer_email": "customer@example.com"
}'Response
Response · 202 Pending
{
"transaction_id": "521888807466",
"provider_transaction_id": "TXN-8841002",
"status": "pending",
"code": "02",
"reason_code": "prompt_sent",
"reason": "Transaction is being processed",
"account_name": "AMA SERWAA",
"subscriber_number": "0240000000",
"gross_amount": 10.5,
"fee_amount": 0,
"net_amount": 10.5,
"currency": "GHS"
}| Field | Type | Description |
|---|---|---|
transaction_id | string | 12-digit Web Rabbit transaction id. Use this to poll status. |
provider_transaction_id | string | Provider-side transaction id for the collection. |
status | enum | pending · approved · failed. MoMo charges start pending. |
code | string | Upstream status code: "00" success, "01" failed, "02" pending, "03" processing. |
account_name | string | Wallet holder name resolved by the mandatory name lookup. |
gross_amount | number | Amount charged, before fee. |
fee_amount | number | Platform fee at your account rate, applied once the charge is approved. |
net_amount | number | Amount credited to your balance after settlement. |
currency | string | Always "GHS" today. |
›HTTP status
202 for pending (the usual case — the customer still has to authorise on their phone),201 if the provider settles immediately, 200 for a resolved failure, 422 when the wallet fails name verification. All responses include an x-request-id header — save it if you need support. The final outcome is confirmed by polling the retrieve endpoint.iTest mode is fully simulated
wr_test_ keys are answered by our built-in simulator — no provider call, no prompt on anyone's handset, no money moved, and amounts capped at GHS 10. Outcomes are driven by the amount, so CI runs are deterministic. See the trigger table in Test data.