PayOuts

Overview

PayOut transactions allow you to send payments to beneficiaries via mobile money. When you initiate a payout, the funds are debited from your merchant wallet and sent to the recipient.

â„šī¸ Note: PayOut transactions are asynchronous. You'll receive an immediate acknowledgment, then get the final status via webhook callback or by querying the transaction status.
âš ī¸ Important: Ensure you have sufficient balance in your wallet before initiating a payout. Insufficient funds will result in an error.

Supported Payment Methods

Below are the mobile money payment methods available for each supported country:

Country Code Available Methods
Democratic Republic of Congo CD mpesa, airtel, orange, afrimoney
Zambia ZM airtel, mtn, zamtel
💡 Tip: Use these method slugs in the method parameter when initiating transactions.
Bank Transfer

Bank transfer payouts are available in NGN for Nigeria. Funds are sent directly to the recipient's Nigerian bank account.

Country Code Currency Method
Nigeria NG NGN bank_transfer
💡 Tip: Use the Lookup endpoints to get the list of banks and verify the recipient's account name before initiating a bank transfer payout.

POST Initiate PayOut

https://genesyspay.com/api/v2/payouts

Create a new PayOut transaction to send payment to a beneficiary.

Request Parameters
Parameter Type Required Description
amount number Required Transaction amount (minimum 0.01)
currency string Required 3-letter currency code (e.g., XOF, ZMW, GHS)
country string Required 2-letter country code (e.g., CI, ZM, GH)
channel string Required Payment channel: mobile_money or bank_transfer
method string Required Payment method slug (e.g., mtn-ci, airtel, orange-ci)
phone_number string Required* Beneficiary phone number. *Required for mobile_money, not used for bank_transfer.
account_number string Required* Recipient's bank account number. *Required for bank_transfer (10-digit NUBAN for Nigeria).
bank_code string Required* Recipient's bank code from the Get Banks endpoint (e.g., 058). *Required for bank_transfer.
beneficiary_name string Required Full name of the beneficiary
beneficiary_email string Optional Beneficiary email address
tx_ref string Required Your unique transaction reference. Used as idempotency key — prevents duplicate payouts on retry.
callback_url string Optional URL to receive transaction status webhook
extras object Optional Custom data to attach to transaction (returned in webhooks)
Example Request
curl -X POST https://genesyspay.com/api/v2/payouts \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_PRIVATE_KEY" \
  -d '{
    "amount": 100,
    "currency": "ZMW",
    "country": "ZM",
    "channel": "mobile_money",
    "method": "airtel",
    "phone_number": "260773317519",
    "beneficiary_name": "John Doe",
    "beneficiary_email": "[email protected]",
    "tx_ref": "123kj0e30m2",
    "callback_url": "https://yoursite.com/webhook",
    "extras": {
      "test": "tes",
      "order_id": "ORD-789"
    }
  }'
Success Response
{
  "status": "success",
  "message": "Transfer initiated successfully",
  "data": {
    "transaction_id": "TR260213.145421.B0EE88D4",
    "tx_ref": "123kj0e30m2",
    "amount": "100.00",
    "fee": "15.00",
    "total_amount": "115.00",
    "currency": "ZMW",
    "status": "SUBMITTED",
    "channel": "mobile_money",
    "payment_method": "airtel",
    "summary": "Transfer submitted to provider",
    "mobile_money": {
      "phone_number": "260773317519",
      "network": "airtel",
      "mno_transaction_id": null
    },
    "extras": {
      "test": "tes",
      "order_id": "ORD-789"
    },
    "account_balance": {
      "previous_balance": "895.00",
      "current_balance": "780.00",
      "balance_type": "AVAILABLE"
    },
    "created_at": "2026-02-13T14:54:21+00:00",
    "updated_at": "2026-02-13T14:54:21+00:00"
  }
}
Example Request — Bank Transfer (Nigeria)
💡 Recommended: Call Lookup Bank Account first to verify the recipient's account name before sending.
curl -X POST https://genesyspay.com/api/v2/payouts \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_PRIVATE_KEY" \
  -d '{
    "amount": 5000,
    "currency": "NGN",
    "country": "NG",
    "channel": "bank_transfer",
    "method": "bank_transfer",
    "account_number": "0123456789",
    "bank_code": "058",
    "beneficiary_name": "John Doe",
    "beneficiary_email": "[email protected]",
    "tx_ref": "BT-OUT-NG-001",
    "callback_url": "https://yoursite.com/webhook"
  }'
Success Response — Bank Transfer
{
  "status": "success",
  "message": "Transfer initiated successfully",
  "data": {
    "transaction_id": "TR260521.152000.D4E5F6G7",
    "tx_ref": "BT-OUT-NG-001",
    "amount": "5000.00",
    "fee": "53.75",
    "total_amount": "5053.75",
    "currency": "NGN",
    "status": "SUBMITTED",
    "channel": "bank_transfer",
    "payment_method": "bank_transfer",
    "summary": "Bank transfer from BIZ LTD",
    "bank_transfer": {
      "account_number": "0123456789",
      "bank_code": "058",
      "beneficiary_name": "John Doe"
    },
    "failure_reason": null,
    "extras": null,
    "account_balance": {
      "previous_balance": "20000.00",
      "current_balance": "14946.25",
      "balance_type": "AVAILABLE"
    },
    "created_at": "2026-05-21T15:20:00+00:00",
    "updated_at": "2026-05-21T15:20:01+00:00"
  }
}
Error Responses
Error Code HTTP Status Description
VALIDATION_ERROR 422 Invalid or missing parameters
INVALID_CURRENCY 422 Currency not supported
INVALID_COUNTRY 422 Country not supported
METHOD_NOT_AVAILABLE 422 Payment method not available for currency/country
AMOUNT_OUT_OF_LIMITS 422 Amount outside allowed limits for this method
INVALID_ARGUMENT 400/422 tx_ref already exists or invalid request data
PAYMENT_FAILED 400/503 Insufficient funds or payout processing failed
PROVIDER_ERROR 422 Payment provider error
INTERNAL_ERROR 500 Internal server error
Insufficient Funds Error Example
{
  "status": "error",
  "message": "Insufficient funds in wallet",
  "error_code": "PAYMENT_FAILED"
}

GET Get Transaction by ID

https://genesyspay.com/api/v2/payouts/{identifier}

Retrieve a specific PayOut transaction by its ID or reference.

Example Request
curl -X GET https://genesyspay.com/api/v2/payouts/TR260213.145421.B0EE88D4 \
  -H "Authorization: Bearer YOUR_PRIVATE_KEY"
Response
{
  "status": "success",
  "data": {
    "transaction_id": "TR260213.145421.B0EE88D4",
    "tx_ref": "123kj0e30m2",
    "amount": "100.00",
    "fee": "15.00",
    "total_amount": "115.00",
    "currency": "ZMW",
    "status": "SUCCESS",
    "channel": "mobile_money",
    "payment_method": "airtel",
    "summary": "Transfer completed successfully",
    "mobile_money": {
      "phone_number": "260773317519",
      "network": "airtel",
      "mno_transaction_id": "MNO987654321"
    },
    "extras": {
      "test": "tes",
      "order_id": "ORD-789"
    },
    "account_balance": {
      "previous_balance": "895.00",
      "current_balance": "780.00",
      "balance_type": "AVAILABLE"
    },
    "created_at": "2026-02-13T14:54:21+00:00",
    "updated_at": "2026-02-13T14:54:31+00:00"
  }
}

GET Get Transaction by tx_ref

https://genesyspay.com/api/v2/payouts/status/{txRef}

Retrieve a PayOut transaction using your custom transaction reference.

Example Request
curl -X GET https://genesyspay.com/api/v2/payouts/status/123kj0e30m2 \
  -H "Authorization: Bearer YOUR_PRIVATE_KEY"

GET List PayOut Transactions

https://genesyspay.com/api/v2/payouts

Retrieve a paginated list of all PayOut transactions.

Query Parameters
Parameter Type Description
status string Filter by status: PENDING, SUBMITTED, SUCCESS, FAILED, CANCELLED
per_page integer Results per page (1-100, default: 20)
page integer Page number (default: 1)
Example Request
curl -X GET "https://genesyspay.com/api/v2/payouts?status=SUCCESS&per_page=10&page=1" \
  -H "Authorization: Bearer YOUR_PRIVATE_KEY"
Response
{
  "status": "success",
  "data": [
    {
      "transaction_id": "TR260213.145421.B0EE88D4",
      "tx_ref": "123kj0e30m2",
      "amount": "100.00",
      "status": "SUCCESS",
      "created_at": "2026-02-13T14:54:21+00:00"
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 3,
    "per_page": 10,
    "total": 25
  }
}

Transaction Statuses

Status Description
PENDING Transaction initiated, awaiting processing
SUBMITTED Transaction submitted to payment provider
SUCCESS Payout completed successfully
FAILED Payout failed (see failure_reason for details)
CANCELLED Transaction cancelled

Webhook Notification

When a payout transaction status changes, we'll send a POST request to your callback_url with the transaction details. For complete webhook implementation guide, retry logic, security best practices, and webhook resend functionality, see the Webhooks documentation.

Webhook Structure
{
  "event": "payout.successful",
  "timestamp": 1770994473,
  "data": {
    "transaction_id": "TR260213.145421.B0EE88D4",
    "tx_ref": "123kj0e30m2",
    "amount": "100.00",
    "fee": "15.00",
    "total_amount": "115.00",
    "currency": "ZMW",
    "status": "SUCCESS",
    "channel": "mobile_money",
    "payment_method": "airtel",
    "summary": "Transfer from BIZ LTD via airtel",
    "failure_reason": null,
    "created_at": "2026-02-13T14:54:21+00:00",
    "updated_at": "2026-02-13T14:54:31+00:00",
    "mobile_money": {
      "phone_number": "260773317519",
      "network": "airtel",
      "mno_transaction_id": null
    },
    "extras": {
      "test": "tes"
    },
    "account_balance": {
      "previous_balance": "895.00",
      "current_balance": "780.00",
      "balance_type": "AVAILABLE"
    }
  }
}
Webhook Events
Event Description
payout.successful Payout completed successfully
payout.failed Payout failed (check failure_reason)
payout.bank_transfer.successful Bank transfer payout credited to recipient account
payout.bank_transfer.failed Bank transfer payout failed (check failure_reason)
💡 Tip: Your webhook endpoint should respond with HTTP 200 to acknowledge receipt. We will retry failed webhook deliveries with exponential backoff. If you miss a webhook, you can manually resend it - see the Webhooks documentation for details.
Webhook Security

Configure a webhook secret in your API Settings to verify webhook authenticity. The signature will be sent in the X-Webhook-Signature header. See the Webhooks documentation for implementation examples.

Best Practices

  • Check Balance: Always verify sufficient wallet balance before initiating payouts
  • Use tx_ref: Provide unique transaction references to prevent duplicates and aid tracking
  • Implement Webhooks: Don't poll for status - use webhooks for real-time updates
  • Handle Failures: Check the failure_reason field when status is FAILED
  • Validate Phone Numbers: Ensure phone numbers are in the correct format for the country
  • Monitor Limits: Be aware of minimum and maximum transaction amounts per method