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:

  1. Initiation: Send a POST request to generate a Virtual Account for a specific transaction amount.
  2. Display: Present the generated virtual_account details (Bank Name, Account Name, Account Number) to your customer.
  3. Payment: The customer makes a bank transfer to the displayed account number.
  4. Verification: Once the funds are received, OGateway processes the payment and sends a Webhook to your callbackURL confirming 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

ParameterTypeRequiredDescription
amountnumberYesThe amount to charge (e.g., 50000).
currencystringYesThe currency code (e.g., NGN). See Currency codes
networkstringYesThe corresponding bank code for the virtual account generation (e.g., 058).
accountNamestringYesName of the customer making the payment.
accountNumberstringYesThe customer's mobile number or identifier.
reasonstringYesA description of the transaction.
referencestringYesA unique string to identify this transaction in your system. Must be unique - duplicate references will be rejected.
callbackURLstringNoThe URL for the final transaction status webhook. This overrides the default callback URL saved under your business.
metadataobjectNoAdditional data to store with the transaction.
emailstringNoCustomer'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

  1. Unique References: Always use a unique reference for each transaction to avoid duplication errors and map transfers accurately to orders in your system.

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

  3. Webhook Security: Verify webhook signatures to ensure callbacks originate from OGateway. See our Callback / Webhook Security guide for implementation details.

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

  5. 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_response on failure).
  • Missing Details: A required field in the payload like accountName or amount was not provided or correctly formatted.