Create Payout
curl --request POST \
--url https://quickei.io/pay/sandbox/api/v1/payouts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"amount": 123,
"currency": "<string>",
"recipient": {},
"reference": "<string>",
"description": "<string>",
"idempotency_key": "<string>"
}
'import requests
url = "https://quickei.io/pay/sandbox/api/v1/payouts"
payload = {
"amount": 123,
"currency": "<string>",
"recipient": {},
"reference": "<string>",
"description": "<string>",
"idempotency_key": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
amount: 123,
currency: '<string>',
recipient: {},
reference: '<string>',
description: '<string>',
idempotency_key: '<string>'
})
};
fetch('https://quickei.io/pay/sandbox/api/v1/payouts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://quickei.io/pay/sandbox/api/v1/payouts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 123,
'currency' => '<string>',
'recipient' => [
],
'reference' => '<string>',
'description' => '<string>',
'idempotency_key' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://quickei.io/pay/sandbox/api/v1/payouts"
payload := strings.NewReader("{\n \"amount\": 123,\n \"currency\": \"<string>\",\n \"recipient\": {},\n \"reference\": \"<string>\",\n \"description\": \"<string>\",\n \"idempotency_key\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://quickei.io/pay/sandbox/api/v1/payouts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 123,\n \"currency\": \"<string>\",\n \"recipient\": {},\n \"reference\": \"<string>\",\n \"description\": \"<string>\",\n \"idempotency_key\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://quickei.io/pay/sandbox/api/v1/payouts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 123,\n \"currency\": \"<string>\",\n \"recipient\": {},\n \"reference\": \"<string>\",\n \"description\": \"<string>\",\n \"idempotency_key\": \"<string>\"\n}"
response = http.request(request)
puts response.read_bodyPOS API
Create Payout
Initiate a payout to a mobile money account or bank account
POST
/
payouts
Create Payout
curl --request POST \
--url https://quickei.io/pay/sandbox/api/v1/payouts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"amount": 123,
"currency": "<string>",
"recipient": {},
"reference": "<string>",
"description": "<string>",
"idempotency_key": "<string>"
}
'import requests
url = "https://quickei.io/pay/sandbox/api/v1/payouts"
payload = {
"amount": 123,
"currency": "<string>",
"recipient": {},
"reference": "<string>",
"description": "<string>",
"idempotency_key": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
amount: 123,
currency: '<string>',
recipient: {},
reference: '<string>',
description: '<string>',
idempotency_key: '<string>'
})
};
fetch('https://quickei.io/pay/sandbox/api/v1/payouts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://quickei.io/pay/sandbox/api/v1/payouts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'amount' => 123,
'currency' => '<string>',
'recipient' => [
],
'reference' => '<string>',
'description' => '<string>',
'idempotency_key' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://quickei.io/pay/sandbox/api/v1/payouts"
payload := strings.NewReader("{\n \"amount\": 123,\n \"currency\": \"<string>\",\n \"recipient\": {},\n \"reference\": \"<string>\",\n \"description\": \"<string>\",\n \"idempotency_key\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://quickei.io/pay/sandbox/api/v1/payouts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": 123,\n \"currency\": \"<string>\",\n \"recipient\": {},\n \"reference\": \"<string>\",\n \"description\": \"<string>\",\n \"idempotency_key\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://quickei.io/pay/sandbox/api/v1/payouts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": 123,\n \"currency\": \"<string>\",\n \"recipient\": {},\n \"reference\": \"<string>\",\n \"description\": \"<string>\",\n \"idempotency_key\": \"<string>\"\n}"
response = http.request(request)
puts response.read_bodyInitiate a payout to a mobile money account or bank account. Funds are deducted from your merchant wallet.
Success Response
Endpoint
POST https://quickei.io/pay/sandbox/api/v1/payouts
Authentication
HTTP Basic Authentication using yourclient_id and client_secret.
Parameters
number
required
Amount to send. Must be greater than 0.
string
required
ISO 4217 currency code (3 characters, e.g.
XAF, XOF, EUR). Must match an active wallet.object
required
Recipient details. Structure depends on the payout type.For mobile money:
For bank transfer:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Must be mobile_money |
mobile_code | string | Yes | Country dialing code (e.g. 237) |
mobile_number | string | Yes | Mobile number without country code |
operator | string | Yes | Mobile operator (mtn, orange, moov) |
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Must be bank_transfer |
bank_code | string | Yes | Bank SWIFT/BIC or local code |
account_number | string | Yes | Recipient account number |
account_name | string | Yes | Account holder full name |
string
required
Your internal reference. Must be unique per merchant (max 255 chars).
string
Description of the payout (max 500 chars).
string
Unique key to prevent duplicate payouts (max 64 chars).
Fees
A fee of 2% is applied to each payout, with a minimum of 100 XAF (or equivalent in the payout currency). The fee is deducted from your wallet on top of the payout amount.| Example | |
|---|---|
| Amount | 10,000 XAF |
| Fee (2%) | 200 XAF |
| Total deducted | 10,200 XAF |
Example Request
curl -X POST https://quickei.io/pay/sandbox/api/v1/payouts \
-H "Authorization: Basic {base64_credentials}" \
-H "Content-Type: application/json" \
-d '{
"amount": 10000,
"currency": "XAF",
"recipient": {
"type": "mobile_money",
"mobile_code": "237",
"mobile_number": "670000000",
"operator": "mtn"
},
"reference": "PAY-2026-0042",
"description": "Salary March 2026",
"idempotency_key": "idem_payout_abc123"
}'
Success Response 200
{
"message": {
"success": ["Payout initiated successfully"]
},
"data": {
"id": "PYT-20260323-X4K9M2",
"reference": "PAY-2026-0042",
"amount": 10000,
"currency": "XAF",
"fee": 200,
"total_deducted": 10200,
"status": "pending",
"recipient": {
"type": "mobile_money",
"mobile_code": "237",
"mobile_number": "670000000",
"operator": "mtn"
},
"description": "Salary March 2026",
"failure_reason": null,
"processed_at": null,
"created_at": "2026-03-23T10:30:00+00:00"
}
}
Payout Statuses
| Status | Description |
|---|---|
pending | Payout created, awaiting processing |
processing | Payout is being processed by the provider |
completed | Funds successfully delivered to the recipient |
failed | Payout failed — see failure_reason for details |
Error Responses
400 Validation Error
{
"message": {
"error": ["The recipient.operator field is required when type is mobile_money"]
}
}
422 Insufficient Balance
{
"message": {
"error": ["Insufficient wallet balance for this payout"]
}
}
409 Duplicate Reference
{
"message": {
"error": ["A payout with this reference already exists"]
}
}

