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, bank_transfer, or shika_wallet |
destination.provider | string | Provider (e.g., mtn, telecel, airteltigo) |
destination.number | string | Masked account/phone number or consumer account ID |
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, bank_transfer, or shika_wallet |
destination.phone_number | string | Yes* | Phone number (for mobile money or shika_wallet lookup) |
destination.provider | string | No | Provider code (auto-detected from phone) |
destination.account_number | string | Yes* | Account number (for bank transfer) |
destination.bank_code | string | Yes* | Bank code (for bank transfer) |
destination.account_id | string | Yes* | Consumer account ID (for shika_wallet, e.g., acc_xxx) |
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'
)Shika Wallet Payout
Send money directly to a consumer's Shika Wallet. This method is instant — no external payment provider is involved.
curl -X POST https://api.shikacreators.com/v1/payouts \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"amount": 50,
"currency": "GHS",
"destination": {
"type": "shika_wallet",
"account_id": "acc_abc123def456"
},
"otp_code": "123456",
"description": "Cashback reward"
}'const payout = await shikacreators.payouts.create({
amount: 50,
currency: 'GHS',
destination: {
type: 'shika_wallet',
account_id: 'acc_abc123def456'
},
otp_code: '123456',
description: 'Cashback reward'
})payout = client.payouts.create(
amount=50,
currency='GHS',
destination={
'type': 'shika_wallet',
'account_id': 'acc_abc123def456'
},
otp_code='123456',
description='Cashback reward'
)You can also use phone_number instead of account_id to look up the consumer by their registered phone number.
Shika Wallet payouts are completed instantly. The status will be completed in the response — no need to poll for status updates.
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.