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:

FieldRequiredNotes
mobile_operatoryesThe 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_numberyesThe recipient’s mobile money number, in the local format the network expects.
nameyesThe 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

POST/v1/payouts

Send GHS or KES to a mobile money wallet. The Idempotency-Key header is required.

Body parameters
amount_minorstring (BigInt)Required

Minor units of the wallet currency.

currencystringRequired

GHS or KES.

recipientobjectConditional

Inline recipient (mobile_operator + mobile_number + name). Required unless beneficiary_id is supplied.

beneficiary_idstringConditional

A saved mobile money beneficiary. Alternative to inline recipient. A beneficiary whose operator has no public slug is not payable via the API.

wallet_idstring

Auto-resolved from currency + env if omitted.

merchant_referencestring

Your own ref. Unique per merchant in a 30-day window.

narrationstring

Shown to the recipient where the network supports it.

Errors

CodeHTTPCause
missing_field400Required body field absent (e.g. recipient.mobile_operator or recipient.mobile_number)
invalid_field400Malformed mobile_operator slug or mobile_number
unknown_operator422mobile_operator is not a valid operator for the currency, see GET /v1/momo_operators
wallet_not_found422wallet_id doesn’t match merchant + currency + env
beneficiary_cooldown429Same recipient paid recently; pass allow_duplicate: true if intentional
limit_violation422Per-tx / daily / per-beneficiary cap exceeded; see error.detail.kind
beneficiary_blacklisted403Recipient is on your merchant blacklist
wallet_frozen403The source wallet is frozen; no debits are permitted
insufficient_funds402Wallet balance is below the payout amount plus fees
routing_failed422No mobile money route is available (e.g. the currency is not enabled yet)
Request
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"
  }'
Request, by beneficiary
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.