Skip to content

Create a non-expiring virtual account

A non-expiring virtual account is an ordinary bank-issued virtual account with no time-to-live: the same lifecycle, the same settlement rules and the same notification as a number from Create a virtual account, except that it never reaches EXPIRED on its own and accepts any number of payments. Use it for a standing collection number per customer of yours: a school fee account per pupil, a savings number per member. The name a payer sees at name enquiry is the payer’s own, built from firstName and lastName.

POST/api/legacy/agent/createFVAscope: virtual-accounts:create
Header Required Description
X-Agent-Account Yes A 10-digit account you may read: your own, or a sub-agent’s transaction account. Decides whose band is used and the fallback settlement account.

The body is JSON. Every field is optional. Note the field names: the three payer fields are camelCase, the settlement field is snake_case.

Field Type Required Description
firstName string No Payer’s first name. Stored upper-cased. Max 100 characters.
lastName string No Payer’s last name. Stored upper-cased. Max 100 characters.
phoneNumber string No Payer’s phone, for example 08012345678. Normalised on save. Max 20 characters.
beneficiary_account string No 10-digit account the payments settle to. Must exist at the bank and be able to receive credits. Same precedence as the dynamic call.

firstName and lastName, joined with a space, form the name a payer sees at name enquiry. If both are omitted the number has no name.

Terminal window
curl -X POST https://api.bankcore.ng/api/legacy/agent/createFVA \
-H "Authorization: Bearer $TOKEN" \
-H "X-Agent-Account: 6020012345" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Adaeze",
"lastName": "Okafor",
"phoneNumber": "08012345678",
"beneficiary_account": "6020023456"
}'
{
"code": "0000",
"desc": "4000001050"
}
Field Description
code 0000 on success.
desc The 10-digit virtual account number. On failure, the reason in words.

Nothing else is returned. Keep your own record of the number against the payer.

HTTP 200 always. Read code, then desc.

Code desc begins with When
0012 Account ... is not linked to this API client X-Agent-Account names an account you may not read.
0096 X-Agent-Account header is required Header missing.
0096 FVA creation failed: Agent account not found: ... The header account does not exist in your tenant.
0096 Account does not belong to an agent The header account belongs to an individual customer.
0096 FVA creation failed: No allocatable LOCAL virtual account range found for customer: ... No bank-issued band for the owner of the header account, or the band is closed to new numbers.
0096 FVA creation failed: All virtual account ranges exhausted ... or Virtual account range ... exhausted Every band is full. Ask the bank for more space.
0096 FVA creation failed: Beneficiary account not found: ... beneficiary_account does not exist.
0096 FVA creation failed: Beneficiary account ... is not active ... beneficiary_account cannot receive credits.

Most failures share the code 0096; the text is the discriminator.

Same number space. The number is drawn from the same bands as expiring numbers, in the same order (bands reserved to your client first, then the owner’s shared bands, lowest start first), and consumes band capacity like any other.

Same settlement precedence. beneficiary_account wins; then an account the bank linked to the band; then the header account; then the oldest account of the band’s owner. The same caution as the dynamic call applies: beneficiary_account is checked for existence and creditability, not ownership. Only ever name your own accounts or a sub-agent’s.

No reference, no amount rule. The call takes no external_ref and no amount. There is no duplicate check: calling twice with the same payer creates two numbers. If you need a reference or an exact-amount rule on a permanent number, use create with no ttl and "multi": true.

Lifecycle. The number stays live for as long as the band is active. It never becomes USED, because every payment is accepted, and it never expires on its own. Once the current-build caution above is lifted, expire ends it like any other number; until then only the bank can switch it off.

The Virtual accounts page lists bank-issued numbers with their status, settlement account and payer name; in the current build, numbers from this call are not listed there. Payments to them appear on Inflows for the band.