Overview
The Virtual Accounts Service is the financial core of PCX. It provisions and manages currency accounts (fiat), internal bank accounts, and internal crypto accounts for customers across any number of organisations. Every account is identified by anaccount_id and tied to both an org_id and a user_id.
Funds move through the service via six primitives: deposit, withdrawal, crypto fund, crypto withdrawal, internal transfer, and cross-rail payout. NGN operations route through SquadCo (virtual account provisioning) and Sarepay (bank transfers); non-NGN fiat and crypto operations route through Bridge.
Customer Onboarding
Before any accounts can be created, a customer must be onboarded. The two-step flow is:POST /virtual-accounts/kyc— Provide the customer’s email and type (individualorbusiness). The response returns acustomer_idand a Terms of Service link the customer must accept.POST /virtual-accounts/onboard— Once KYC is accepted, submit the full customer profile includingorg_id,user_id, name, phone, and an optionalinitial_balance. This creates the customer record and seeds any provisioned accounts.
Account Types
| Type | Endpoint | Description |
|---|---|---|
| Currency | POST /virtual-accounts/currency | Fiat account in any supported currency |
| Internal Bank | POST /virtual-accounts/internal/bank | Admin-provisioned bank account |
| Internal Crypto | POST /virtual-accounts/internal/crypto | Admin-provisioned crypto account |
VirtualAccount shape and can be fetched by organisation (GET /virtual-accounts/org/{org_id}) or by user (GET /virtual-accounts/user/{user_id}).
Fund Operations
Fiat Deposits and Withdrawals
- Deposit (
POST /virtual-accounts/deposit) — Admin-only. Credits an amount directly to an account. For NGN accounts this routes through SquadCo. - Withdrawal (
POST /virtual-accounts/withdraw) — Available tointernal-adminandorg-admin. For NGN withdrawals, the transaction is placed inpendingstatus and requires an admin approval step before the Sarepay bank transfer fires. Non-NGN withdrawals may target a pre-linkedexternal_account_idor be directed with abank_code+beneficiary_account_numberpair.
Crypto Funding and Withdrawal
Bridge is the provider for all crypto operations. Specify thepayment_rail (blockchain network, e.g. ethereum, solana) and currency (token symbol, e.g. usdc).
- Crypto deposit —
POST /virtual-accounts/fund/crypto - Crypto withdrawal —
POST /virtual-accounts/withdraw/crypto(requires ato_address)
Internal Transfers
POST /virtual-accounts/transfer moves funds between two accounts on the platform. Supply from_account_id, to_account_id, amount, and user_id. Both accounts must be active.
NGN Account Lookup
Before initiating a manual NGN withdrawal, usePOST /virtual-accounts/ngn/account-lookup to verify the destination bank account via Sarepay. The response includes the verified account_name for confirmation.
Transactions
Virtual account transactions are separate from the main PCX transaction ledger. Each record carries atype (credit or debit), status (pending, completed, failed), and — for crypto operations — a payment_rail.
| Endpoint | Description |
|---|---|
GET /virtual-accounts/transactions/{transaction_id} | Single transaction. Pass user identity via X-User-Id header or user_id query param. |
GET /virtual-accounts/{account_id}/transactions | Paginated list filtered by type, status, and date range. |
GET /virtual-accounts/sarepay/transactions/status | Check NGN transfer status in Sarepay by transaction_id or reference. |
last_evaluated_key from the previous meta block.
External Accounts
External bank accounts are linked via Bridge and stored percustomer_id. They serve as withdrawal destinations without requiring raw account numbers at withdrawal time.
POST /virtual-accounts/link— Link an account. Supports all major rail fields:account_number,sort_code(GBP),routing_number(USD),iban+bic(EUR), and address details for compliance.GET /virtual-accounts/link— List linked accounts for a customer (filtered optionally bycurrency).DELETE /virtual-accounts/link— Unlink an account bycustomer_id+external_account_id.
Activity Logs
Account activity is recorded in an immutable log accessible atGET /virtual-accounts/logs. Filter by org_id, account_id, event type, and date range. Aggregated metrics are available at GET /virtual-accounts/logs/metrics.
Fee Configurations
Fees are configured per currency and transaction type. Each configuration defines:| Field | Description |
|---|---|
fee_structure | percentage or fixed_amount |
fee_value | Percentage (0–100) or flat amount |
min_fee / max_fee | Cap / floor for percentage structures |
fee_type | Category label (e.g. platform_fee) |
POST /virtual-accounts/fees/preview to calculate the fee for a specific transaction_type, amount, and currency before executing the operation. This is useful for building pre-confirmation UIs that show users their total cost.
Admin Suite
All endpoints under/virtual-accounts/admin/ require the internal-admin role. They provide:
- Full account and customer listings with advanced filtering
- Transaction approval and rejection — NGN withdrawals queue here before reaching Sarepay
- Cross-rail payout trigger — manually advances a transaction that has been funded on one rail to disburse on another
- Platform analytics — aggregated volume and transaction counts
SquadCo Admin
The/virtual-accounts/admin/squadco/ group provides direct visibility and control over the NGN SquadCo layer:
- View and create SquadCo virtual accounts
- List and manage pending NGN withdrawal approvals
- Manually process approved withdrawals via Sarepay
- Monitor the SquadCo wallet balance
Webhooks
Provider events (Bridge, SquadCo) arrive atPOST /virtual-accounts/webhook/{provider_name}. Authentication is handled internally using provider-specific secrets — this endpoint is not called by PCX API consumers directly.
Authentication
All endpoints (except the webhook receiver) require a Bearer JWT in theAuthorization header. Admin endpoints additionally enforce the internal-admin role; withdrawal also accepts org-admin.