Payouts
Send money to mobile money wallets and bank accounts.
Payouts API
The Payouts API allows you to send money to mobile money wallets and bank accounts in Ghana.
The Payout Object
{
"id": "po_abc123def456",
"object": "payout",
"amount": 100,
"currency": "GHS",
"fee": 1.50,
"status": "completed",
"destination": {
"type": "mobile_money",
"provider": "mtn",
"number": "024****567",
"name": "John Doe"
},
"description": "Salary payment",
"metadata": {
"employee_id": "123"
},
"provider_reference": "OP123456789",
"failure_reason": null,
"created_at": "2024-01-15T10:00:00Z",
"completed_at": "2024-01-15T10:00:05Z"
}Attributes
| Attribute | Type | Description |
|---|---|---|
id | string | Unique identifier |
object | string | Always "payout" |
amount | number | Amount in GHS |
currency | string | Currency code (GHS) |
fee | number | Transaction fee in GHS |
status | string | created, pending, processing, succeeded, failed, cancelled |
destination | object | Destination account details |
destination.type | string | mobile_money or bank_transfer |
destination.provider | string | Provider (e.g., mtn, telecel, airteltigo) |
destination.number | string | Masked account/phone number |
destination.name | string | Recipient name |
description | string | Payout description |
metadata | object | Custom metadata |
provider_reference | string | Provider transaction reference |
failure_reason | string | Error message if failed |
created_at | string | Creation timestamp |
completed_at | string | Completion timestamp |
Create a Payout
Sends money to a mobile money wallet or bank account.
POST /v1/payoutsRequest Body
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | number | Yes | Amount in GHS (e.g., 100 for GHS 100.00) |
currency | string | No | Currency (default: GHS) |
destination | object | Yes | Destination account details |
destination.type | string | Yes | mobile_money or bank_transfer |
destination.phone_number | string | Yes* | Phone number (for mobile money) |
destination.provider | string | No | Provider code (auto-detected from phone): mtn, telecel, airteltigo |
destination.account_number | string | Yes* | Account number (for bank transfer) |
destination.bank_code | string | Yes* | Bank code (for bank transfer) |
destination.account_name | string | No | Recipient name |
otp_code | string | Yes | 6-digit OTP code for verification |
description | string | No | Payout description |
metadata | object | No | Custom metadata |
Before initiating a payout, you must first request an OTP using the OTP API. The OTP is sent to the merchant's registered phone number and must be verified within 10 minutes.
Mobile Money Payout
curl -X POST https://api.shikacreators.com/v1/payouts \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"amount": 100,
"currency": "GHS",
"destination": {
"type": "mobile_money",
"phone_number": "0241234567",
"account_name": "John Doe"
},
"otp_code": "123456",
"description": "Salary payment",
"metadata": {
"employee_id": "123"
}
}'const payout = await shikacreators.payouts.create({
amount: 100,
currency: 'GHS',
destination: {
type: 'mobile_money',
phone_number: '0241234567',
account_name: 'John Doe'
},
otp_code: '123456',
description: 'Salary payment',
metadata: {
employee_id: '123'
}
})payout = client.payouts.create(
amount=100,
currency='GHS',
destination={
'type': 'mobile_money',
'phone_number': '0241234567',
'account_name': 'John Doe'
},
otp_code='123456',
description='Salary payment',
metadata={'employee_id': '123'}
)$payout = $shikacreators->payouts->create([
'amount' => 100,
'currency' => 'GHS',
'destination' => [
'type' => 'mobile_money',
'phone_number' => '0241234567',
'account_name' => 'John Doe'
],
'otp_code' => '123456',
'description' => 'Salary payment',
'metadata' => ['employee_id' => '123']
]);Bank Transfer Payout
curl -X POST https://api.shikacreators.com/v1/payouts \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"amount": 500,
"currency": "GHS",
"destination": {
"type": "bank_transfer",
"account_number": "1234567890",
"bank_code": "GCB",
"account_name": "John Doe"
},
"otp_code": "123456",
"description": "Vendor payment"
}'const payout = await shikacreators.payouts.create({
amount: 500,
currency: 'GHS',
destination: {
type: 'bank_transfer',
account_number: '1234567890',
bank_code: 'GCB',
account_name: 'John Doe'
},
otp_code: '123456',
description: 'Vendor payment'
})payout = client.payouts.create(
amount=500,
currency='GHS',
destination={
'type': 'bank_transfer',
'account_number': '1234567890',
'bank_code': 'GCB',
'account_name': 'John Doe'
},
otp_code='123456',
description='Vendor payment'
)To send money to a consumer's Shika Wallet, use the Disbursements API with destination.type: "shika_wallet". The Payouts API only supports mobile_money and bank_transfer destinations.
Supported Providers
Mobile Money
| Provider | Code | Phone Prefixes |
|---|---|---|
| MTN Mobile Money | mtn | 024, 025, 053, 054, 055, 059 |
| Telecel Cash | telecel | 020, 050 |
| AirtelTigo Money | airteltigo | 026, 027, 056, 057 |
The provider is automatically detected from the phone number. You can optionally specify it explicitly.
Banks
| Bank | Code |
|---|---|
| Ghana Commercial Bank | GCB |
| Ecobank Ghana | ECO |
| Stanbic Bank | SBG |
| Standard Chartered | SCB |
| Absa Bank | ABSA |
| Fidelity Bank | FBN |
| CalBank | CAL |
| Access Bank | ABG |
| UBA Ghana | UBA |
| Zenith Bank | ZBG |
Contact support for the complete list of supported banks.
Response
{
"id": "po_abc123def456",
"object": "payout",
"amount": 100,
"currency": "GHS",
"fee": 1.50,
"status": "completed",
"destination": {
"type": "mobile_money",
"provider": "mtn",
"number": "024****567",
"name": "John Doe"
},
"description": "Salary payment",
"metadata": {
"employee_id": "123"
},
"provider_reference": "OP123456789",
"failure_reason": null,
"created_at": "2024-01-15T10:00:00Z",
"completed_at": "2024-01-15T10:00:05Z"
}Retrieve a Payout
Retrieves a payout by ID.
GET /v1/payouts/:idcurl https://api.shikacreators.com/v1/payouts/po_abc123def456 \
-H "Authorization: Bearer sk_test_..."const payout = await shikacreators.payouts.retrieve('po_abc123def456')payout = client.payouts.retrieve('po_abc123def456')List Payouts
Returns a list of payouts.
GET /v1/payoutsQuery Parameters
| Parameter | Type | Description |
|---|---|---|
limit | integer | Number of results (1-100) |
starting_after | string | Cursor for pagination |
status | string | Filter by status |
curl "https://api.shikacreators.com/v1/payouts?status=succeeded&limit=10" \
-H "Authorization: Bearer sk_test_..."const payouts = await shikacreators.payouts.list({
status: 'succeeded',
limit: 10
})payouts = client.payouts.list(status='succeeded', limit=10)Response
{
"object": "list",
"data": [
{
"id": "po_abc123def456",
"object": "payout",
"amount": 100,
"status": "succeeded",
...
}
],
"has_more": true,
"url": "/v1/payouts"
}Payout Statuses
| Status | Description |
|---|---|
created | Payout has been created |
pending | Payout is queued for processing |
processing | Payout is being processed by the provider |
succeeded | Payout was successful |
failed | Payout failed |
cancelled | Payout was cancelled |
Error Codes
| Code | Description |
|---|---|
insufficient_balance | Not enough balance in your account |
invalid_destination | Destination account is invalid |
recipient_unavailable | Recipient's account is unavailable |
daily_limit_exceeded | Daily payout limit exceeded |
amount_too_small | Amount below minimum (GHS 1.00) |
amount_too_large | Amount above maximum |
otp_verification_required | OTP verification is required |
invalid_phone_number | Invalid Ghana phone number |
Webhook Events
| Event | Description |
|---|---|
payout.created | Payout was created |
payout.pending | Payout is pending processing |
payout.completed | Payout was successful |
payout.failed | Payout failed |
app.post('/webhooks', (req, res) => {
const event = Webhook.constructEvent(req.body, signature, secret)
switch (event.type) {
case 'payout.completed':
const payout = event.data.object
console.log(`Payout ${payout.id} completed!`)
break
case 'payout.failed':
const failedPayout = event.data.object
console.log(`Payout failed: ${failedPayout.failure_reason}`)
break
}
res.json({ received: true })
})OTP Verification Flow
Payouts require OTP verification for security. Here's the complete flow:
Step 1: Request OTP
curl -X POST https://api.shikacreators.com/v1/otp/request \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"purpose": "PAYOUT"
}'Step 2: Verify OTP
curl -X POST https://api.shikacreators.com/v1/otp/verify \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"code": "123456",
"purpose": "PAYOUT"
}'Step 3: Create Payout
Use the verified OTP code when creating the payout:
curl -X POST https://api.shikacreators.com/v1/payouts \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"amount": 100,
"destination": {
"type": "mobile_money",
"phone_number": "0241234567"
},
"otp_code": "123456"
}'The OTP is valid for 10 minutes after verification. If expired, you'll need to request a new OTP.