Documentation

Platform Admin Virtual Accounts

Manage virtual accounts and dynamic sessions across all tenants

Overview

Virtual accounts provide unique bank account numbers that can receive payments. They can be dedicated (permanent) or dynamic (temporary sessions for specific transactions).

Virtual Account Types

Virtual accounts come in different types based on their lifecycle and usage pattern.

TypeDescriptionUse Case
dedicatedPermanent virtual account tied to a wallet accountLong-term collections, recurring payments, customer funding accounts
dynamicTemporary session-based account number with expirationOne-time payments, invoice-specific collections, time-limited transactions
capabilityFeature-enabled account for specific integrationsPOS settlements, processor integrations, specialized payment flows

Virtual Account Purposes

Each virtual account is assigned a purpose that determines its behavior and routing.

PurposeDescription
wallet_fundingReceives deposits to fund wallet accounts
wallet_paymentReceives payments for wallet-based transactions
collectionsGeneral-purpose collection account for businesses
posSettlement account for POS terminal transactions

Status Definitions

StatusDescriptionCan Receive Payments
activeVirtual account is operational and can receive paymentsYes
expiredDynamic session has passed its expiration timeNo
closedVirtual account has been permanently deactivatedNo

Provider Integrations

Virtual accounts are provisioned through various banking partners and payment providers.

ProviderBanks SupportedFeatures
providusProvidus BankDedicated and dynamic VAs, instant notification
wemaWema Bank (ALAT)Dedicated VAs, corporate collections
gtbGTBankDedicated VAs, high-volume collections
sterlingSterling BankDynamic VAs, session-based payments

List Virtual Accounts

Retrieve virtual accounts across all tenants with comprehensive filtering options.

Endpoint

GET/api/v1/admin/virtual-accounts

List all virtual accounts across the platform. Supports filtering by tenant, provider, status, type, and purpose. Can optionally include active sessions for dynamic accounts.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Query Parameters

ParameterTypeRequiredDescription
tenant_idstringNoFilter by tenant UUID
account_idstringNoFilter by linked wallet account UUID
providerstringNoFilter by banking providerValues: providus, wema, gtb, sterling
statusstringNoFilter by virtual account statusValues: active, expired, closed
account_typestringNoFilter by virtual account typeValues: dynamic, dedicated, capability
purposestringNoFilter by virtual account purposeValues: wallet_funding, wallet_payment, collections, pos
querystringNoSearch by account name, number, or reference
numberstringNoExact match on virtual account number
sort_bystringNo (default: created_at)Sort fieldValues: created_at, virtual_account_number
sort_orderstringNo (default: desc)Sort orderValues: asc, desc
include_sessionsbooleanNo (default: false)Include active sessions for dynamic virtual accounts
limitintegerNo (default: 20)Page size (max 200)
offsetintegerNo (default: 0)Page offset

Response- Paginated list of virtual accounts with tenant and linked account details

json
{
  "data": [
    {
      "virtual_account": {
        "id": "va_550e8400-e29b-41d4-a716-446655440000",
        "account_id": "acc_660e8400-e29b-41d4-a716-446655440001",
        "account_type": "dedicated",
        "purpose": "wallet_funding",
        "virtual_account_number": "9900123456",
        "account_name": "John Doe/WalletCore",
        "provider": "providus",
        "provider_reference": "PVD-REF-12345",
        "bank_name": "Providus Bank",
        "bank_code": "101",
        "status": "active",
        "expires_at": null,
        "created_at": "2025-01-10T08:00:00Z",
        "metadata": {
          "customer_id": "cust_123",
          "source": "api"
        }
      },
      "tenant_id": "tenant_770e8400-e29b-41d4-a716-446655440002",
      "tenant_name": "Acme Corp",
      "account": {
        "id": "acc_660e8400-e29b-41d4-a716-446655440001",
        "account_code": "ACC-001234",
        "account_name": "John Doe Wallet",
        "currency": "NGN",
        "product_type": "wallet",
        "wallet_type": "customer",
        "status": "active"
      },
      "sessions": []
    },
    {
      "virtual_account": {
        "id": "va_880e8400-e29b-41d4-a716-446655440003",
        "account_id": "acc_990e8400-e29b-41d4-a716-446655440004",
        "account_type": "dynamic",
        "purpose": "collections",
        "virtual_account_number": "9900789012",
        "account_name": "Tech Solutions Ltd/Invoice-2025-001",
        "provider": "sterling",
        "provider_reference": "STL-REF-67890",
        "bank_name": "Sterling Bank",
        "bank_code": "232",
        "status": "active",
        "expires_at": "2025-01-15T23:59:59Z",
        "created_at": "2025-01-14T09:00:00Z",
        "metadata": {
          "invoice_id": "INV-2025-001",
          "expected_amount": 150000
        }
      },
      "tenant_id": "tenant_770e8400-e29b-41d4-a716-446655440002",
      "tenant_name": "Acme Corp",
      "account": {
        "id": "acc_990e8400-e29b-41d4-a716-446655440004",
        "account_code": "ACC-005678",
        "account_name": "Tech Solutions Ltd",
        "currency": "NGN",
        "product_type": "wallet",
        "wallet_type": "business",
        "status": "active"
      },
      "sessions": [
        {
          "id": "sess_110e8400-e29b-41d4-a716-446655440005",
          "session_account_number": "9900789012",
          "status": "active",
          "expected_amount": 150000,
          "credited_amount": 0,
          "created_at": "2025-01-14T09:00:00Z",
          "expires_at": "2025-01-15T23:59:59Z"
        }
      ]
    }
  ],
  "pagination": {
    "limit": 20,
    "offset": 0,
    "total_count": 15420
  }
}

Error Responses

StatusCodeDescription
401unauthorizedMissing or invalid admin JWT
403forbiddenAdmin role required
400invalid_filterInvalid filter parameter value

Query Parameters Reference

ParameterTypeDescription
tenant_idUUIDFilter to specific tenant
account_idUUIDFilter to specific linked wallet account
providerstringBank provider (providus, wema, gtb, sterling)
statusstringVirtual account status
account_typestringType: dynamic, dedicated, or capability
purposestringPurpose: wallet_funding, wallet_payment, collections, pos
querystringFree-text search across name, number, reference
numberstringExact virtual account number match
include_sessionsbooleanInclude active sessions for dynamic VAs

List Virtual Account Sessions

Retrieve dynamic virtual account sessions across all tenants. Sessions are temporary account numbers created for specific payment expectations.

Endpoint

GET/api/v1/admin/virtual-account-sessions

List all dynamic virtual account sessions. Sessions track expected payments with amounts, expiration times, and inflow details. Useful for monitoring payment completion rates and reconciliation.

Headers

ParameterTypeRequiredDescription
AuthorizationstringYesBearer {admin_access_token}

Query Parameters

ParameterTypeRequiredDescription
tenant_idstringNoFilter by tenant UUID
account_idstringNoFilter by linked wallet account UUID
virtual_account_idstringNoFilter by parent virtual account UUID
providerstringNoFilter by banking provider
statusstringNoFilter by session statusValues: active, expired, closed
numberstringNoExact match on session account number
created_fromstringNoFilter sessions created after this date (ISO 8601)
created_tostringNoFilter sessions created before this date (ISO 8601)
expires_fromstringNoFilter sessions expiring after this date (ISO 8601)
expires_tostringNoFilter sessions expiring before this date (ISO 8601)
include_inflowbooleanNo (default: false)Include inflow transaction details for credited sessions
limitintegerNo (default: 20)Page size (max 200)
offsetintegerNo (default: 0)Page offset

Response- Paginated list of dynamic sessions with virtual account, tenant, and optional inflow details

json
{
  "data": [
    {
      "id": "sess_110e8400-e29b-41d4-a716-446655440005",
      "virtual_account_id": "va_880e8400-e29b-41d4-a716-446655440003",
      "session_account_number": "9900789012",
      "status": "active",
      "created_at": "2025-01-14T09:00:00Z",
      "expires_at": "2025-01-15T23:59:59Z",
      "closed_at": null,
      "expected_amount": 150000,
      "credited_amount": 150000,
      "credited_at": "2025-01-14T14:30:00Z",
      "tenant_id": "tenant_770e8400-e29b-41d4-a716-446655440002",
      "tenant_name": "Acme Corp",
      "account": {
        "id": "acc_990e8400-e29b-41d4-a716-446655440004",
        "account_code": "ACC-005678",
        "account_name": "Tech Solutions Ltd",
        "currency": "NGN",
        "product_type": "wallet",
        "wallet_type": "business",
        "status": "active"
      },
      "virtual_account": {
        "id": "va_880e8400-e29b-41d4-a716-446655440003",
        "account_id": "acc_990e8400-e29b-41d4-a716-446655440004",
        "account_type": "dynamic",
        "purpose": "collections",
        "virtual_account_number": "9900789012",
        "account_name": "Tech Solutions Ltd/Invoice-2025-001",
        "provider": "sterling",
        "provider_reference": "STL-REF-67890",
        "bank_name": "Sterling Bank",
        "bank_code": "232",
        "status": "active",
        "expires_at": "2025-01-15T23:59:59Z",
        "created_at": "2025-01-14T09:00:00Z",
        "metadata": {}
      },
      "inflow": {
        "transaction_id": "txn_220e8400-e29b-41d4-a716-446655440006",
        "amount": 150000,
        "currency": "NGN",
        "status": "completed",
        "description": "Payment for Invoice INV-2025-001",
        "created_at": "2025-01-14T14:28:00Z",
        "completed_at": "2025-01-14T14:30:00Z",
        "failed_at": null,
        "reversal_of_transaction_id": null,
        "reversed_by_transaction_id": null,
        "provider_payload": {
          "session_id": "STL-SESS-12345",
          "sender_account_number": "0123456789",
          "sender_account_name": "CUSTOMER ABC",
          "sender_bank_code": "058",
          "sender_bank_name": "GTBank",
          "payment_reference": "PAY-REF-2025-001",
          "narration": "Payment for services",
          "transaction_date": "2025-01-14T14:28:00Z"
        }
      }
    }
  ],
  "pagination": {
    "limit": 20,
    "offset": 0,
    "total_count": 8540
  }
}

Error Responses

StatusCodeDescription
401unauthorizedMissing or invalid admin JWT
403forbiddenAdmin role required
400invalid_date_rangeInvalid date format or range

Session Lifecycle

Understanding the session lifecycle helps in monitoring payment flows.

StageStatusDescription
CreatedactiveSession created with expected amount, awaiting payment
CreditedactivePayment received, credited_amount > 0, credited_at set
ExpiredexpiredSession passed expires_at without full payment
ClosedclosedSession manually closed by admin or system

Inflow Transaction Status

The inflow object tracks the actual payment received on the session.

StatusDescription
pendingPayment notification received, processing in progress
completedPayment successfully credited to the linked account
failedPayment processing failed, no credit applied
reversedPayment was reversed after initial completion

Provider Payload Fields

The provider_payload contains raw payment details from the banking partner. Common fields include:

FieldDescription
session_idProvider's internal session identifier
sender_account_numberPayer's bank account number
sender_account_namePayer's account name as registered with their bank
sender_bank_codeCBN code of the payer's bank
sender_bank_nameName of the payer's bank
payment_referenceUnique payment reference from provider
narrationPayment description provided by the payer
transaction_dateTimestamp when payment was processed by the provider

Data Models

Reference documentation for the data structures returned by virtual account APIs.

VirtualAccountSummary

Core virtual account information.

FieldTypeDescription
idstringUnique virtual account identifier
account_idstringUUID of linked wallet account
account_typestringType: dynamic, dedicated, or capability
purposestringPurpose: wallet_funding, wallet_payment, collections, pos
virtual_account_numberstring10-digit NUBAN account number
account_namestringName displayed on bank statements
providerstringBanking provider (providus, wema, etc.)
provider_referencestring | nullProvider's internal reference
bank_namestringFull name of the bank
bank_codestringCBN bank code
statusstringCurrent status (active, expired, closed)
expires_atstring | nullExpiration timestamp for dynamic VAs
created_atstringCreation timestamp
metadataobjectCustom metadata attached to the VA

AccountSummary

Linked wallet account information.

FieldTypeDescription
idstringUnique account identifier
account_codestringHuman-readable account code
account_namestringAccount holder name
currencystringAccount currency (e.g., NGN)
product_typestringProduct type (wallet, savings, etc.)
wallet_typestringWallet type (customer, business, pos)
statusstringAccount status

DynamicSession

Session for dynamic virtual accounts.

FieldTypeDescription
idstringUnique session identifier
virtual_account_idstringParent virtual account UUID
session_account_numberstringAccount number for this session
statusstringSession status (active, expired, closed)
created_atstringSession creation timestamp
expires_atstringSession expiration timestamp
closed_atstring | nullWhen session was closed (if applicable)
expected_amountnumberExpected payment amount in minor units
credited_amountnumberActual amount credited
credited_atstring | nullWhen payment was credited
tenant_idstringOwning tenant UUID
tenant_namestringOwning tenant name
accountAccountSummaryLinked wallet account details
virtual_accountVirtualAccountSummaryParent virtual account details
inflowSessionInflow | nullPayment transaction details (if include_inflow=true)

SessionInflow

Payment transaction received on a session.

FieldTypeDescription
transaction_idstringUnique transaction identifier
amountnumberTransaction amount in minor units
currencystringTransaction currency
statusstringTransaction status (pending, completed, failed, reversed)
descriptionstring | nullPayment description
created_atstringTransaction creation timestamp
completed_atstring | nullWhen transaction completed
failed_atstring | nullWhen transaction failed
reversal_of_transaction_idstring | nullIf this is a reversal, the original transaction
reversed_by_transaction_idstring | nullIf reversed, the reversing transaction
provider_payloadobjectRaw payment details from banking provider

Common Use Cases

Examples of how to use the virtual account APIs for common scenarios.

Monitor Pending Sessions

Find all sessions awaiting payment that are close to expiration.

bash
# Find active sessions expiring in the next 24 hours with no credit
curl -X GET \
  'https://api.walletcore.dev/api/v1/admin/virtual-account-sessions?
    status=active&
    expires_to=2025-01-15T23:59:59Z&
    include_inflow=true' \
  -H 'Authorization: Bearer {admin_token}'

Find Virtual Accounts by Provider

List all virtual accounts from a specific banking provider.

bash
# List all Providus virtual accounts
curl -X GET \
  'https://api.walletcore.dev/api/v1/admin/virtual-accounts?
    provider=providus&
    status=active&
    limit=100' \
  -H 'Authorization: Bearer {admin_token}'

Reconcile Tenant Payments

Get all sessions with inflows for a specific tenant.

bash
# Get all credited sessions for a tenant
curl -X GET \
  'https://api.walletcore.dev/api/v1/admin/virtual-account-sessions?
    tenant_id=tenant_770e8400-e29b-41d4-a716-446655440002&
    created_from=2025-01-01T00:00:00Z&
    include_inflow=true' \
  -H 'Authorization: Bearer {admin_token}'

Search by Account Number

Find a virtual account by its exact account number.

bash
# Find virtual account by number
curl -X GET \
  'https://api.walletcore.dev/api/v1/admin/virtual-accounts?
    number=9900123456' \
  -H 'Authorization: Bearer {admin_token}'