# Overview

This documentation walks you through the process of integrating Vesicash Payment and Merchant of Records capabilities into your existing platform.

Welcome to the Vesicash API documentation :-)

This document highlights the requirement for 3rd party application integration with the Vesicash API. It strives to be RESTful and is designed with flexibility and ease of integration using any programming language by banks, payment processors, marketplaces or ecommerce providers.


# API Basics

The API gives you access to all payment features that you can use on our dashboard and lets you extend them for use in your application. The API allows you initiate payment, make payment, and manage payout transactions between yourself and another party. Here's is what you need to do:

* Create an account: Start your experience by creating a free [Vesicash account](https://merchant.vesicash.com/). By default, you would have access to your test environment after you sign up. The test keys can be generated from the developer's tab of the settings page.

<figure><img src="/files/5npp1BWETdx907vahdxL" alt=""><figcaption></figcaption></figure>

* Configure your integration: Utilize our API integration to configure your payment system.
* Complete your KYC: To take your account live, We'll need to review your details and profile it correctly for the best experience. You are required to submit your business documents and other relevant information to make this review possible.
* Go live and accept payments from your customers: Once your account has been approved, you can start collecting payments from your customers

When you've fully tested and are ready to go live, you can proceed to create a [live business account](https://merchant.vesicash.com/) and of course, login to generate[ live API Keys](https://merchant.vesicash.com/) to replace the test keys.&#x20;

### Making a Request

Next to each endpoint is the expected method to access that endpoint. All you need to do is pass in the specific parameters as will be shown in this documentation, and you can make calls to the endpoints.

### Input/Output Format

Both request body data and response data are formatted as JSON. Content type for responses will always be `application/json`.

Generally, all responses will be in the following format:

{% hint style="info" %}

#### Standard API response format

{\
&#x20;"status": \[string] - indicating whether or not the request could be processed,\
"code" : \[integer] - indicating the request code,\
&#x20;"message": \[string] - contains the result of the action that was processed,\
"data": \[object] - contains the payload of the action that was processed\
}
{% endhint %}

### Base URL

All API requests must be made over HTTPS to the following base URL, and unencrypted HTTP connections are not supported.&#x20;

When calling any API, the environment keys used, would determine if the request is on a test environment of live environment.&#x20;

**NOTE:** All request must be made with a valid Vesicash public and Private keys.

| Environment | URL                            |
| ----------- | ------------------------------ |
| Production  | <https://api.mor.vesicash.com> |


# Authentication

The Vesicash API supports basic authentication using the access Keys (public and private keys) which is accessible via the Vesicash dashboard.&#x20;

Public keys are fielded from any front-end integration like the Vesicash app. By design, public keys cannot modify any part of you or your customer account details besides initiating transactions and making payments. The private keys however, are to be kept secret. If for any reason you believe your private key has been compromised or you wish to reset them, you can do so from the dashboard.

### Usage

Authenticate your API calls by including your private key in the header of each request you make.&#x20;

```
 --header 'accept: application/json' \
 --header 'V-PRIVATE-KEY: v_EnterThePrivateKeyThatWasGeneratedHere' 
 --header 'V-PUBLIC-KEY: v_EnterThePublicKeyThatWasGeneratedHere' 
```

> While carrying out api test, we will provide you **test keys** for test transactions. However, after testing, you must switch to the **Live keys** in production whilst deploying.

API requests made without authentication will fail with the status code `401: Unauthorized`


# Errors

Again, Vesicash API is RESTful and uses conventional HTTP response codes to indicate the success or failure status of requests.

| Status Code             | Description                                                                                                                                     |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| 200, 201                | The request was successful and intended action was carried out.                                                                                 |
| 400                     | The request could not be fulfilled because it already exists or is a bad request                                                                |
| 401                     | The request was not authorized. This occurs when you fail to pass in a private key in the authorization header or the one passed in is invalid. |
| 404                     | The request could not be fulfilled as the request resource does not exist.                                                                      |
| 500, 501, 502, 503, 504 | The request could not be fulfilled due to an error from Vesicash. This shouldn't happen, so please report as soon as you encounter this.        |

#### Failure Reasons

This section lists all possible failure reasons returned by the API, along with their descriptions and corresponding status values. Use these codes to understand and handle failed transaction responses.

| Failure Reason                     | Description                                         | Status  |
| ---------------------------------- | --------------------------------------------------- | ------- |
| ABANDONED\_TRANSACTION             | Abandoned transaction/PIN not inputted              | Failed  |
| DECLINED\_TRANSACTION              | Declined transaction                                | Failed  |
| INSUFFICIENT\_FUNDS                | Insufficient Wallet Balance                         | Failed  |
| INVALID\_PIN                       | PIN Mismatch                                        | Failed  |
| TRANSACTION\_LIMIT\_EXCEEDED       | Transaction Limit Exceeded                          | Failed  |
| ACCOUNT\_NOT\_FOUND                | Invalid Wallet Account                              | Failed  |
| ACCOUNT\_BLOCKED                   | Wallet Locked / Suspended                           | Failed  |
| PROVIDER\_TIMEOUT                  | Provider System Timeout                             | Failed  |
| TRNASACTION\_FAILED                | Transaction failed on the provider’s end            | Failed  |
| <p></p><p>TRNASACTION\_PENDING</p> | Transaction was still pending on the provider's end | Pending |


# Payments


# Introduction

All business account on Vesicash is opened to a Merchant of Record service. By default a USD and a GBP MoR wallet is created for all account after ongoing proper onboarding on the platform.

Our MoR service cuts across some African countries, such as **Ghana, Kenya, Egypt, South Africa** and **Zambia**. To setup an MoR service in any of these countries, you would need to sign an MoR agreement on that country on Vesicash platform. Then you should be eligible to carryout transaction in that country.

Each MoR transaction attracts a certain sales tax percentage, which would be deducted when your MoR funds is being processed from your MoR wallet to your base wallet.

Vesicash provides a seamless way to accept payments across multiple channels, including **cards** and **mobile money**. Whether you're integrating payments into a website, mobile application, or a custom checkout flow, our flexible APIs give you complete control while ensuring secure and smooth transactions.

Vesicash supports **two payment completion flows**, depending on your preferred integration style:

#### **1. Checkout flow (Redirect flow)** <a href="#id-1.-checkout-flow-redirect-flow" id="id-1.-checkout-flow-redirect-flow"></a>

Use this flow if you want Vesicah to handle the entire payment UI/UX.

**Steps:**

1. **Initiate payment**: Call the Initiate Payment endpoint to create a new transaction.
2. **Redirect Customer**: Extract the payment\_link returned in the response.
3. **Customer Completes Payment**: Redirect the customer to the Vesicash-hosted checkout page where they complete the transaction.

#### 2. Non‑Checkout Flow (Direct API Flow) <a href="#id-2.-non-checkout-flow-direct-api-flow" id="id-2.-non-checkout-flow-direct-api-flow"></a>

Use this flow if you want to handle the checkout UI yourself and complete payments programmatically via API.

**Steps:**

1. **Initiate Payment:**

* Call the **`Initiate Payment`** endpoint to begin the transaction.
* The response includes a **`payment_reference`**.

2. **Complete Payment**: Call the Complete Payment endpoint, passing the payment\_reference returned during initiation.<br>

<br>

<br>


# Mobile Money

Collect mobile money payments from your customers.

Mobile money lets you accept payments from customers using their mobile wallets. It is a fast, secure, and convenient payment method that does not require a bank account.

{% hint style="info" %}
**Supported networks and regions**

Alexpay currently supports mobile money payments in Ghana and Zambia for the following networks:

* Ghana: **MTN** and **Telecel**
* Zambia: **MTN**, **Airtel** and **Zamtel**
  {% endhint %}

#### Requirements

Before integrating mobile money payments, complete the following steps:

1. Review the [Introduction section](https://docs.vesicash.com/api-documentation/payments/introduction) before you continue with this guide.
2. Retrieve your API keys from the [Vesicash Dashboard](https://merchant.vesicash.com/login) to authorize requests.
3. Generate your webhook secret using the [Generate Webhook Secret](https://docs.vesicash.com/generate-webhook-secret) endpoint. This is required to start receiving and securely verifying webhook notifications.

**How Mobile Money Payments Work**

When a customer selects Mobile Money as their payment method, a push notification is sent to their registered mobile device. To complete the transaction, the customer must:

1. Open the notification on their mobile device.
2. Authorize the payment by inputting their PIN or following the provider's authentication process.
3. Once authorized, the payment is processed, and both the customer and the merchant receive a confirmation.

<br>


# Checkout - flow

The **Standard Checkout** integration allows you to generate a unique, secure payment URL that your customers can use to complete their transactions on the Vesicash-hosted payment page. This is the quickest and simplest way to start accepting payments with minimal backend implementation.

1. **Initialize the Payment**: Make a server-side POST request to the payment initialization endpoint:
2. **Redirect the Customer**: Upon a successful request, we’ll return a unique link for the payment page. Redirect your customer to this page to complete their payment.
3. **After the Payment**: Once the payment is completed, the customer will be redirected back to your provided redirectUrl. You can use this event to confirm the transaction and update your records.

**Step 1: Initialize the Payment**

Send a server‑side POST request to the payment initialization endpoint.

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

#### Headers

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

#### Request body

* currency (string): The currency for the payment.
* country (string): The country for the payment.
* reference (string, optional): The transaction reference. If not provided, a value will be generated internally. The reference must be at least 10 characters long.
* narration (string): Description or reason for the payment.
* method (string): The payment method to be used.
* amount (number): The amount of the payment.
* webhook\_url (string): A URL where notifications about the payment status will be sent.
* redirect\_url (sting):

#### Request

For example, you can make a post request to the endpoint above and pass in the raw json data below to create a one-off transaction.

```
{
"currency": "ZMW",
    "country": "ZM",
    "narration": "payment for rice",
    "reference": "***********"
    "method": "mobilemoney", //"card"
    "amount": 1.3,
    "webhook_url: "",
    "redirect_url": "",
}
```

#### Step 2: Redirect the Customer&#xD;

Upon a successful request, we’ll return a paymentLink for the payment page. Redirect the customer to this URL in your browser or mobile app.

#### Response

```
{
    "status": "success",
    "code": 200,
    "message": "success",
    "data": {
        "payment_link": "",
        "reference": "",
        "payment_id": "",
        "status": "pending"
    }
}
```

**Step 3: After the Payment**

Once the customer completes the payment on the Vesicash checkout page:

1. **Customer Redirect**: The customer is redirected to the redirectUrl you provided in the initialization request.
2. **Query Payment Status**: Your server should call the Payment Status endpoint to confirm the final state of the transaction (e.g., success, failed, pending).
3. **Receive Webhook Notification**: Vesicash automatically sends webhook notifications to your configured URL whenever a transaction status changes, provided your webhook secret is properly generated and verified.


# Non‑Checkout Flow

The **Non‑Checkout Flow** allows you to collect mobile money payments **without redirecting the customer to the Vesicash checkout page**.

In this method, you initiate the payment from your backend and then complete it by making a direct API call using the payment reference.

This flow is ideal when you want **full control of the payment experience** within your website, mobile app, or custom UI.

**How the Non‑Checkout Mobile Money Flow Works**

1. **Initialize the Payment**: Make a server-side POST request to the payment initialization endpoint. Vesicash returns a paymentReference that uniquely identifies the transaction.
2. **Complete the Payment**: Using the paymentReference returned during initiation, your server immediately calls the Complete Payment endpoint. Vesicash will use this reference to trigger the Mobile Money push prompt on the customer’s device.
3. **After the Payment**: Once the payment is completed you can check the status on the status check endpoint and a webhook notification will be sent.

**Step 1: Initialize the Payment**

Send a server‑side POST request to the payment initialization endpoint.

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

#### Headers

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

#### Request body

* currency (string): The currency for the payment.
* country (string): The country for the payment.
* reference (string, optional): Transaction reference. If not supplied, the system will internally generate a value. Must be at least 10 characters long.
* narration (string): Description or reason for the payment.
* method (string): The payment method to be used.
* amount (number): The amount of the payment.
* webhook\_url (string): A URL where notifications about the payment status will be sent.
* redirect\_url (sting):

#### Request

For example, you can make a post request to the endpoint above and pass in the raw json data below to create a one-off transaction.

```
{
"currency": "ZMW",
    "country": "ZM",
    "narration": "payment for rice",
    "reference":"**********"
    "method": "mobilemoney", //"card"
    "amount": 1.3,
    "webhook_url: "",
    "redirect_url": "",
}
```

#### Response

```
{
    "status": "success",
    "code": 200,
    "message": "success",
    "data": {
        "payment_link": "",
        "reference": "",
        "payment_id": "",
        "status": "pending"
    }
}
```

**Step 2: Complete the Payment**

Immediately after receiving the paymentReference, your server must complete the transaction.

This call triggers the Mobile Money push prompt on the customer’s device.

<mark style="color:$success;">**POST**</mark>**: /v1/payment/pay/:payment\_reference**

**Params**

| Name               | Type   | Description                                                        |
| ------------------ | ------ | ------------------------------------------------------------------ |
| payment\_reference | string | The payment reference that was generated when initializing payment |

#### Headers

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

#### Request body

* account\_number (string): The account number for the payment. For mobile money payments, this can also be the customer’s phone number. It must include the country code but should not include the + sign or the leading 0.
* customer\_first\_name (string): The customer’s first name.
* customer\_last\_name (string): The customer’s last name.
* phone\_number (string): The customer’s phone number. It must include the country code but should not include the + sign or the leading 0.
* email (number): The customer’s email address.
* method (string): The payment method to be used.

#### Request

```
{
    "account_number":"{{phone_number}}",
    "customer_first_name":"Greghh",
    "customer_last_name": "Greg",
    "phone_number":"{{phone_number}}",
    "email":"grveg@gmail.com",
    "method":"mobilemoney"

}
```

#### Response

```
{
    "status": "success",
    "code": 200,
    "message": "payment sent for processing",
    "data": {
        "message": "payment sent for processing",
        "device_storage_token": null,
        "method": "mobilemoney",
        "payment_status": "pending",
        "operator": "MTNGhana"
    }
}
```

The customer receives a Mobile Money prompt and approves the payment using their PIN.

Once approval is completed, Vesicash processes the transaction.

**Step 3: After the Payment**

Once the customer completes the payment on the Vesicash checkout page:

1. **Query Payment Status**: Your server should call the Payment Status endpoint to confirm the final state of the transaction (e.g., success, failed, pending).
2. **Receive Webhook Notification**: Vesicash automatically sends webhook notifications to your configured URL whenever a transaction status changes, provided your webhook secret is properly generated and verified.


# Card Payment

Card Payments allow customers to pay securely using their debit or credit cards. Vesicash supports 3‑D Secure (3DS) authentication for enhanced security and fraud protection.

{% hint style="info" %}
**Supported Card Processors**

Alexpay currently supports mobile money payments in Ghana and Zambia for the following networks:

* **MPGS:** Domestic payments in **Ghana**
* **SyberSource:** Cross‑border payments
* **GTI Payments: USD payment**
  {% endhint %}

#### Requirements

Before integrating mobile money payments, complete the following steps:

1. Review the [introduction section](https://docs.vesicash.com/~/revisions/T2SeA1NC6K5Q60gXmVDh/api-documentation/payments/introduction) before you continue with this guide.
2. Retrieve your API keys from the [Vesicash Dashboard](https://merchant.vesicash.com/login) to authorize requests.
3. Generate your webhook secret using the [Generate Webhook Secret](https://docs.vesicash.com/generate-webhook-secret) endpoint. This is required to start receiving and securely verifying webhook notifications.

**How Mobile Money Payments Work**

When a customer selects Card as their payment method, Vesicash automatically handles the 3DS authentication process.

1. **Customer Chooses Card Payment**: The customer selects "Card" as the payment option on the initialization endpoint.
2. **Redirect to 3DS Authentication Page**: Alexpay displays a secure, PCI‑compliant 3DS page for authentication.
3. **Customer Completes 3DS Authentication:**<br>

<br>


# Checkout - flow

The **Standard Checkout** integration allows you to generate a unique, secure payment URL that your customers can use to complete their transactions on the Vesicash-hosted payment page. The flow supports two active operators depending on the currency of the transaction. &#x20;

1. **GTI** - Exclusively for **USD** payments.
2. **MPGS** - Exclusively for **GHS** payments.

#### STEPs

1. **Initialize the Payment**: Make a server-side POST request to the payment initialization endpoint:
2. **Redirect the Customer**: Upon a successful request, we’ll return a unique link for the payment page. Redirect your customer to this page to complete their payment.
3. **After the Payment**: Once the payment is completed, the customer will be redirected back to your provided redirectUrl. You can use this event to confirm the transaction and update your records.

#### **Step 1: Initialize the Payment**

Send a server‑side POST request to the payment initialization endpoint.

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

#### Headers

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

#### Request body

* currency (string): The currency for the payment.
* country (string): The country for the payment.
* narration (string): Description or reason for the payment.
* reference (string, optional): Transaction reference. If not supplied, the system will internally generate a value. Must be at least 10 characters long.
* method (string): The payment method. Expected value is usually card..
* amount (number): The amount of the payment.
* operator(string): The payment gateway operator to use. Expected values are `gti` or `mpgs`.
* redirect\_success\_url(string): The absolute URL where the user will be redirected to upon a successful payment.
* redirect\_failed\_url(string):The absolute URL where the user will be redirected to if the payment fails.
* integration\_type(string): Required when operator is `mpgs`. The expected value is `DIRECT_API`.
* webhook\_url (string): A URL where notifications about the payment status will be sent.

#### Request

&#x20;**1. GTI (USD Payments)**

The GTI operator is strictly used for payments in USD.

```
{
    "amount": 1,
    "currency": "USD",
    "country": "US",
    "method": "card",
    "operator": "gti",
    "refence":"**************"
    "narration": "Checkout GTI Test",
    "redirect_success_url": "https://www.yourdomain.com/success",
    "redirect_failed_url": "https://merchant.yourdomain.com/login",
    "webhook_url": "https://api.yourdomain.com/webhooks/checkout"
}

```

#### &#x20;2. MPGS (GHS Payments)&#xD;

The MPGS operator is used for payments in GHS. Notice the inclusion of the `integration_type` attribute.

```
{
    "amount": 1,
    "country": "GH",
    "currency": "GHS",
    "method": "card",
    "narration": "Test Narration",
    "refence": "**************"
    "operator": "mpgs",
    "redirect_success_url": "https://alexpay-mpgs.yourdomain.app/api/confirm",
    "redirect_failed_url": "https://alexpay-mpgs.yourdomain.app/api/failed",
    "webhook_url": "https://api.yourdomain.com/webhooks/checkout",
    "integration_type": "DIRECT_API"
}

```

#### Step 2: Redirect the Customer&#xD;

Upon a successful request, we’ll return a paymentLink for the payment page.Redirect the customer to this URL in your browser or mobile app.

#### Response

```
{
    "status": "success",
    "code": 200,
    "message": "success",
    "data": {
        "payment_link": "",
        "reference": "",
        "payment_id": "",
        "status": "pending"
    }
}
```

**Step 3: After the Payment**

Once the customer completes the payment on the Vesicash checkout page:

1. **Customer Redirect**: The customer is redirected to the redirectUrl you provided in the initialization request.
2. **Receive Webhook Notification**: Vesicash automatically sends webhook notifications to your configured URL whenever a transaction status changes, provided your webhook secret is properly generated and verified..
3. **Query Payment Status**: Your server should call the Payment Status endpoint to confirm the final state of the transaction (e.g., success, failed, or pending) if webhook notifications are delayed.


# Non‑Checkout Flow

The **Non‑Checkout Flow** allows you to recieve card  payments **without redirecting the customer to the Vesicash checkout page**.

In this method, you initiate the payment from your backend and then complete it by making a direct API call using the payment reference.

This flow is ideal when you want **full control of the payment experience** within your website, mobile app, or custom UI.

The flow supports two active operators depending on the currency of the transaction.

1. **GTI** - Exclusively for **USD** payments.
2. **MPGS** - Exclusively for **GHS** payments.

**How the Non‑Checkout Card payment Flow Works**

1. **Initialize the Payment**: Make a server-side POST request to the payment initialization endpoint. Vesicash returns a paymentReference that uniquely identifies the transaction.
2. **Complete the Payment**: Using the paymentReference returned during initiation, your server immediately calls the Complete Payment endpoint. This returns a bank card payment link. Load this link and the customer will complete the transaction.
3. **After the Payment**: Once the payment is completed you can check the status on the status check endpoint and a webhook notification will be sent.

**Step 1: Initialize the Payment**

Send a server‑side POST request to the payment initialization endpoint.

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

#### Headers

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

#### Request body

* currency (string): The currency for the payment.
* country (string): The country for the payment.
* narration (string): Description or reason for the payment.
* reference (string, optional): Transaction reference. If not supplied, the system will internally generate a value. Must be at least 10 characters long.
* method (string): The payment method to be used.
* amount (number): The amount of the payment.
* operator(string): The payment gateway operator to use. Expected values are gti or mpgs.
* redirect\_success\_url(string): The absolute URL where the user will be redirected to upon a successful payment.
* redirect\_failed\_url(string):The absolute URL where the user will be redirected to if the payment fails.
* integration\_type(string): Required when operator is mpgs. The expected value is DIRECT\_API.
* webhook\_url (string): A URL where notifications about the payment status will be sent.

#### Request

1. #### GTI (USD Payments)

The GTI operator is strictly used for payments in USD.

For example, you can make a post request to the endpoint above and pass in the raw json data below to create a one-off transaction.

```
{
    "amount": 1,
    "currency": "USD",
    "country": "US",
    "method": "card",
    "operator": "gti",
    "narration": "Checkout GTI Test",
    "reference": "***********"
    "redirect_success_url": "https://www.yourdomain.com/success",
    "redirect_failed_url": "https://merchant.yourdomain.com/login",
    "webhook_url": "https://api.yourdomain.com/webhooks/checkout"
}

```

2. #### MPGS (GHS Payments)

The `MPGS` operator is used for payments in `GHS`. Notice the inclusion of the integration\_type attribute.

```
{
    "amount": 1,
    "country": "GH",
    "currency": "GHS",
    "method": "card",
    "narration": "Test Narration",
    "reference": "*************"
    "operator": "mpgs",
    "redirect_success_url": "https://alexpay-mpgs.yourdomain.app/api/confirm",
    "redirect_failed_url": "https://alexpay-mpgs.yourdomain.app/api/failed",
    "webhook_url": "https://api.yourdomain.com/webhooks/checkout",
    "integration_type": "DIRECT_API"
}

```

#### Response

```
{
    "status": "success",
    "code": 200,
    "message": "success",
    "data": {
        "payment_link": "",
        "reference": "",
        "payment_id": "",
        "status": "pending"
    }
}
```

**Step 2: Complete the Payment**

Using the paymentReference returned during initiation, your server immediately calls the Complete Payment endpoint. This returns a bank card payment link. Load this link and the customer will complete the transaction

<mark style="color:$success;">**POST**</mark>**: /v1/payment/pay/:payment\_reference**

**Params**

| Name               | Type   | Description                                                        |
| ------------------ | ------ | ------------------------------------------------------------------ |
| payment\_reference | string | The payment reference that was generated when initializing payment |

#### Headers

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

#### Request

#### 1. GTI Payload Requirements <a href="#user-content-1-gti-payload-requirements" id="user-content-1-gti-payload-requirements"></a>

The GTI operator requires basic card details, standard billing information, and redirect URLs to handle the payment outcome.<br>

```
{
    "card_number": "5399839213647612",
    "card_cvv": "208",
    "card_expiry_date": "0929",
    "email": "customer@example.com",
    "phone_number": "+2348011112222",
    "customer_first_name": "John",
    "customer_last_name": "Doe",
    "method": "card",
    "operator": "gti",
    "billing_address_line1": "123 Business Way",
    "billing_city": "Lagos",
    "billing_province": "Lagos",
    "billing_postal_code": "100001",
    "billing_country": "NG",
    "redirect_url": "https://google.com",
    "redirect_success_url": "https://www.google.com/",
    "redirect_failed_url": "https://merchant.vesicash.com/login"
}

```

2. #### MPGS Payload Requirements

The **MPGS** operator requires detailed client metadata and network info (likely for 3D Secure verification) but excludes the billing and redirection information found in the **GTI** payload.

```
{
    "phone_number": "111111111",
    "email": "customer@example.com",
    "customer_first_name": "Jane",
    "customer_last_name": "Doe",
    "card_number": "111111111111111111",
    "card_expiry_date": "0629",
    "card_cvv": "222",
    "java_enabled": false,
    "language": "en-GB",
    "screen_height": 1080,
    "screen_width": 1920,
    "color_depth": 24,
    "time_zone": -60,
    "ip_address": "{{clientIPAddress}}",
    "browser_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36"
}

```

#### Response

```
{
    "status": "success",
    "code": 200,
    "message": "Success. Redirect to 3DS.",
    "data": {
        "message": "Success. Redirect to 3DS.",
        "device_storage_token": null,
        "method": "card",
        "payment_status": "processing",
        "operator": "gti",
        "reference": "",
        "redirect_url": "https://checkout.gtipayglobal.com/checkout//mp"
    }
}
```

Then load the payment link provided in the response, allowing the customer to authorize the card payment.

Once approval is completed, Vesicash processes the transaction.

**Step 3: After the Payment**

Once the customer completes the payment on the bank checkout page:

1. **Query Payment Status**: Your server should call the Payment Status endpoint to confirm the final state of the transaction (e.g., success, failed, pending).
2. **Receive Webhook Notification**: Vesicash automatically sends webhook notifications to your configured URL whenever a transaction status changes, provided your webhook secret is properly generated and verified.

#### Webhook Notification&#xD;

Once the payment is processed, Vesicash sends a POST request to your webhook\_url with the final payment outcome. Use this event — not the initial API response — to update your system's payments state.<br>

{% code overflow="wrap" %}

```
{
"amount":1,
"business_id":"56b2f01d-75e4-46e4-b8ec-c79441844001",
"charge":0,"created_at":"2026-04-30T16:46:23.060208Z",
"currency":"ZMW",
"customer":
{
"id":"690bf0df-d187-42a8-9137-dc7402f2d080",
"email":"greg@gmail.com",
"phone_number":"260968832801",
"firstname":"Ademola",
"environment":"live",
"lastname":"Ayeola",
"details":null,
"business_id":"56b2f01d-75e4-46e4-b8ec-c79441844001",
"blacklisted":false,
"no_payments":34,
"last_payment":"2026-04-30T16:46:23.060208Z",
"created_at":"2025-12-04T10:03:47.870978Z",
"updated_at":"2026-04-30T16:46:35.914213Z"
},
"environment":"live","event":"payment_successful","id":"99c6bf3a-4092-4dad-bf32-22ab3cb394e3","method":"mobilemoney","narration":"payment for the purchase of seven doors","provider_transaction_id":"99c6bf3a-4092-4dad-bf32-22ab3cb394e3","redirect_url":"https://www.google.com","reference":"PY_VM_08c04dac73","status":"successful","type":"payment"}
```

{% endcode %}


# Initiate Payment

The endpoint /v1/payment/init is a POST request that initiates a payment. The request body should be in raw format and include the following parameters:

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

#### Headers

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

#### Request body

* currency (string): The currency for the payment.
* country (string): The country for the payment.
* narration (string): Description or reason for the payment.
* method (string): The payment method to be used.
* amount (number): The amount of the payment.
* webhook\_url (string): A URL where notifications about the payment status will be sent.
* redirect\_url (sting):

#### Request

For example, you can make a post request to the endpoint above and pass in the raw json data below to create a one-off transaction.

```
{
"currency": "ZMW",
    "country": "ZM",
    "narration": "payment for rice",
    "method": "mobilemoney", //"card"
    "amount": 1.3,
    "webhook_url: "",
    "redirect_url": "",
}
```

#### Response

```
{
    "status": "success",
    "code": 200,
    "message": "success",
    "data": {
        "payment_link": "",
        "reference": "",
        "payment_id": "",
        "status": "pending"
    }
}
```


# Pay with mobile money

The endpoint /v1/payment/pay/:payment\_reference is a POST request that initiates a mobile money payment. The request body should be in raw format and include the following parameters:

#### <mark style="color:green;">POST:</mark> /v1/payment/pay/:payment\_reference

#### Params

| Name               | Type   | Description                                                        |
| ------------------ | ------ | ------------------------------------------------------------------ |
| payment\_reference | string | The payment reference that was generated when initializing payment |

#### Headers

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

#### Request body

* currency (string): The currency for the payment.
* country (string): The country for the payment.
* narration (string): Description or reason for the payment.
* method (string): The payment method to be used.
* amount (number): The amount of the payment.
* customer\_first\_name (string): The first name of the customer.
* customer\_last\_name (string): The last name of the customer.
* account\_number (string): The customer's account number.

#### Request

For example, you can make a post request to the endpoint above and pass in the raw json data below to create a one-off transaction.

```
{
    "email":"",
    "customer_first_name":"segun",
    "customer_last_name":"ige",
    "customer_city":"ikorodu",
    "account_number":"",
    "phone_number":"",
}
```

#### Response

```
{
    "status": "success",
    "code": 200,
    "message": "success",
    "data": {
        "payment_link": "",
        "reference": "",
        "payment_id": "",
        "status": "pending"
    }
}
```


# Pay with card

This endpoint allows you to initiate a payment with the provided details.

The endpoint /v1/payment/pay/:payment\_reference is a POST request that initiates a card payment. The request body should be in raw format and include the following parameters:

#### <mark style="color:green;">POST:</mark> v1/payment/pay/:payment\_reference

\
**Params**

| Name               | Type   | Description                                                        |
| ------------------ | ------ | ------------------------------------------------------------------ |
| payment\_reference | string | The payment reference that was generated when initializing payment |

#### Headers

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

#### Request body

* currency (string): The currency for the payment.
* country (string): The country for the payment.
* narration (string): Description or reason for the payment.
* method (string): The payment method, in this case "card".
* token(string): The context token generated from the payment context.
* amount (number): The amount of the payment.
* customer\_first\_name (string): The first name of the customer.
* customer\_last\_name (string): The last name of the customer.
* account\_number (string): The customer's account number.
* card\_number(string): Card number (PAN)
* card\_expiry\_date(sting): Card expiry in MMYY format
* card\_cvv(string): Card CVV code
* java\_enabled(Boolean): Indicates if Java is enabled in browser
* language(string): Browser language
* screen\_height(integer): Screen height in pixels

  *

#### Request

For example, you can make a post request to the endpoint above and pass in the raw json data below to create a one-off transaction.

```
//card
{
    "phone_number": "2335********",
    "email": "customer@example.com",
    "customer_first_name": "Jane",
    "customer_last_name": "Doe",
    "card_number": "5399*********",
    "card_expiry_date": "0629",
    "card_cvv": "***",
    "java_enabled": false,
    "language": "en-GB",
    "screen_height": 1080, //This should be generated Programmatically
    "screen_width": 1920,    //This should be generated Programmatically
    "color_depth": 24,    //This should be generated Programmatically
    "time_zone": -60,    //This should be generated Programmatically
    "ip_address":"", //This will be generated from the Get client IP Address endpoint
    "browser_user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36" //This should be generated Programmatically
}
```

#### Response

```
{
    "status": "success",
    "code": 200,
    "message": "success",
    "data": "payment sent for processing"
}
```


# Complete a card payment

The endpoint is used to complete a card payment.

<mark style="color:green;">POST:</mark> <https://api.gateway.redstonepgs.com/v1/payment/complete-3ds/:payment\\_reference>

#### <kbd>Headers</kbd>

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

#### Response

```
{
    "status": "success",
    "code": 200,
    "message": "success",
    "data": "payment sent for processing"
}
```

The capture\_token will be used to initialize the microform on the Generate card payment token endpoint.


# Continue payment

This endpoint allows the user to continue a payment with the given payment reference.

The endpoint /v1/payment/pay/:payment\_reference/continue is a POST request to continue a card payment. No request body parameters are required for this request.

#### <mark style="color:green;">POST:</mark> v1/payment/pay/:payment\_reference/continue

\
**Params**

| Name               | Type   | Description                                                        |
| ------------------ | ------ | ------------------------------------------------------------------ |
| payment\_reference | string | The payment reference that was generated when initializing payment |

#### Headers

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

#### Response

```
{
    "status": "success",
    "code": 200,
    "message": "success",
    "data": "payment sent for processing"
}
```


# Complete payment

This endpoint allows the user to complete a payment with the given payment reference.

This endpoint allows the user to continue a payment with the given payment reference.

The endpoint /v1/payment/pay/:payment\_reference/complete is a POST request to complete a card payment. No request body parameters are required for this request.

#### <mark style="color:green;">POST:</mark> v1/payment/pay/:payment\_reference/complete

\
**Params**

| Name               | Type   | Description                                                        |
| ------------------ | ------ | ------------------------------------------------------------------ |
| payment\_reference | string | The payment reference that was generated when initializing payment |

#### Headers

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

#### Response

```
{
    "status": "success",
    "code": 200,
    "message": "success",
    "data": "payment sent for processing"
}
```


# Initiate a Refund

Initiate a refund for a previously completed transaction. Refunds are processed asynchronously — the response confirms the refund has been queued, and a webhook notification is sent once the funds are returned to the customer.

### How Refunds Work

Vesicash refunds are sent directly to the customer based on the original payment method:

* **Mobile Money** → refunded to customer wallet
* **Card** → refunded back to the customer’s card

{% 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/refunds/process

#### Headers

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

#### Request body

* amount (number: required): The amount to be refunded. This value must not be greater than the amount associated with the specified payment reference.
* payment\_reference (string: required): The reference of the payment that needs to be refunded. This should match the original payment reference.
* transfer\_to (string:required): The destination type for the refund disbursement. Currently supports `mobile_number` and `card`
* country\_id (string :optional for `mobile money`): The unique identifier for the country in which the transaction is being processed. To retrieve a valid `country_id`, call the [Get Countries endpoint](https://docs.vesicash.com/~/revisions/sUGfrlHe2F4873mAN9dv/get-countries) and use the `country_id` field from the matching country object in the response.
* momo\_phone\_number (string:required for `mobile money`): The mobile money number to receive the refund. E.164 format without the + prefix. E.g. 2340999993.
* webhook\_url (string:optional): A valid HTTPS URL where Vesicash will POST the refund status notification once processing is complete. Must be publicly accessible. Overrides your dashboard default if provided.
* reason (string: optional): The reason for the refund.

#### 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 Refund

{
    "amount":1,
    "country_id":"{{country_id}}",
    "transfer_to":"mobile_number",
    "momo_phone_number": "{{phone_number}}",
    "payment_reference":"{{reference}}",
    "webhook_url": "{{webhook_url}}",
    "reason":"testing refund reason" //optional
}

//Card Refund (NEW)
{
  "amount": 1,
  "payment_reference": "PY_VM_8*******",
  "transfer_to": "card",
  "webhook_url": "https://example.com/webhook",
  "reason": "Customer requested refund"
}
```

#### Response

```
{
    "status": "success",
    "code": 200,
    "message": "refund queued successfully",
    "data": {
        "status": "pending",
        "message": "refund queued successfully",
        "reference": ""
    }
}
```

#### 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.                                                                             |
| message        | string | Human-readable summary of the API response.                                                                            |
| data.status    | string | Current refund status. One of: `processing` `successful` `failed`                                                      |
| data.reference | string | Unique refund reference assigned by Vesicash. Use this to poll the refund status endpoint or correlate webhook events. |

{% 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 refund is processed, Vesicash sends a POST request to your webhook\_url with the final refund outcome. Use this event — not the initial API response — to update your system's refund state.

```
{
    "amount": 0.1,
    "business_id": "56b2f01d-75e4-46e4-b8ec-",
    "charge": 0,
    "created_at": "2026-02-26T14:59:47.228153Z",
    "currency": "GHS",
    "customer": {
        "email": "",
        "firstname": "",
        "lastname": "",
        "phone_number": "233208******"
    },
    "environment": "live",
    "event": "refund_successful",
    "id": "5f8c954e-9428-44b7-8966-",
    "method": "mobilemoney",
    "narration": "testing refund reason",
    "provider_transaction_id": "",
    "redirect_url": "",
    "reference": "",
    "status": "successful",
    "type": "refund"
}
```

{% 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  | Refund amount exceeds the remaining refundable balance          | The refund amount is zero, negative, or exceeds the refundable balance on the original transaction. |
| 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  | Refund Provider service returned an error                       | The `momo_phone_number` is not a valid E.164 formatted mobile money number.                         |


# 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. |


# 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&#x20;
* [ ] 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 **/payment/banks?country=GH** to get the bank\_id.

2. **Initiate the Payout**\
   POST to `/v1/payment/payouts/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.

   <br>

#### <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 be disburse.&#x20;
* countryId (string): The Vesicash identifier for the payout country. Call `GET` /`v1/countries` to retrieve available country IDs.
* transfer\_to(string): The disbursement method. Determines which additional fields are required. e.g `mobile_money` or `bank`.
* webhook\_url(string): A publicly accessible HTTPS URL where Vesicash will POST the payout status notification.
* narration (string: optional): A brief description or note regarding the payout. This helps in identifying the purpose of the transaction.
* momo\_phone\_number (string, optional): The mobile money phone number to which the payout will be sent. If this is not provided, the payment will be credited to the merchant's momo account.

#### Additional Parameters by Transfer Type

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

{% tabs %}
{% tab title="mobile\_money" %}
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. eg 260999993000
{% endtab %}

{% tab title="bank" %}
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 create a one-off transaction.

```
//Mobile Money Payout


{
    
    "amount":123,
    "countryId": "{{zambia_country_id}}",
    "transfer_to":"mobile_money"   // bank
    "momo_phone_number": "260********",
    "webhook_url": "https://webhook.site/99a3cf82-d235-00000000000000000000",
    "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": 26,
        "message": "Payout is being processed by the provider",
        "reference": "PY_6c663231b************",
        "status": "processing"
    }
}
```


# Get transaction status

This endpoint retrieves the details of a specific payment by providing the payment ID in the endpoint URL.

#### <mark style="color:green;">GET:</mark>/v1/payment/:payment\_reference

**Params**

| Name               | Type   | Description                                                        |
| ------------------ | ------ | ------------------------------------------------------------------ |
| payment\_reference | string | The payment reference that was generated when initializing payment |

#### Headers

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

#### Response

The response will be in JSON format and will have the following schema:

````
```json
{
    "status": "success",
    "code": 200,
    "message": "success",
    "data": {
        "id": "",
        "amount": 143,
        "type": "payment",
        "method": "mobilemoney",
        "status": "pending",
        "currency": "ZMW",
        "reference": "",
        "business_id": "",
        "created_at": "2024-11-06T10:14:31.888324Z",
        "environment": "test",
        "redirect_url": "http://www.google.com",
        "email": "user@example.com",
        "customer_first_name": "",
        "customer_last_name": "",
        "phone_number": ""
    }
}
```
````


# Get payments for business

This endpoint makes an HTTP GET request to retrieve a list of payments with pagination. The request includes query parameters for the page number and limit of results per page.

#### <mark style="color:green;">GET:</mark>/v1/payment/

**Params**

| Name      | Type    | Description                                                        |
| --------- | ------- | ------------------------------------------------------------------ |
| page      | integer | The page number for paginated results                              |
| reference | string  | The payment reference that was generated when initializing payment |
| limit     | integer | The limit of payments per page                                     |
| from      | integer | The timestamp of the starting date                                 |
| to        | integer | The timestamp of the ending date                                   |

#### Headers

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

#### Response

The response will have a status code of 200 and a content type of application/json. The body of the response will contain an array of payment data, including details such as payment ID, amount, environment, type, method, status, currency, reference, narration, provider transaction ID, customer details, business ID, creation timestamp, and update timestamp. Additionally, the response will include pagination information with details about the current page, total page count, and total pages count.

```
{
    "status": "success",
    "code": 200,
    "message": "success",
    "data": [
        {
            "id": "20a72fd0-a3a3-4c5d-9fea-e3a7e02b26a5",
            "amount": 1,
            "environment": "test",
            "type": "payment",
            "method": "mobilemoney",
            "status": "pending",
            "currency": "ZMW",
            "reference": "PY_c77f7bff21514bdf9dfe9f1b2",
            "narration": "",
            "provider_transaction_id": "",
            "customer_details": "00000000-0000-0000-0000-000000000000",
            "business_id": "8f212284-3a4d-4c2d-ad27-d0e8703c89cf",
            "created_at": "2024-08-21T12:38:56.704592Z",
            "updated_at": "2024-08-21T12:38:56.704592Z"
        },
        {
            "id": "b05d7e8a-deea-44fd-bc0a-ca6e467c368b",
            "amount": 1,
            "environment": "test",
            "type": "payment",
            "method": "mobilemoney",
            "status": "pending",
            "currency": "ZMW",
            "reference": "PY_6bfb1ddf065d40ebb26e57d7b",
            "narration": "",
            "provider_transaction_id": "",
            "customer_details": "00000000-0000-0000-0000-000000000000",
            "business_id": "8f212284-3a4d-4c2d-ad27-d0e8703c89cf",
            "created_at": "2024-08-21T10:54:11.119607Z",
            "updated_at": "2024-08-21T10:54:11.119607Z"
        }
         ],
    "pagination": [
        {
            "current_page": 1,
            "page_count": 3,
            "total_pages_count": 2
        }
    ]
}
```


# Wallet balance


# Get wallet histories

This endpoint makes an HTTP GET request to retrieve a list of successfull transactions with pagination. The request includes query parameters for the  number page and limit of results per page.

#### <mark style="color:green;">GET:</mark>v1/account/get-wallet-histories

**Params**

| Name      | Type    | Description                           |
| --------- | ------- | ------------------------------------- |
| page      | integer | The page number for paginated results |
| timestamp | integer | The timestamp of the ending time      |

#### Headers

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

#### Response

The response will be in JSON format and will have the following schema:

```
{
    "status": "success",
    "code": 200,
    "message": "success",
    "data": [
        {
            "id": "50f86bf7-6",
            "balance_before": 119.63,
            "balance_after": 119.73,
            "amount": 0.1,
            "action": "refund",
            "type": "credit",
            "wallet_id": "7a6b5247-0080-",
            "reference": "PY_cf390d12",
            "currency_code": "GHS",
            "country_code": "GH",
            "balance_at": "2026-01-12T16:51:55.285126Z"
        },
            "currency_code": "GHS",
            "country_code": "GH",
            "balance_at": "2026-01-12T16:43:45.082621Z"
        },
        {
            "id": "1329ef10-a328-4dfb-9083-de37a1cd6cc2",
            "balance_before": 118.73,
            "balance_after": 119.73,
            "amount": 1,
            "action": "card-payment",
            "type": "credit",
            "wallet_id": "7a6b5247-0080-49eb-b440-45c48b2cfb7e",
            "reference": "PY_63055d1600e542768792e0983",
            "currency_code": "GHS",
            "country_code": "GH",
            "balance_at": "2026-01-12T12:45:02.829338Z"
        },
        {
            "id": "2334203a-44ea-47fe-8b00-22d4c073f759",
            "balance_before": 120.73,
            "balance_after": 118.73,
            "amount": 2,
            "action": "payout",
            "type": "debit",
            "wallet_id": "7a6b5247-0080-49eb-b440-45c48b2cfb7e",
            "reference": "PY_1fc9629f1162491b80d482e75",
            "currency_code": "GHS",
            "country_code": "GH",
            "balance_at": "2026-01-12T11:17:49.000636Z"
        },
        {
            "id": "304633a3-4948-442c-b39c-73112cd7326e",
            "balance_before": 119.73,
            "balance_after": 120.73,
            "amount": 1,
            "action": "card-payment",
            "type": "credit",
          
        {
            "id": "2835574f-2ba1-4e92-ba8b-",
            "balance_before": 119.73,
            "balance_after": 120.73,
            "amount": 1,
            "action": "refund",
            "type": "credit",
            "wallet_id": "7a6b5247-0080-49eb-b440-",
            "reference": "",
            "currency_code": "GHS",
            "country_code": "GH",
            "balance_at": "2026-01-05T11:31:42.750002Z"
        },
        {
            "id": "6ed9e757-9caf-497c-a095-",
            "balance_before": 120.73,
            "balance_after": 119.73,
            "amount": 1,
            "action": "payout",
            "type": "debit",
            "wallet_id": "7a6b5247-0080-49eb-b440-",
            "reference": "",
            "currency_code": "GHS",
            "country_code": "GH",
            "balance_at": "2026-01-05T11:31:27.956157Z"
        },
        {
            "id": "3d989d44-e8ac-4bf3-a8f9-",
            "balance_before": 121.73,
            "balance_after": 120.73,
            "amount": 1,
            "action": "payout",
            "type": "debit",
            "wallet_id": "7a6b5247-0080-49eb-b440-",
            "reference": "",
            "currency_code": "GHS",
            "country_code": "GH",
            "balance_at": "2026-01-05T11:30:08.855668Z"
        },
        {
            "id": "e4af8ece-9ff1-4419-9363-",
            "balance_before": 122.73,
            "balance_after": 121.73,
            "amount": 1,
            "action": "payout",
            "type": "debit",
            "wallet_id": "7a6b5247-0080-49eb-b440-",
            "reference": "",
            "currency_code": "GHS",
            "country_code": "GH",
            "balance_at": "2026-01-05T11:11:58.958077Z"
        },
        {
            "id": "777bf346-25f0-4015-9e16-",
            "balance_before": 121.73,
            "balance_after": 122.73,
            "amount": 1,
            "action": "mobile-money-payment",
            "type": "credit",
            "wallet_id": "7a6b5247-0080-49eb-b440-",
            "reference": "",
            "currency_code": "GHS",
            "country_code": "GH",
            "balance_at": "2026-01-05T11:09:12.589033Z"
        },
        {
            "id": "c0fb30d9-6c22-482a-b345-",
            "balance_before": 122.73,
            "balance_after": 121.73,
            "amount": 1,
            "action": "payout",
            "type": "debit",
            "wallet_id": "7a6b5247-0080-49eb-b440-",
            "reference": "",
            "currency_code": "GHS",
            "country_code": "GH",
            "balance_at": "2026-01-05T11:02:43.570271Z"
        },
        {
            "id": "78e7a810-b53a-40a8-84d4-",
            "balance_before": 123.73,
            "balance_after": 122.73,
            "amount": 1,
            "action": "payout",
            "type": "debit",
            "wallet_id": "7a6b5247-0080-49eb-b440-",
            "reference": "",
            "currency_code": "GHS",
            "country_code": "GH",
            "balance_at": "2026-01-05T10:36:02.749439Z"
        },
        {
            "id": "3a0b5e7f-ee3f-4adc-903d-",
            "balance_before": 122.73,
            "balance_after": 123.73,
            "amount": 1,
            "action": "card-payment",
            "type": "credit",
            "wallet_id": "7a6b5247-0080-49eb-b440-",
            "reference": "",
            "currency_code": "GHS",
            "country_code": "GH",
            "balance_at": "2026-01-05T10:31:49.922202Z"
        },
        {
            "id": "181ad166-d79b-4d4e-a617-",
            "balance_before": 124.73,
            "balance_after": 122.73,
            "amount": 2,
            "action": "payout",
            "type": "debit",
            "wallet_id": "7a6b5247-0080-49eb-b440-",
            "reference": "",
            "currency_code": "GHS",
            "country_code": "GH",
            "balance_at": "2026-01-05T10:29:32.571139Z"
        },
        {
            "id": "8e48fcf9-87c0-4ab5-bc6e-",
            "balance_before": 123.73,
            "balance_after": 124.73,
            "amount": 1,
            "action": "card-payment",
            "type": "credit",
            "wallet_id": "7a6b5247-0080-49eb-b440-",
            "reference": "PY_fce698bd970",
            "currency_code": "GHS",
            "country_code": "GH",
            "balance_at": "2026-01-05T09:21:53.340784Z"
        }
    ],
    "pagination": [
        {
            "current_page": 1,
            "page_count": 20,
            "total_pages_count": 7
        }
    ]
}
```


# Get wallet balance

This endpoint makes an HTTP GET request to retrieve the available wallet balance.

#### <mark style="color:green;">GET:</mark>v1/account/wallets

#### Headers

| Name          | Type   | Description              |
| ------------- | ------ | ------------------------ |
| secret-key    | string | Your vesicash secret key |
| public-key    | string | Your Vesicash public key |
| Authorization |        | Bearer token             |

#### Response

The response will be in JSON format and will have the following schema:

```
    "status": "success",
    "code": 200,
    "message": "success",
    "data": [
        {
            "id": "ade3534b***************",
            "balance": 11,
            "environment": "live",
            "business_id": "7****************",
            "country": {
                "id": "f6bf7*****************",
                "name": "Ghana",
                "country_code": "GH",
                "currency_code": "GHS"
            },
            "created_at": "2025-07-28T15:01:13.590536Z",
            "updated_at": "2025-12-17T13:27:14.386401Z"
        },
        {
            "id": "d37415d0-df6**************",
            "balance": 347.99,
            "environment": "live",
            "business_id": "79ef173*****************",
            "country": {
                "id": "e7467e17-0ce*****************",
                "name": "Zambia",
                "country_code": "ZM",
                "currency_code": "ZMW"
            },
            "created_at": "2024-10-29T11:30:41.912092Z",
            "updated_at": "2026-01-06T14:27:04.801411Z"
        }
    ]
}
```


# Generate webhook secret

Generate a new webhook secret for your Vesicash account. This secret is used to sign outgoing webhook payloads, allowing you to verify that incoming notifications genuinely originate from Vesicash.

**How It Works**

Each time this endpoint is called, Vesicash generates a new cryptographic secret tied to your account. You use this secret on your server to validate the `mor-signature` header on every incoming webhook request.

1. **Call this endpoint**

   `POST to /v1/account/generate-webhook-secret` with your secret-key. No request body is needed.
2. **Store the secret securely**

   Save the returned `webhook_secret` in your environment variables or secret manager. Never expose it in client-side code or logs.
3. **Verify incoming webhooks**\
   On every Vesicash webhook, compute an HMAC-SHA256 signature of the raw request body using your secret, then compare it against the `mor-signature` header.

{% hint style="info" %}
**🔴 Regenerating Invalidates the Previous Secret**

Calling this endpoint generates a brand new secret and immediately invalidates the old one. Any webhook verification using the previous secret will fail. Update your environment variables before regenerating in production.
{% endhint %}

<mark style="color:green;">POST</mark> : v1/account/generate-webhook-secret

#### Headers

| Name       | Type   | Decsription              |
| ---------- | ------ | ------------------------ |
| secret-key | string | Your Vesicash secret key |

#### Response

On a successful request, the API will return a response with the following structure:

* `webhook_secret` (string): The generated webhook secret that will be used for authentication.

```
{
  "status": "",
  "code": 0,
  "message": "",
  "data": {
    "webhook_secret": ""
  }
}

            
```

**NOTE:** **Webhook Authentication Using HMAC-SHA256** After authentication using the specified method, the generated webhook token must be stored in a secure location (for example, a secrets manager or encrypted configuration store). The webhook signature is created by computing an HMAC-SHA256 hash on a single string that must be reconstructed exactly on your server.

```
HMAC-SHA256(   your_webhook_secret,   timestamp + "." + raw_request_body )  
```


# Get Countries

This endpoint retrieves a list of countries along with their associated details. Use these IDs when initializing payments, processing refunds, or filtering transactions by country.

<mark style="color:green;">GET</mark> : v1/countries

This is a lightweight, read-only endpoint with no request body or query parameters. Authentication requires only your public key — it is safe to call from a client-side environment.

{% hint style="info" %}
**No Request Body**

This endpoint accepts no query parameters or request body. Simply send the GET request with your public-key header.
{% endhint %}

**Response**

Returns an array of country objects. Each object contains the `id` you pass to other Vesicash endpoints, alongside the country name, ISO code, currency.

* Data :An array containing country objects, where each object includes:
* id: The unique identifier for the country.
* name: The name of the country.
* country\_code: The ISO code representing the country.
* currency\_code: The currency code associated with the country.

```
{
  "status": "",
  "code": 0,
  "message": "",
  "data": [
    {
      "id": "",
      "name": "",
      "country_code": "",
      "currency_code": ""
    }
  ]
}
```

### Using country\_id in Other Requests

Once you have fetched the country list, use the `country_id` field wherever Vesicash requires a country identifier — for example, when processing a refund.


# Get Client IP Address

Retrieves the IP address of the client making the request.

<mark style="color:green;">GET</mark> :v1/decision/ip

**Response**

```
{
    "data": {
        "ip_address": "XXXXXXXXXXX"
    },
    "message": "IP address retrieved successfully",
    "status": true
}
```


# Get bank Id

This endpoint retrieves a list of banks available in a specified country.

<mark style="color:green;">GET</mark> : v1/payment/banks?country=GH

#### Param

**Response**

<br>

On a successful request, the API will return a response with the following structure:

* Data :An array containing country objects, where each object includes:
* id: The unique identifier for the country.
* name: The name of the country.
* country\_code: The ISO code representing the country.
* currency\_code: The currency code associated with the country.

```
{
  "status": "",
  "code": 0,
  "message": "",
  "data": [
    {
      "id": "",
      "name": "",
      "country_code": "",
      "currency_code": ""
    }
  ]
}
```


