# Initiate a Payout

Disburse funds directly to a customer's mobile money wallet or bank account. Payouts are processed asynchronously — the API queues the disbursement and notifies your server via webhook once the funds are settled.

* [ ] Mobile Money
* [ ] Bank Transfer

**How It Works**

Before initiating a payout, you may need to look up reference IDs depending on your disbursement method. Both flows share the same endpoint — only the request body differs.

1. **Fetch Prerequisites**

   For mobile money, call `GET /v1/countries` to get the `country_id`.\
   For bank transfers, also call `GET /v1/banks` to get the `bank_id`.
2. **Initiate the Payout**

   POST to `/v1/payment/payout/process` with the amount, destination, and transfer method. Vesicash queues the disbursement and returns a payout reference.
3. **Receive Webhook** \
   Vesicash sends a POST notification to your `webhook_url` when the payout status changes to successful or failed.

{% hint style="info" %}
**Amount Constraint**

The refund amount must not exceed the original transaction amount. Partial refunds are supported — you may call this endpoint multiple times as long as the cumulative refunded amount does not exceed the original charge.
{% endhint %}

#### <mark style="color:green;">POST:</mark> /v1/payment/payouts/process

#### Headers

| Name       | Type   | Description              |
| ---------- | ------ | ------------------------ |
| secret-key | string | Your Vesicash secret key |
| public-key | string | Your Vesicash public key |

**Request Body — Common Parameters**

These parameters apply to **all payout types** regardless of transfer\_to value.

* amount (number): The amount to disburse.
* countryId (string): The unique identifier for the country in which the transaction is being processed. To retrieve a valid `countryId`, call the [Get Countries endpoint](https://docs.vesicash.com/~/revisions/sUGfrlHe2F4873mAN9dv/get-countries) and use the `countryId` field from the matching country object in the response.
* transfer\_to (string): The disbursement method. Determines which additional fields are required.`mobile_number` ,`bank`
* webhook\_url (string):A publicly accessible HTTPS URL where Vesicash will POST the payout status notification.
* reason (string): The reason for the refund.

#### Additional Parameters by Transfer Type

The fields below are required depending on the value of `transfer_to`.

{% tabs %}
{% tab title="mobile\_number" %}
momo\_phone\_number (string): The mobile money phone number to receive the payout. Provide the full number in E.164 format — country code followed by the subscriber number, with no +, spaces, or dashes. E.g. `260999993000` instead of +`260999993000`
{% endtab %}

{% tab title="Tab 2" %}
bank\_id (string): The unique Vesicash identifier for the destination bank. Call `GET /v1/banks` to retrieve the list of supported banks and their IDs for the selected country.

account\_number (string): The recipient's bank account number. Must be a valid account number at the specified bank.
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**ℹ️ Fetching Bank IDs**

Use the `GET /v1/banks` endpoint with the relevant `country_id` to retrieve a list of available banks and their corresponding `bank_id` values before making a bank payout request.
{% endhint %}

#### Request

For example, you can make a post request to the endpoint above and pass in the raw json data below to refund a successful transaction.

```
//Mobile Money Payout

{
    
    "amount":0.4,
    "countryId": "{{country_Id}}",
    "transfer_to": "mobile_number",
    "momo_phone_number":"{{account_number}}",
    "webhook_url":"{{webhook_url}}",
    "narration":"testing" //optional
}
```

```

//Bank Transfer Payout

{
  "amount": 123,
  "countryId": "zambia_country_id",
  "transfer_to": "bank",
  "bank_id": "zmb_zanaco_001",             // from GET /v1/banks
  "account_number": "1234567890",
  "webhook_url": "https://yourapp.com/webhooks/vesicash",
  "narration": "March commission payout"           // optional
}
```

#### Response

```
{
  "status": "success",
  "code": 200,
  "message": "payout queued successfully",
  "data": {
    "amount": 123,
    "message": "Payout is being processed by the provider",
    "reference": "PY_6c663231b************",  // store this to track the payout
    "status": "processing"                       // will update via webhook
  }
}
```

#### Response Fields

| Field          | Type   | Description                                                                                                                                      |
| -------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| status         | string | Top-level outcome of the API call. `success` or `error`.                                                                                         |
| code           | number | HTTP status code mirror. `200` on success.                                                                                                       |
| data.reference | string | Unique payout reference assigned by Vesicash. Prefixed with PY\_. Use this to query the payout status endpoint or match incoming webhook events. |
| message        | string | Human-readable summary of the API response.                                                                                                      |
| data.status    | string | Current payout status. One of: `processing` `successful` `failed`                                                                                |
| data.amount    | string | The disbursement amount as received by Vesicash.                                                                                                 |

{% hint style="info" %}
Store the `data.reference` returned in the response. You can use it to query the  [status endpoint](https://docs.vesicash.com/~/revisions/B4WbZDJmrvuixkS1SN5C/api-documentation/payments/get-payment-details) or match it against incoming webhook payloads.
{% endhint %}

### Webhook Notification

Once the payout is processed, Vesicash sends a POST request to your `webhook_url` with the final payout outcome. Use this event — not the initial API response — to update your system's refund state.

```
{
    "amount": 2,
    "business_id": "56b2f01d-75e4-46e4-b8ec-",
    "charge": 0,
    "created_at": "2026-03-05T09:52:55.410737Z",
    "currency": "GHS",
    "customer": {
        "email": "",
        "firstname": "",
        "lastname": "",
        "phone_number": "23320887******"
    },
    "environment": "live",
    "event": "payout_successful",
    "id": "31741038-9ae5-46e6-aeb3-",
    "method": "mobilemoney",
    "narration": "testing",
    "provider_transaction_id": "",
    "redirect_url": "",
    "reference": "PY_72f5985*****",
    "status": "successful",
    "type": "payout"
}
```

{% hint style="info" %}
**✓ Signature Verification**

Always verify the X-Vesicash-Signature header on incoming webhooks using your webhook secret before updating any records. Discard requests with invalid signatures.
{% endhint %}

### Error Codes

| HTTP | Mesage                                                          | Description                                                                 |
| ---- | --------------------------------------------------------------- | --------------------------------------------------------------------------- |
| 400  | payout amount is less that 0                                    | The amount is zero, negative, or not a valid number.                        |
| 400  | payment not found                                               | The `payment_reference` does not match any transaction in your account.     |
| 400  | Insufficient funds or wallet error preventing refund processing | I                                                                           |
| 400  | Payout Provider service returned an error                       | The `momo_phone_number` is not a valid E.164 formatted mobile money number. |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.vesicash.com/api-documentation/payments/initiate-a-payout.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
