# Virtual Account Creation

## Summary

Create Virtual Accounts on demands, receive funds from customers via Virtual Account Number and get notification on Virtual Accounts usage.

Dedicated Virtual Accounts (DVAs) is a service that lets you create Nigerian, Ghana virtual accounts for your customers. These accounts allow your customers to receive payment from their customers.

When you create a Dedicated Virtual Account (DVA) for a customer, all bank transfers to that account will automatically be recorded as transactions from that customer.

### Coverage

| Country | currency |
| ------- | -------- |
| Nigeria | NGN      |
| Ghana   | GHS      |

#### Integration steps

You can generate a VA and start receiving money in 3 easy steps:

1. Prepare payload (payload includes: first name, last name, currency and email)
2. Initiate VA creation (encrypting payload)
3. Get instant response

***

{% hint style="info" %}

### Before you begin!

* [Link](https://api.postman.com/collections/8963555-100bce95-af05-4af3-8ff6-797f50c99492?access_key=PMAT-01H5J5C8851FV7P97X9BYC19ZE) to the Postman collection
* Find your keys on the Klasha Dashboard → Settings → Generate API Keys ([here](https://dashboard.klasha.com/settings/keys))
* Klasha Dashboard, Generate API Keys page

<img src="/files/LFFicElNA6dWGpxBEdo1" alt="" data-size="original">

{% endhint %}

{% content-ref url="/pages/p15ikIRu4qZuG2xRX2op" %}
[Token Generation](/~/revisions/wTs3QfcE0Q2ImN5VimGe/overview/token-generation.md)
{% endcontent-ref %}

#### [Encryption Algorithm here](/~/revisions/wTs3QfcE0Q2ImN5VimGe/accepting-payments/payments-api.md#encryption-algorithm)

### Initiate VA creation

## create a virtual account

<mark style="color:green;">`POST`</mark>  {{env\_url}}/wallet/virtual/v3/business/create/account

Encrypt the plain request body using the encryption algorithm specified above. Set the encrypted data to the message as shown below. You are required to set the x-auth-token and Authorization in the headers.

#### Headers

| Key           | Value                    |
| ------------- | ------------------------ |
| x-auth-token  | Your merchant public key |
| Authorization | Bearer \<token here>     |

**Request Body (encrypted)**

```json
{
   "message": "encrypted-message"
}
```

The result of the encryption of the payload that we specified has to be used with the Create virtual account endpoint as shown below:

#### Request Body (plain)

{% tabs %}
{% tab title="NGN" %}

```json
(Individual)
{
   "firstName": "John",
   "lastName": "Doe",
   "currency": "NGN",
   "email": "test@klasha.com"
}

(Business)
{
   "currency": "NGN"
   "email": "test@klasha.com"
}
```

{% endtab %}

{% tab title="GHS" %}

```json
(Individual)
{
   "firstName": "John",
   "lastName": "Doe",
   "currency": "GHS",
   "email": "test@klasha.com"
}

(Business)
{
   "currency": "GHS",
   "email": "test@klasha.com"
}
```

{% endtab %}
{% endtabs %}

| Name                                        | Type   | Description                                             |
| ------------------------------------------- | ------ | ------------------------------------------------------- |
| firstName<mark style="color:red;">\*</mark> | String | John                                                    |
| lastName<mark style="color:red;">\*</mark>  | String | Doe                                                     |
| currency<mark style="color:red;">\*</mark>  | String | Must be one of the supported currencies in the Coverage |
| email<mark style="color:red;">\*</mark>     | String | <test@klasha.com>                                       |

When you create a Virtual Account (VA), please allow a few seconds for processing. The accountName will be the first and last name for a personal account, or the business name for a corporate account. Below are some sample responses you can expect.

{% tabs %}
{% tab title="200: OK (NGN) " %}

```json
{
    "id": 645,
    "walletId": null,
    "accountNumber": "8571529225",
    "bankName": "WEMA BANK",
    "orderRef": "7uIyXachQYC9hcTpgWOZ",
    "txRef": "klasha-virtual-account-banktransfer-Business owner-133",
    "flwRef": "URF_vK8el9541NEy0j66imFD",
    "currency": "NGN",
    "userId": null,
    "businessId": 133,
    "bankCode": null,
    "enabled": true,
    "accountName": "Business owner",
    "email": "test@klasha.com",
    "profileHash": null,
    "blockReason": null,
    "createdAt": "2025-09-29 13:32:59",
    "updatedAt": "2025-09-29 13:32:59"
}
```

{% endtab %}

{% tab title="200: OK (GHS)" %}

```json

 {  
    "id": 4,
    "walletId": null,
    "accountNumber": "7003000100286",
    "bankName": "Affinity",
    "orderRef": "URF_1758189467615_5253135",
    "txRef": "klasha-virtual-account-banktransfer-Neo ai-1758189463344",
    "flwRef": "MockFLWRef-1758189467924",
    "currency": "GHS",
    "userId": null,
    "businessId": 133,
    "bankCode": null,
    "enabled": true,
    "accountName": "John Doe",
    "email": "neo2@matrix.com",
    "profileHash": null,
    "blockReason": null,
    "createdAt": "2025-09-18 10:57:49",
    "updatedAt": "2025-09-18 10:57:49"
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```json
{
    "message": "There is no identity available for this bvn.",
    "error": "Operation not allowed"
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```json
{
    "message": "Bvn name mismatch.",
    "error": "Operation not allowed"
}
```

{% endtab %}
{% endtabs %}

## Requery

<mark style="color:blue;">`GET`</mark> <mark style="color:red;">`{{env_url}}`</mark>`/wallet/virtual/v2/account/`<mark style="color:red;">`{{email}}`</mark>

In case of network downtime or failures during VA creation, the virtual account can be re-queried with the user’s email. This can be fetched using the Requery with email API on the Postman collection.

#### Headers

| Key           | Value                |
| ------------- | -------------------- |
| Authorization | Bearer \<token here> |

{% tabs %}
{% tab title="200: OK " %}

```json
[
    {
        "accountNumber": "8573777620",
        "bankName": "WEMA BANK",
        "orderRef": "HsKRPDlemp7XBKvgO1HE",
        "txRef": "klasha-fund-wallet-banktransfer-steph-AJDcN6app",
        "flwRef": "URF_1Qw8TF2ZN1KkIdsqyHYI",
        "businessId": 5,
        "enabled": true,
        "accountName": "Forrest Green",
        "email": "test@klasha.com",
        "createdAt": "2023-07-04 17:02:59",
        "updatedAt": "2023-07-04 17:02:59"
    }
]
```

{% endtab %}
{% endtabs %}

<details>

<summary>Transaction Webhook</summary>

When payments are received from your users, we would send a webhook with the details of the transaction to your callback URL.

```json
{
  "data": {
    "createdAt": "2023-07-14T19:28:18.585",
    "narration": "Bank Transfer",
    "destinationCurrency": "NGN",
    "sourceAmount": 2000,
    "sourceCurrency": "NGN",
    "virtualAccount":"0987654321",
    "tnxRef": "reference_322123243",
    "status": "successful",
    "destinationAmount": 2000,
    "originatorAccountName":"Stephen Oj",
    "bankName": "Access Bank",
    "originatorAccountNumber":"1234456211",
    "customer": {
      "id": 53603,
      "name": "Last Name",
      "email": "test@steph.com",
      "phone": null,
      "createdAt": "2023-07-04 20:11:05",
      "updatedAt": "2023-07-04 20:11:05"
    }
  },
  "event": "charge.completed"
}
```

</details>

## Polling transaction status

<mark style="color:green;">`POST`</mark> `{{env_url}}/nucleus/tnx/collection/status`

To know the status of a transaction, you can fetch the transaction using the Transaction Status API on the Postman collection. Make use of the session id received from the bank. See an example below:

#### Request Body

| Name                                      | Type   | Description             |
| ----------------------------------------- | ------ | ----------------------- |
| gateRef<mark style="color:red;">\*</mark> | String | 10043599483902847574821 |

{% tabs %}
{% tab title="200: OK " %}

```json
{
    "destinationCurrency": "NGN",
    "sourceAmount": 2500.000000,
    "sourceCurrency": "NGN",
    "status": "successful",
    "destinationAmount": 2500.000000,
    "customer": {
        "id": 53603,
        "name": "Last Name",
        "email": "test@steph.com",
        "phone": null,
        "createdAt": "2023-07-04 20:11:05",
        "updatedAt": "2023-07-04 20:11:05"
    }
}
```

{% endtab %}
{% endtabs %}


---

# 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://developers.klasha.com/~/revisions/wTs3QfcE0Q2ImN5VimGe/bank-account-collection/virtual-account-creation.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.
