API ReferenceVirtual Accounts

Virtual Accounts

Virtual Accounts give each customer a dedicated bank account number. When the customer makes a bank transfer to that number, the payment is automatically matched to them — no manual reconciliation required.

Provider support

Virtual Accounts are supported by Paystack (Wema Bank and Titan Bank), Monnify, and Squad. Paystack is the primary implementation. You must have at least one of these providers configured under Provider Keys before creating virtual accounts.

Endpoints

POST/v1/virtual-accounts
GET/v1/virtual-accounts
GET/v1/virtual-accounts/:id

Create a Virtual Account

Creates a dedicated bank account number for a customer. Accounts are scoped per email and provider combination.

POST
/v1/virtual-accounts

Creates a virtual account for a customer. Returns the existing account if one already exists for this email and provider.

Request body

ParameterTypeRequiredDescription
customer_emailstringRequiredCustomer's email address. A dedicated account is created per email+provider combination — calling this endpoint again with the same email returns the existing account.
customer_namestringRequiredCustomer's full name.
customer_phonestringOptionalCustomer's phone number.
preferred_bankstringOptionalBank to create the virtual account with. Options: wema-bank, titan-paystack. Defaults to wema-bank.
provider_idstringOptionalForce a specific provider. Omit to auto-select.
metadataobjectOptionalUp to 20 key-value string pairs.
Example requestbash
curl -X POST https://api.popfab.io/v1/virtual-accounts \
  -H "Authorization: Bearer sk_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_email": "ada@example.com",
    "customer_name": "Ada Okafor",
    "customer_phone": "+2348012345678",
    "preferred_bank": "wema-bank"
  }'
200 OK — Virtual account objectjson
{
  "id": "ppfb_va_a1b2c3d4e5f6",
  "customer_email": "ada@example.com",
  "customer_name": "Ada Okafor",
  "account_number": "9876543210",
  "account_name": "POPFAB/Ada Okafor",
  "bank_name": "Wema Bank",
  "currency": "NGN",
  "provider": "paystack",
  "active": true,
  "metadata": {},
  "created_at": "2025-03-19T12:00:00.000Z",
  "updated_at": "2025-03-19T12:00:00.000Z"
}
The endpoint is idempotent — calling it again with the same customer_email returns the existing active account without creating a duplicate.

List Virtual Accounts

Returns a cursor-paginated list of all virtual accounts for your merchant, newest first.

GET
/v1/virtual-accounts

Returns a paginated list of virtual accounts.

Query parameters

ParameterTypeRequiredDescription
limitintegerOptionalResults per page. Default 20, max 100.
cursorstringOptionalPagination cursor from a previous response next_cursor field.
List virtual accountsbash
curl "https://api.popfab.io/v1/virtual-accounts?limit=50" \
  -H "Authorization: Bearer sk_test_YOUR_API_KEY"

Get a Virtual Account

GET
/v1/virtual-accounts/:id

Retrieves a single virtual account by its POPFAB ID.

Get virtual account by IDbash
curl https://api.popfab.io/v1/virtual-accounts/ppfb_va_a1b2c3d4e5f6 \
  -H "Authorization: Bearer sk_test_YOUR_API_KEY"

How Payments Are Matched

When a customer makes a bank transfer to their dedicated virtual account number, Paystack detects the inbound credit and sends a charge.success webhook to POPFAB's inbound webhook URL. POPFAB receives this event and automatically creates a payment record linked to the matching customer. Merchants should listen for payment.success webhooks from POPFAB to be notified when a virtual-account payment is received.

Make sure you have configured your POPFAB inbound webhook URL in your Paystack dashboard under Settings → Webhooks.

Provider Support

ProviderVirtual AccountsBanks available
PaystackWema Bank, Titan Bank
MonnifyMultiple
SquadGTBank
Flutterwave
Interswitch
Payaza