Xtopay
Payment APIs

Direct Send Money

Disburse funds directly to a customer's Mobile Money wallet instantly via API.

Direct Send Money

The Direct Send Money API allows merchants to programmatically disburse funds directly from their Xtopay Disbursement Account to any customer's Mobile Money wallet. This is ideal for payouts, customer refunds, withdrawals, affiliate commission payouts, cashbacks, and any other automated disbursement flow.


Supported Channels

Xtopay supports direct disbursements across the following networks:

Mobile Money ProviderChannel IdentifierCountry
MTN Mobile Moneymtn-ghGhana
Telecel Cashvodafone-ghGhana
AT Money (AirtelTigo)tigo-ghGhana

Disbursement Account Funding

To disburse payments via the Direct Send Money API, your business must maintain an active balance in your Disbursement Account.

You can fund your Disbursement Account via one of two methods:

  • Online Funding: Fund it using bank transfer or card payment from your merchant dashboard.
  • Balance Transfer: Instantly transfer settled funds from your Xtopay Collection Account to your Disbursement Account.

For detailed custom limits or support, please contact your Xtopay Account / Relationship Manager.


Business IP Whitelisting

[!WARNING] Whitelisting Required Direct Send Money endpoints are live and require strict IP whitelisting. Requests from non-whitelisted IP addresses will return a 403 Forbidden error or timeout.

Please submit your production server public IP addresses to your Xtopay Retail Systems Engineer for whitelisting. We permit a maximum of four (4) IP addresses per service key.


Understanding the Service Flow

The Direct Send Money process is asynchronous. When you send money, Xtopay processes and forwards the request to the mobile money networks. The final delivery status is usually resolved within 30 seconds.

Service Steps

StepDescription
1Your server makes a Send Money request to POST /v1/payments/send.
2Xtopay validates the credentials and disbursement balance, debits the account, and returns a pending status PROCESSING (ResponseCode 0001).
3Xtopay dispatches the funds to the mobile wallet.
4Once confirmed by the carrier, Xtopay dispatches an HTTP POST webhook callback containing the final state.
5If no callback is received within five (5) minutes of initiation, query the Transaction Status Check API (GET /v1/payments/:reference) to verify.

Direct Send Request Flow

sequenceDiagram
    autonumber
    actor Customer
    participant AppServer as Merchant Server
    participant Xtopay as Xtopay API
    participant Telco as Telco Gateway

    AppServer->>Xtopay: POST /v1/payments/send (Auth: Bearer secret_key)
    Xtopay-->>AppServer: Return processing response (ResponseCode 0001)
    Xtopay->>Telco: Forward payout request
    Telco-->>Customer: Funds deposited in recipient wallet
    Telco-->>Xtopay: Payout settlement confirmation
    Xtopay->>AppServer: Send Webhook Callback (POST payment.succeeded)
    Note over AppServer, Xtopay: Fallback: Check status via GET /v1/payments/:reference if callback fails

API Reference

To initiate a payout transaction, send an HTTP POST request to the endpoint below.

DetailDescription
API Endpointhttps://api.xtopay.co/v1/payments/send
Request TypePOST
Content Typeapplication/json
AuthenticationBasic Base64(clientId:clientSecret)

Request Parameters

ParameterTypeRequiredDescription
amountIntegerYesSpecifies the total amount to disburse in minor units (e.g. 20000 = GHS 200.00). Decimals are not allowed.
currencyStringNoThree-letter ISO 4217 currency code (e.g. GHS, NGN, USD). Defaults to GHS.
phoneStringYesThe recipient's mobile wallet number in international format (e.g. 233200000000 or +233200000000).
providerStringYesThe provider code channel identifier. Available channels: MTN, TELECEL, AIRTELTIGO.
nameStringYesThe recipient name matching their mobile wallet profile. The phone number can be passed as a placeholder if name is unknown.
descriptionStringYesTransaction details displayed to the recipient on wallet logs.
customerIdStringNoOptional Xtopay customer ID to associate the payout with.
metadataObjectNoFlat JSON key-value store to attach merchant references (e.g. { "clientReference": "3jL2KlUy3vt21" }).

Response Parameters

ParameterTypeDescription
successBooleanIndicates if the payout request was accepted successfully.
dataObjectPayload containing disbursement details.
data.idStringUnique transaction ID generated by Xtopay.
data.referenceStringUnique transaction reference string.
data.amountIntegerPayout amount in minor units.
data.feeIntegerPlatform processing fee in minor units.
data.statusStringStatus of the disbursement (always PROCESSING).
data.phoneStringIngested recipient phone number.
data.nameStringRecipient wallet name.
data.createdAtStringISO 8601 creation timestamp.

Code Examples

curl https://api.xtopay.co/v1/payments/send \
  -u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 80,
    "currency": "GHS",
    "phone": "233200000000",
    "provider": "TELECEL",
    "name": "Joe Doe",
    "description": "Union Dues Payout",
    "metadata": {
      "clientReference": "3jL2KlUy3vt21"
    }
  }'

Sample Response

200 OK

{
  "success": true,
  "responseCode": "0001",
  "data": {
    "id": "pay_09f84e20a283942e807128e8c21d0303",
    "reference": "3jL2KlUy3vt21",
    "status": "PROCESSING",
    "amount": 80,
    "fee": 0,
    "currency": "GHS",
    "phone": "233200000000",
    "name": "Joe Doe",
    "createdAt": "2026-06-06T12:00:00Z"
  }
}

Webhook Callback

Xtopay dispatches callback webhook alerts to your registered URL once the payout is finalized by the telco gateway.

Sample Callback (Successful)

{
  "ResponseCode": "0000",
  "Data": {
    "AmountDebited": 80,
    "TransactionId": "09f84e20a283942e807128e8c21d0303",
    "ExternalTransactionId": "142116938399",
    "Description": "Telecel Cash payment has been made successfully",
    "ClientReference": "3jL2KlUy3vt21",
    "Amount": 80,
    "Charges": 1,
    "Meta": null,
    "RecipientName": "Joe Doe"
  }
}

Sample Callback (Failed)

{
  "ResponseCode": "4075",
  "Data": {
    "AmountDebited": 80,
    "TransactionId": "08f84e20a283942e807128e8c21d0302",
    "ExternalTransactionId": null,
    "Description": "Insufficient prepaid balance.",
    "ClientReference": "3jL2KlUy3vt21",
    "Amount": 80,
    "Charges": 0,
    "Meta": null,
    "RecipientName": null
  }
}

Transaction Status Check

Checks the status of a send transaction. It is mandatory to implement this check to verify the final transaction state if no webhook callback is received within 5 minutes of initiation.

To poll the status, send an HTTP GET request appending the unique client reference.

DetailDescription
API Endpointhttps://api.xtopay.co/v1/payments/:reference
Request TypeGET
Content Typeapplication/json
AuthenticationBasic Base64(clientId:clientSecret)

Request Parameters

ParameterTypeRequiredDescription
:referenceStringYesThe client reference of the transaction (3jL2KlUy3vt21).

Sample GET Request

curl https://api.xtopay.co/v1/payments/3jL2KlUy3vt21 \
  -u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET"

Sample Response (Succeeded)

200 OK

{
  "ResponseCode": "success",
  "data": {
    "TransactionId": "09f84e20a283942e807128e8c21d0303",
    "networkTransactionId": "142116938399",
    "Amount": 80,
    "Fees": 1,
    "ClientReference": "3jL2KlUy3vt21",
    "Channel": "vodafone-gh",
    "CustomerNumber": "233200000000",
    "transactionStatus": "success",
    "CreatedAt": "2026-06-06 12:00:00"
  }
}

Response Codes & Actions

Response CodeDescriptionRequired Action
0000Payout has been completed successfully.None. Update the transaction as successful in your local logs.
0001Payout request accepted. Webhook will be sent once processed.Mark the payout as pending. Wait for the webhook callback.
2001payment failed (e.g. invalid recipient wallet number, duplicate client reference).Verify the recipient number or review if the reference was previously used.
3050mobile number is not registered for Mobile Money payouts.Verify the number with the customer and ensure the correct network provider.
4000Validation errors. Request payload contains incorrect parameters.Inspect the request parameter schemas and try again.
4075Insufficient prepaid balance.Top up your Disbursement Account balance from your Xtopay dashboard.
5000Internal error. Xtopay or carrier gateway is undergoing maintenance.Retry in a few minutes or contact Xtopay support.

How is this guide?

Edit this page on GitHub
Last updated on June 6, 2026

On this page