Virtual Accounts

Provision persistent NUBANs (dedicated virtual accounts) for your customers.

A virtual account is a persistent NUBANmapped to one of your customers. Once created it never changes, so a customer can pay into the same account number repeatedly. Every inflow is reconciled against the account's optional expectedAmountKobo.

Amounts are in kobo, not naira

Every amount is an integer in kobo (₦1 = 100 kobo). expectedAmountKobo: 500000 means ₦5,000. Passing naira is the single most common integration bug.

accountRef is unique per tenant

Re-using an existing accountRef returns the existing account rather than creating a duplicate. Use a stable, unique reference per customer (e.g. an invoice or user id).

Provisioning can briefly fail (502)

Provisioning depends on the upstream bank provider's sandbox, which is occasionally flaky. On a 502 Upstream provider error, retry with the same accountRef — it is safe and returns the account once it succeeds.
get/api/v1/virtual-accounts

List the tenant's virtual accounts (optionally scoped to a sub-merchant).

Requires Bearer token

Query parameters

subMerchantRefstringoptional
takeintegeroptional

Responses

200OK
GET /api/v1/virtual-accounts
curl -X GET "https://api.xental.online/api/v1/virtual-accounts" \
  -H "Authorization: Bearer <API_TOKEN>"
post/api/v1/virtual-accounts

Provision a persistent NUBAN for a customer. From an <b>API key</b> the mode follows the key's `key_mode` — a test key mints a sandbox NUBAN, a live key a real one. From the <b>dashboard</b> provisioning is always live and requires approved onboarding; test customers and virtual accounts are created via a test API key.

Provisions a NUBAN via the bank provider and stores it under your accountRef. If you pass expectedAmountKobo, inflows are classified as exact / underpaid / overpaid against it; omit it for an open account that simply accrues credit.

Requires Bearer token

Body parameters

accountRefstringoptional
namestringoptional
emailstringoptional
phonestringoptional
expectedAmountKobointegeroptional
expiryDateUtcstring<date-time>optional
subMerchantRefstringoptional

Responses

201Provisioned; body carries the NUBAN + reconciliation state.403Provisioning from the dashboard without approved onboarding.409A virtual account already exists for this accountRef.
POST /api/v1/virtual-accounts
curl -X POST "https://api.xental.online/api/v1/virtual-accounts" \
  -H "Authorization: Bearer <API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "accountRef": "inv_001",
    "name": "Ada Lovelace",
    "email": "ada@example.com"
  }'
Example request body
{
  "accountRef": "inv_001",
  "name": "Ada Lovelace",
  "email": "ada@example.com"
}
get/api/v1/virtual-accounts/{accountRef}

Fetch a virtual account by its accountRef (details + balance/state).

Returns the account plus its running balance (amountPaidKobo), deficit, overpayment, and paymentState — the fastest way to poll payment progress if you are not using webhooks or Live Checkout.

Requires Bearer token

Path parameters

accountRefstringrequired

Responses

200OK404No virtual account for this accountRef.
GET /api/v1/virtual-accounts/{accountRef}
curl -X GET "https://api.xental.online/api/v1/virtual-accounts/inv_001" \
  -H "Authorization: Bearer <API_TOKEN>"
delete/api/v1/virtual-accounts/{accountRef}

Delete a customer's virtual account (and the customer if it has no other accounts). Only accounts with no payment activity can be deleted.

Requires Bearer token

Path parameters

accountRefstringrequired

Responses

204Deleted.404No virtual account for this accountRef.409The account has payment activity and cannot be deleted.
DELETE /api/v1/virtual-accounts/{accountRef}
curl -X DELETE "https://api.xental.online/api/v1/virtual-accounts/inv_001" \
  -H "Authorization: Bearer <API_TOKEN>"