Collections (Inflow)

Collections are how you receive money into your business. Capera supports three collection methods:

MethodHow it worksBest for
NGN Static Virtual AccountDedicated bank account number per customerRecurring payments from known customers
NGN Dynamic Virtual AccountTemporary account for an exact amountOne-time invoice or order payments
Mobile Money (MoMo) CollectionPush payment request to a mobile walletMarkets where MoMo is the primary payment rail

NGN Static Virtual Accounts

A static virtual account is a permanent NGN bank account number tied to one of your customers. The customer can send any amount at any time and you are notified via webhook on every deposit.

Prerequisites

The customer must exist before you generate a virtual account. Create the customer first — see Customers.

Generate a static virtual account

POST /v1/virtual-accounts/ngn
Authorization: Bearer <api-key>
Content-Type: application/json
{
  "customerReference": "CUST-001"
}

Request fields

FieldTypeRequiredDescription
customerReferencestringYesThe reference you assigned when creating the customer
preferredBankstringNoRequest a specific bank provider. If omitted, Capera uses the default active provider.

Response

{
  "success": true,
  "data": {
    "id": "va_abc123",
    "accountNumber": "1234567890",
    "accountName": "Amara Okafor - Your Business",
    "bankName": "Providus Bank",
    "createdAt": "2024-01-15T10:05:00Z",
    "updatedAt": "2024-01-15T10:05:00Z"
  }
}

Share the accountNumber and bankName with your customer. They do a regular bank transfer — no integration needed on their end.

List a customer's virtual accounts

GET /v1/virtual-accounts/ngn/{customerReference}
Authorization: Bearer <api-key>

Response

{
  "success": true,
  "data": [
    {
      "id": "va_abc123",
      "accountNumber": "1234567890",
      "accountName": "Amara Okafor - Your Business",
      "bankName": "Providus Bank",
      "createdAt": "2024-01-15T10:05:00Z",
      "updatedAt": "2024-01-15T10:05:00Z"
    }
  ]
}

Get a specific virtual account

GET /v1/virtual-accounts/ngn/{customerReference}/{accountId}
Authorization: Bearer <api-key>

List available bank providers

To see which banks are available as providers (and which support static accounts), use:

GET /v1/virtual-accounts/preferred-banks
Authorization: Bearer <api-key>

You can filter by bank name:

GET /v1/virtual-accounts/preferred-banks?bank_name=providus
Authorization: Bearer <api-key>

Response

{
  "success": true,
  "data": [
    {
      "provider": "PROVIDUS",
      "bankName": "Providus Bank",
      "isActive": true,
      "isDefaultStatic": true,
      "supportsStaticAccount": true
    }
  ]
}

Webhook event

When a payment arrives on a customer's static virtual account:

Event: customer.deposit.success

{
  "id": "evt_ghi789",
  "event": "customer.deposit.success",
  "timestamp": "2024-01-15T12:00:00Z",
  "data": {
    "id": "dep_xyz456",
    "customerReference": "CUST-001",
    "amount": 500000,
    "fee": 25,
    "currency": "NGN",
    "reference": "CAPERA-CUSTDEP-456",
    "senderAccountName": "John Smith",
    "senderAccountNumber": "1122334455",
    "senderBankName": "First Bank",
    "recipientAccountNumber": "1234567890",
    "recipientBankName": "Providus Bank",
    "sessionId": "000001240115...",
    "transactionId": "txn_abc789",
    "createdAt": "2024-01-15T12:00:00Z"
  }
}

NGN Dynamic Virtual Accounts

A dynamic virtual account is a temporary NGN bank account created for a specific payment amount. It expires after 24 hours and only accepts the exact amount specified.

Use dynamic accounts when you know how much you expect to receive — for example to settle an invoice, collect an order payment, or enforce exact-amount top-ups.

Generate a dynamic virtual account

POST /v1/virtual-accounts/dynamic/ngn
Authorization: Bearer <api-key>
Content-Type: application/json
{
  "amount": 1500000
}

Request fields

FieldTypeRequiredDescription
amountintegerYesExpected payment amount in kobo. Minimum 100 (₦1).
preferredBankstringNoRequest a specific bank provider. Defaults to the active dynamic provider (Globus).

Amounts are always in kobo. ₦1 = 100 kobo, ₦15,000 = 1,500,000 kobo.

Response

{
  "success": true,
  "data": {
    "accountNumber": "9900123456",
    "accountName": "Your Business Name",
    "bankName": "Globus Bank",
    "expiresIn": "24h0m0s",
    "fee": 50
  }
}
FieldDescription
accountNumberShare this with the payer
accountNameYour business name as it appears on the account
bankNameThe bank providing the virtual account
expiresInTime until the account stops accepting payments
feeCollection fee in kobo deducted from the incoming deposit

Webhook event

When a payment is received on a dynamic account:

Event: deposit.success

{
  "id": "evt_def456",
  "event": "deposit.success",
  "timestamp": "2024-01-15T12:00:00Z",
  "data": {
    "id": "dep_xyz789",
    "amount": 1500000,
    "fee": 50,
    "currency": "NGN",
    "reference": "CAPERA-DEP-123",
    "senderAccountName": "Jane Doe",
    "senderAccountNumber": "9876543210",
    "senderBankName": "GTBank",
    "recipientAccountNumber": "9900123456",
    "recipientBankName": "Globus Bank",
    "sessionId": "000001240115...",
    "transactionId": "txn_xyz789",
    "createdAt": "2024-01-15T12:00:00Z"
  }
}

Mobile Money (MoMo) Collection

MoMo collection initiates a payment request directly to a customer's mobile wallet. The customer receives a prompt on their phone and approves the payment. Some operators require an OTP confirmation step.

Step 1: List operators

Fetch the available MoMo operators for the customer's country.

GET /v1/momo/operators/{country_code}

No authentication required. country_code is an ISO 3166-1 alpha-2 code (e.g. GH, KE, UG).

You can filter by type using the type query parameter:

GET /v1/momo/operators/GH?type=collection

Response

{
  "success": true,
  "data": [
    { "operator": "MTN Ghana", "operatorCode": "MTN_GH" },
    { "operator": "Vodafone Ghana", "operatorCode": "VOD_GH" },
    { "operator": "AirtelTigo Ghana", "operatorCode": "ATL_GH" }
  ]
}

Step 2: Resolve the account (recommended)

Verify the phone number and retrieve the account holder's name before initiating the request.

GET /v1/momo/resolve-account
Authorization: Bearer <api-key>
Content-Type: application/json
{
  "operatorCode": "MTN_GH",
  "phoneNumber": "+233241234567"
}

Response

{
  "success": true,
  "data": {
    "firstName": "Kwame",
    "lastName": "Mensah",
    "operatorCode": "MTN_GH"
  }
}

Step 3: Request the payment

POST /v1/momo/collection
Authorization: Bearer <api-key>
Content-Type: application/json
{
  "reference": "COLL-2024-001",
  "amount": 5000,
  "operatorCode": "MTN_GH",
  "phoneNumber": "+233241234567",
  "currency": "GHS",
  "narration": "Payment for order #2042",
  "payer": {
    "firstName": "Kwame",
    "lastName": "Mensah",
    "email": "[email protected]"
  }
}

Request fields

FieldTypeRequiredDescription
referencestringYesYour unique identifier for this collection — used for idempotency
amountintegerYesAmount in the currency's minor unit. Must be greater than 0.
operatorCodestringYesOperator code from the List Operators response
phoneNumberstringYesPayer's phone number in E.164 format
currencystringYesISO 4217 currency code (e.g. GHS, KES, UGX)
narrationstringNoDescription of the payment
payer.firstNamestringYesPayer's first name
payer.lastNamestringYesPayer's last name
payer.emailstringNoPayer's email address

Response

{
  "success": true,
  "data": {
    "amount": 5000,
    "phoneNumber": "+233241234567",
    "operator": "MTN_GH",
    "currency": "GHS",
    "narration": "Payment for order #2042",
    "reference": "COLL-2024-001",
    "status": "PENDING",
    "instruction": null
  }
}

Some operators return an instruction object containing a USSD code or prompt the customer must complete to approve the payment.

Step 4: Handle OTP (if required)

Some operators require the payer to enter a one-time PIN sent to their phone. If the operator uses OTP-based authorisation, submit it using:

POST /v1/momo/collection/verify-otp
Authorization: Bearer <api-key>
Content-Type: application/json
{
  "reference": "COLL-2024-001",
  "otp": "123456"
}

Response

{
  "success": true,
  "data": {
    "reference": "COLL-2024-001",
    "operator": "MTN_GH",
    "status": "APPROVED"
  }
}

Step 5: Check collection status

Poll for the final outcome or rely on webhooks.

GET /v1/momo/collection/{reference}
Authorization: Bearer <api-key>

Response

{
  "success": true,
  "data": {
    "amount": 5000,
    "phoneNumber": "+233241234567",
    "operator": "MTN_GH",
    "currency": "GHS",
    "reference": "COLL-2024-001",
    "status": "SUCCESSFUL"
  }
}

Error handling

ErrorCauseResolution
Customer not foundThe customerReference does not existCreate the customer first
Amount must be at least 100Dynamic VA amount below minimum (₦1)Use amount >= 100
Service is not availableVirtual account provider temporarily unavailableRetry later or try a different preferredBank
provider is disabledThe requested preferredBank is inactiveOmit preferredBank to use the default, or use /preferred-banks to find an active one
provider does not support static accountsThe requested provider only supports dynamic accountsChoose a different provider

What's next

  • Payouts — send money to bank accounts and mobile wallets
  • Deposits — query incoming deposit history
  • Webhooks — receive real-time payment notifications

Did this page help you?