Virtual Account API
The Virtual Account API allows merchants to create a virtual account numbers for their customers to enable them carry out transactions.
Requirements
To use this endpoint, ensure that:
-
Your API key is active and IP whitelisting is correctly configured.
-
The user has a valid BVN (Bank Verification Number).
-
You provide a unique reference value per request.
Endpoint
POST {{baseURL}}/v1/virtual-account
Headers
Header | Type | Description | Required |
---|---|---|---|
Content-Type | String | Must be application/json | ✅ Yes |
x-api-key | String | API key for authentication | ✅ Yes |
Sample cURL
Request
curl --location '{{baseURL}}/v1/virtual-account' \
--header 'Content-Type: application/json' \
--header 'x-api-key: YOUR_API_KEY_HERE \
--data-raw '{
"currency": "NGN",
"country": "NG",
"firstName": "Jumoke",
"lastName": "Dumebi",
"email": "example@email.com",
"phoneNumber": "+23481345XXXX",
"bvn": "{{bvn}}",
"reference": "0000659750629287231102XXXXXX",
"accountName": "Jumoke Dumebi"
}'
Request Body
Field | Type | Description | Required |
---|---|---|---|
currency | String | Currency code (e.g., NGN ) | ✅ Yes |
country | String | Country code (e.g., NG ) | ✅ Yes |
firstName | String | Customer's first name | ✅ Yes |
lastName | String | Customer's last name | ✅ Yes |
email | String | Customer's email address | ✅ Yes |
phoneNumber | String | Customer's phone number | ✅ Yes |
bvn | String | Bank Verification Number | ✅ Yes |
reference | String | Unique 30 number reference for the request | ✅ Yes |
accountName | String | Account name for the virtual account | ✅ Yes |
Responses
If the request is successful, the API returns the following JSON response:
{
"message": "virtual account created successfully",
"status": "success",
"data": {
"id": "e21f7365-4fc9-4669-a9d9-xxxxxxxxxxxxx",
"firstName": "Jumoke",
"lastName": "Dumebi",
"email": "example@email.com",
"phoneNumber": "+234813456XXXXX",
"bvn": "********",
"reference": "000065975062928723110XXXXXXXXXX",
"account": {
"name": "Jumoke Dumebi",
"bankName": "Mock BANK",
"sortCode": null,
"number": "881725XXXXX"
},
"status": "ACTIVE",
"currency": "NGN",
"country": "NG",
"created": "2025-05-15T13:39:57.405491181"
}
}
Response Breakdown
General Information
This section describes the high-level response fields present in every API response, regardless of the operation outcome.
Field | Type | Description |
---|---|---|
message | String | Human-readable message describing the result of the API call. |
status | String | The outcome of the API call. Typically "success" or "error" . |
Virtual Account Data
Field | Type | Description |
---|---|---|
id | String | Unique identifier for the virtual account resource. |
firstName | String | First name of the virtual account. |
lastName | String | Last name of the virtual account holder. |
email | String | Email address associated with the account holder. |
phoneNumber | String | Phone number of the account holder |
bvn | String | Bank Verification Number, masked for security purposes. |
reference | String | A unique reference string passed during account creation for traceability. |
account.name | String | Name on the generated virtual account. |
account.bankName | String | Name of the financial institution providing the virtual account. |
account.sortCode | String | Sort code of the bank |
account.number | String | The virtual account number assigned to the user. |
status | String | Current status of the virtual account (e.g., ACTIVE , INACTIVE ). |
currency | String | Currency code for transactions. |
country | String | ISO 3166-1 alpha-2 country code (e.g., NG for Nigeria). |
created | String | ISO 8601 formatted timestamp indicating when the virtual account was created. |
Virtual Account Collection Webhook
Virtual account creation does not trigger a webhook. However, incoming payments to the account do.
When a payment is successfully made into a virtual account, it will trigger the virtualaccount.completed
webhook event.
If a payment to the virtual account fails, it will trigger the virtualaccount.failed
webhook event.
- Example:
virtualaccount.completed
Payload
{
"event": "virtualaccount.completed",
"data": {
"id": "7bcae5c0-8038-430a-86c4-xxxxxxxxxxxxx",
"referenceNumber": "TCECWJXXXXX",
"amount": 200,
"type": "FUNDING",
"state": "COMPLETED",
"destination": "NGN wallet",
"source": {
"bankName": "Opay",
"accountName": "JUSTIN DOE",
"accountNumber": "81725818XX"
},
"customer": {
"email": "example@email.com",
"reference": "000051875359311XXXXXXXXXX",
"account": {
"name": "Chris Doe",
"bankName": "Super BANK",
"number": "88178XXXXXX",
"sortCode": null
}
},
"country": "NG",
"currency": "NGN",
"fee": {
"vat": 2,
"stampDuty": 0,
"base": 2
},
"settlement": {
"amount": 196
},
"created": "2025-05-19T18:53:00.740455409",
"processed": "2025-05-19T18:53:00.740455409"
}
}
Refer to the Example: virtualaccount.completed section in the main Webhooks documentation for a detailed breakdown of this payload.
✅ Notes
- bvn is always masked in the response for compliance and security.
- The value of reference should be unique per request to ensure idempotency.
- The returned account.number can be used to receive payments through the listed bankName.
- Always validate the status field before assuming the account is active or ready to use.