Collections (Inflow)
Collections are how you receive money into your business. Capera supports three collection methods:
| Method | How it works | Best for |
|---|---|---|
| NGN Static Virtual Account | Dedicated bank account number per customer | Recurring payments from known customers |
| NGN Dynamic Virtual Account | Temporary account for an exact amount | One-time invoice or order payments |
| Mobile Money (MoMo) Collection | Push payment request to a mobile wallet | Markets 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
| Field | Type | Required | Description |
|---|---|---|---|
customerReference | string | Yes | The reference you assigned when creating the customer |
preferredBank | string | No | Request 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
| Field | Type | Required | Description |
|---|---|---|---|
amount | integer | Yes | Expected payment amount in kobo. Minimum 100 (₦1). |
preferredBank | string | No | Request 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
}
}| Field | Description |
|---|---|
accountNumber | Share this with the payer |
accountName | Your business name as it appears on the account |
bankName | The bank providing the virtual account |
expiresIn | Time until the account stops accepting payments |
fee | Collection 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=collectionResponse
{
"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
| Field | Type | Required | Description |
|---|---|---|---|
reference | string | Yes | Your unique identifier for this collection — used for idempotency |
amount | integer | Yes | Amount in the currency's minor unit. Must be greater than 0. |
operatorCode | string | Yes | Operator code from the List Operators response |
phoneNumber | string | Yes | Payer's phone number in E.164 format |
currency | string | Yes | ISO 4217 currency code (e.g. GHS, KES, UGX) |
narration | string | No | Description of the payment |
payer.firstName | string | Yes | Payer's first name |
payer.lastName | string | Yes | Payer's last name |
payer.email | string | No | Payer'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
| Error | Cause | Resolution |
|---|---|---|
Customer not found | The customerReference does not exist | Create the customer first |
Amount must be at least 100 | Dynamic VA amount below minimum (₦1) | Use amount >= 100 |
Service is not available | Virtual account provider temporarily unavailable | Retry later or try a different preferredBank |
provider is disabled | The requested preferredBank is inactive | Omit preferredBank to use the default, or use /preferred-banks to find an active one |
provider does not support static accounts | The requested provider only supports dynamic accounts | Choose a different provider |
What's next
Updated 4 months ago