Mobile money payouts (GHS, KES)
Send GHS or KES to a mobile money wallet. The recipient is identified by a network operator plus their mobile number, not a bank account. This is a same-currency payout: it debits your GHS or KES wallet directly, with no FX.
Availability. Mobile money payouts require GHS or KES to be enabled on your account. Until then a mobile money payout is rejected at routing. Contact Technest support to enable a mobile money currency.
New to payouts? Start with the Payouts overview for the common fields, customer attribution, and management endpoints shared across every currency.
The recipient
You address a mobile money recipient with two fields:
| Field | Required | Notes |
|---|---|---|
mobile_operator | yes | The operator’s public slug from GET /v1/momo_operators?currency=GHS (e.g. mtn-ghana, safaricom-mpesa-kenya). Validated against the operator list, not a format rule. |
mobile_number | yes | The recipient’s mobile money number, in the local format the network expects. |
name | yes | The account holder’s name as registered on their mobile money wallet. |
Look the operator up via GET /v1/momo_operators and send its slug as mobile_operator. A slug the operator list does not carry returns 422 unknown_operator with the input echoed; a malformed slug returns 400 invalid_field.
Tip: call GET /v1/momo_operators?currency=GHS once at integration time, cache the response, and look up by name when building payloads.
POSTCreate a mobile money payout
Send GHS or KES to a mobile money wallet. The Idempotency-Key header is required.
Minor units of the wallet currency.
GHS or KES.
Inline recipient (mobile_operator + mobile_number + name). Required unless beneficiary_id is supplied.
A saved mobile money beneficiary. Alternative to inline recipient. A beneficiary whose operator has no public slug is not payable via the API.
Auto-resolved from currency + env if omitted.
Your own ref. Unique per merchant in a 30-day window.
Shown to the recipient where the network supports it.
Errors
| Code | HTTP | Cause |
|---|---|---|
missing_field | 400 | Required body field absent (e.g. recipient.mobile_operator or recipient.mobile_number) |
invalid_field | 400 | Malformed mobile_operator slug or mobile_number |
unknown_operator | 422 | mobile_operator is not a valid operator for the currency, see GET /v1/momo_operators |
wallet_not_found | 422 | wallet_id doesn’t match merchant + currency + env |
beneficiary_cooldown | 429 | Same recipient paid recently; pass allow_duplicate: true if intentional |
limit_violation | 422 | Per-tx / daily / per-beneficiary cap exceeded; see error.detail.kind |
beneficiary_blacklisted | 403 | Recipient is on your merchant blacklist |
wallet_frozen | 403 | The source wallet is frozen; no debits are permitted |
insufficient_funds | 402 | Wallet balance is below the payout amount plus fees |
routing_failed | 422 | No mobile money route is available (e.g. the currency is not enabled yet) |
curl https://api.swappr.me/api/v1/payouts \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"amount_minor": "5000000",
"currency": "GHS",
"recipient": {
"name": "Ama Mensah",
"mobile_operator": "mtn-ghana",
"mobile_number": "0244123456"
},
"merchant_reference": "PAYOUT_001"
}'curl https://api.swappr.me/api/v1/payouts \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"amount_minor": "5000000",
"currency": "GHS",
"beneficiary_id": "ben_cmo8x2p9q0...",
"merchant_reference": "PAYOUT_002"
}'Response
201 Created with the payout object. Status transitions to paid when the network confirms; listen for the payout.paid webhook.
The management endpoints (list, retrieve, requery, cancel) are currency-agnostic, see the NGN page.