Virtual Accounts
Our Virtual Accounts solution allows you to generate a temporary or static bank account number for your customers to transfer funds into. This is ideal for bank transfers in regions like Nigeria (NGN) where customers prefer paying directly from their banking apps.
Note: Currency and network availability depends on your business account permissions. Currently, Virtual Accounts are primarily supported for NGN. Contact support to enable additional currencies.
How it works
The Virtual Account payment flow is asynchronous. Here is the typical journey:
- Initiation: Send a
POSTrequest to generate a Virtual Account for a specific transaction amount. - Display: Present the generated
virtual_accountdetails (Bank Name, Account Name, Account Number) to your customer. - Payment: The customer makes a bank transfer to the displayed account number.
- Verification: Once the funds are received, OGateway processes the payment and sends a Webhook to your
callbackURLconfirming the success.
Base URL
https://api.ogateway.io
Authentication
All requests must include your API key in the Authorization header:
Authorization: your_api_key
Generate Virtual Account
Generate a virtual bank account number for a customer transfer.
Endpoint: POST /collections/virtual-account
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| amount | number | Yes | The amount to charge (e.g., 50000). |
| currency | string | Yes | The currency code (e.g., NGN). See Currency codes |
| network | string | Yes | The corresponding bank code for the virtual account generation (e.g., 058). |
| accountName | string | Yes | Name of the customer making the payment. |
| accountNumber | string | Yes | The customer's mobile number or identifier. |
| reason | string | Yes | A description of the transaction. |
| reference | string | Yes | A unique string to identify this transaction in your system. Must be unique - duplicate references will be rejected. |
| callbackURL | string | No | The URL for the final transaction status webhook. This overrides the default callback URL saved under your business. |
| metadata | object | No | Additional data to store with the transaction. |
| string | No | Customer's email address. |
Example Request
curl --request POST \
--url https://api.ogateway.io/collections/virtual-account \
--header 'Authorization: your_api_key' \
--header 'Content-Type: application/json' \
--data '{
"amount": 50000,
"currency": "NGN",
"network": "058",
"accountName": "John Doe",
"accountNumber": "0123456789",
"reason": "Payment for order #1234",
"reference": "ref_va_ngn_001",
"callbackURL": "https://your-website.com/webhook"
}'Example Response (200 OK)
The immediate response shows the transaction has been INITIATED and returns the virtual_account details for the customer to pay into.
{
"id": "5ba941b5-eb5c-4618-b8ec-4d1419fb2d38",
"amount": "50000",
"currency": "NGN",
"status": "INITIATED",
"channel": "BANK",
"type": "DEBIT",
"customer": {
"accountName": "John Doe",
"accountNumber": "0123456789"
},
"metadata": {},
"reason": "Payment for order #1234",
"fee": "100.00",
"callback_url": "https://your-website.com/webhook",
"created_at": "2023-07-06T10:30:00.000Z",
"updated_at": "2023-07-06T10:30:45.000Z",
"reference": "ref_va_ngn_001",
"network": "058",
"api_key": "live",
"opening_balance": 150000.5,
"closing_balance": 150000.5,
"virtual_account": {
"bank_name": "Wema Bank",
"account_name": "WeWire / John Doe",
"account_number": "7300012345"
}
}See Error Codes for Error Responses.
Handling the Callback
See full details in our Callbacks section
Since Virtual Account transactions depend on the customer transferring funds, you must listen for a Webhook event at the callbackURL you provided to confirm receipt of the payment and the final COMPLETED status.
Success Payload Example
{
"id": "5ba941b5-eb5c-4618-b8ec-4d1419fb2d38",
"amount": "50000",
"fee": "100.00",
"currency": "NGN",
"status": "COMPLETED",
"channel": "BANK",
"type": "DEBIT",
"reason": "Payment for order #1234",
"network": "058",
"bear_fee": "business",
"customer": {
"accountName": "John Doe",
"accountNumber": "0123456789"
},
"metadata": {},
"created_at": "2023-07-06T10:30:00.000Z",
"updated_at": "2023-07-06T10:35:46.308Z",
"checkout_url": null,
"error_message": null,
"telco_response": "APPROVED",
"virtual_account": {
"bank_name": "Wema Bank",
"account_name": "WeWire / John Doe",
"account_number": "7300012345"
},
"provider_message": "Success",
"reference_business": "ref_va_ngn_001"
}Failed Payload Example
{
"id": "5ba941b5-eb5c-4618-b8ec-4d1419fb2d38",
"amount": "50000",
"fee": "0",
"currency": "NGN",
"status": "FAILED",
"channel": "BANK",
"type": "DEBIT",
"reason": "Payment for order #1234",
"network": "058",
"bear_fee": "business",
"customer": {
"accountName": "John Doe",
"accountNumber": "0123456789"
},
"metadata": {},
"created_at": "2023-07-06T10:30:00.000Z",
"updated_at": "2023-07-06T10:40:41.308Z",
"checkout_url": null,
"error_message": "Customer failed to make transfer within the allotted time",
"telco_response": "Timeout",
"virtual_account": {
"bank_name": "Wema Bank",
"account_name": "WeWire / John Doe",
"account_number": "7300012345"
},
"provider_message": "Expired",
"reference_business": "ref_va_ngn_001"
}Best Practices
-
Unique References: Always use a unique
referencefor each transaction to avoid duplication errors and map transfers accurately to orders in your system. -
Accurate Display: Clearly display the
bank_name,account_number, and exactly the amount to transfer to the customer. Inform them that the account is temporary and tied strictly to this transaction. -
Webhook Security: Verify webhook signatures to ensure callbacks originate from OGateway. See our Callback / Webhook Security guide for implementation details.
-
Idempotency: Retain the virtual account mapping against the order reference. Some virtual accounts expire if no transfer is initiated; handle timeouts gracefully by regenerating a new account if needed.
-
Test Mode: Use test API keys (starting with
test_) during development. This will generate mock virtual accounts and simulated responses without creating real bank-end accounts.
Common Error Scenarios
- Currency Not Enabled: Your business account does not possess permission for creating virtual accounts in the requested currency (e.g. attempting to generate a USD VA when only NGN is enabled).
- Duplicate Reference: Overwriting or using an old transaction reference for a new payload.
- Provider Downtime: An underlying bank provider might be experiencing downtime leading to generation failure (check
provider_hook_responseon failure). - Missing Details: A required field in the payload like
accountNameoramountwas not provided or correctly formatted.
Updated 13 days ago