Send money (payout)
A payout sends money from your MoyaPay balance to a beneficiary's mobile money account.
POST /payout
Requires a Bearer token.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
refercence_cl | string | yes | Your merchant reference. Must match the account of the token |
business_code | string | yes | Business code provided by MoyaPay. Must belong to your account |
country_code | string | yes | Country of the transaction: CI, SN, BF, CM, BN, RDC, CB, GMB |
payment_method | string | yes | Payout code of the payment method, see Payment methods |
merchant_transaction_id | string | yes | Your transaction identifier, unique |
amount | number | yes | Amount, as a JSON number. See Limits |
currency | string | yes | Currency of the transaction's country, for example XOF. Choose it from the Currencies by country table |
telephone | string | yes | Beneficiary phone number, as a string. See Limits |
successUrl | string | yes | Redirect URL after a successful payout (redirect-based methods, such as Wave) |
failedUrl | string | yes | Redirect URL after a failed payout |
notifyUrl | string | yes | Your notification URL (see the note in Collect a payment) |
Example
- cURL
- Node.js
- PHP
- Python
curl -X POST https://services.moya-pay.com/service/api/v1/payout \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"refercence_cl": "CL-123456",
"business_code": "MYP-000000-ABCDEF",
"country_code": "CI",
"payment_method": "WAVE_CI",
"merchant_transaction_id": "PAYOUT-2026-000045",
"amount": 5000,
"currency": "XOF",
"telephone": "0505000000",
"successUrl": "https://shop.example.com/payment/success",
"failedUrl": "https://shop.example.com/payment/failed",
"notifyUrl": "https://shop.example.com/api/moyapay/notify"
}'
const res = await fetch('https://services.moya-pay.com/service/api/v1/payout', {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
refercence_cl: 'CL-123456',
business_code: 'MYP-000000-ABCDEF',
country_code: 'CI',
payment_method: 'WAVE_CI',
merchant_transaction_id: 'PAYOUT-2026-000045',
amount: 5000,
currency: 'XOF',
telephone: '0505000000',
successUrl: 'https://shop.example.com/payment/success',
failedUrl: 'https://shop.example.com/payment/failed',
notifyUrl: 'https://shop.example.com/api/moyapay/notify',
}),
});
const body = await res.json();
if (!body.success) throw new Error(body.description || body.message);
<?php
$payload = [
'refercence_cl' => 'CL-123456',
'business_code' => 'MYP-000000-ABCDEF',
'country_code' => 'CI',
'payment_method' => 'WAVE_CI',
'merchant_transaction_id' => 'PAYOUT-2026-000045',
'amount' => 5000,
'currency' => 'XOF',
'telephone' => '0505000000',
'successUrl' => 'https://shop.example.com/payment/success',
'failedUrl' => 'https://shop.example.com/payment/failed',
'notifyUrl' => 'https://shop.example.com/api/moyapay/notify',
];
$ch = curl_init('https://services.moya-pay.com/service/api/v1/payout');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests
resp = requests.post(
"https://services.moya-pay.com/service/api/v1/payout",
headers={"Authorization": f"Bearer {token}"},
json={
"refercence_cl": "CL-123456",
"business_code": "MYP-000000-ABCDEF",
"country_code": "CI",
"payment_method": "WAVE_CI",
"merchant_transaction_id": "PAYOUT-2026-000045",
"amount": 5000,
"currency": "XOF",
"telephone": "0505000000",
"successUrl": "https://shop.example.com/payment/success",
"failedUrl": "https://shop.example.com/payment/failed",
"notifyUrl": "https://shop.example.com/api/moyapay/notify",
},
timeout=30,
)
body = resp.json()
Response
{
"status": 201,
"success": true,
"code": 200,
"message": "TRANSACTION IS INITIATED SUSSESSFULLY",
"data": {
"status": "PENDING",
"transaction_id": "PAYOUT-2026-000045"
}
}
The response has the same shape as for a payin: test success, then read data.status. The final result arrives by callback or through the status endpoint.
Same precautions as a payin
A merchant_transaction_id must stay unique, and an identical transaction (same amount, same number) still in progress for less than a minute is rejected. On a 500 error, check the status before sending again.