Business Collections API
Collect mobile money from customers in Kenya, Tanzania, and Uganda into your collection wallet.
Prerequisites: Collections must be enabled for your business by WakaPay admin. Contact your account manager to activate collections and configure auto-sweep settings.
Quick Start
Typical collection flow:
- Receive apiKey & apiSecret - Provided via secure email from WakaPay
- Generate JWT -
POST /business/auth - Create Collection -
POST /business/collections(initiates payment push to customer) - Poll Status OR Wait for Callback -
GET /business/collections/:idor receive webhook - Verify Collection Wallet Balance -
GET /business/balance?purpose=collection
Key Concepts
| Concept | Definition |
|---|---|
| Collection | Push/STK/USSD payment request to customer phone; on success, funds credit collection wallet |
| Collection Wallet | Balance bucket with purpose=collection (per currency). Separate from payout wallet |
| Payout Wallet | Existing purpose=payout wallets used by /business/payout/* endpoints |
| Auto-Sweep | Nightly transfer from collection wallet to configured bank/mobile account (TZ/KE) |
Environments
UAT (Sandbox)
For development and integration testing.
Base URL: https://api.test.wakapay.io
Test Numbers: Use TESTENV numbers for auto-success collections:
- Kenya:
+254700000001 - Tanzania:
+255700000001 - Uganda:
+256700000001
Credentials: UAT apiKey and apiSecret (separate from production)
Production
For live customer transactions.
Base URL: https://api.wakapay.io
Credentials: Production apiKey and apiSecret (provided via secure email)
Each environment has its own credentials. Never use production credentials in UAT.
Supported Countries
| Country | Currency | Status | Production Status |
|---|---|---|---|
| Tanzania | TZS | Production | Active - All networks |
| Kenya | KES | Production | Active - All networks |
| Uganda | UGX | Production | Active - All networks |
Provider Routing
WakaPay automatically routes collections based on the customer’s mobile number (MSISDN):
| Country | Supported Networks | Customer Experience |
|---|---|---|
| Kenya | All mobile networks | M-Pesa STK push |
| Tanzania | All mobile networks | USSD or wallet payment prompt |
| Uganda | All mobile networks | Mobile money prompt |
Note: Partners do not need to specify the provider manually. Routing is determined automatically from the customer’s phone number.
Authentication
Generate a JWT access token using your API credentials.
POST /business/authRequest Body
{
"apiKey": "YOUR_API_KEY",
"apiSecret": "YOUR_API_SECRET"
}Example Request
curl -X POST https://api.test.wakapay.io/business/auth \
-H "Content-Type: application/json" \
-d '{
"apiKey": "YOUR_API_KEY",
"apiSecret": "YOUR_API_SECRET"
}'Response (200 OK)
{
"accessToken": "eyJ...",
"expiresIn": 3600
}The token expires after the specified duration (e.g., 3600 seconds). Reuse the same token for all API requests until it expires.
Using the Token
Include the token in all subsequent requests:
Authorization: Bearer YOUR_ACCESS_TOKENGet Balance
Retrieve your business wallet balances, including both payout and collection wallets.
GET /business/balanceQuery Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
currency | string | No | Currency code (KES, TZS, UGX) |
purpose | string | No | Wallet purpose: payout or collection |
Example Request - All Balances
curl https://api.test.wakapay.io/business/balance \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Response - All Balances
{
"businessId": "biz_abc123",
"items": [
{
"currency": "TZS",
"purpose": "payout",
"available": 1000000,
"holding": 0,
"pending": 0
},
{
"currency": "TZS",
"purpose": "collection",
"available": 25000,
"holding": 0,
"pending": 0
}
]
}Example Request - Collection Wallet Only
Filter to view only your collection wallet:
curl "https://api.test.wakapay.io/business/balance?currency=TZS&purpose=collection" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Response - Collection Wallet
{
"available": 25000,
"businessId": "biz_abc123",
"currency": "TZS",
"purpose": "collection",
"holding": 0,
"pending": 0
}Response Fields
| Field | Type | Description |
|---|---|---|
available | number | Available balance in the collection wallet |
holding | number | Funds on hold (reserved for processing) |
pending | number | Pending funds (collections being settled) |
purpose | string | Wallet type: collection or payout |
currency | string | Wallet currency (KES, TZS, UGX) |
businessId | string | Your business ID |
Create Collection
Create and initiate a collection request. This immediately sends the payment push/STK/USSD to the customer’s phone.
POST /business/collectionsRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | Yes | Amount to collect in major units (see minimum amounts below) |
currency | string | Yes | Must match MSISDN country: KES, TZS, or UGX |
mobile | string | Yes | Customer phone number in E.164 format |
reference | string | No | Your unique transaction/order reference (unique per business) |
narration | string | No | Customer-facing description (see narration support table) |
callbackUrl | string | No | Per-collection webhook URL (overrides business-level callback) |
Minimum Amounts
Minimum amount depends on the collection corridor.
- Uganda: ≥ 500 UGX
- Other countries: Contact WakaPay for current corridor-specific limits
Narration Support
The narration field is optional. Whether it’s displayed to the customer depends on the provider:
| Corridor / Provider | Shows Narration to Customer? |
|---|---|
| Kenya | Yes (M-Pesa STK narration) |
| Tanzania | No |
| Uganda | Yes |
Example Requests by Country
Tanzania
Tanzania (TZS)
UAT/Testing:
curl -X POST https://api.test.wakapay.io/business/collections \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"currency": "TZS",
"mobile": "+255700000001",
"reference": "INV-1001",
"narration": "Invoice 1001"
}'Production:
curl -X POST https://api.wakapay.io/business/collections \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"currency": "TZS",
"mobile": "+2557XXXXXXXX",
"reference": "INV-1001",
"narration": "Invoice 1001"
}'Supported Networks: All Tanzania mobile networks Customer Experience: USSD or wallet payment prompt Narration: Not shown to customer
Response (201 Created)
{
"id": "019abc...",
"status": "collection_pending",
"amount": 5000,
"currency": "TZS",
"mobile": "+2557XXXXXXXX",
"reference": "INV-1001",
"narration": "Invoice 1001",
"provider": "airtel",
"mnoPaymentReference": null,
"businessId": "biz_abc123",
"createdAt": "2024-08-08T07:53:06Z",
"updatedAt": "2024-08-08T07:53:06Z"
}Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Collection ID (use this to query status) |
status | string | Collection status (see statuses section) |
amount | number | Collection amount |
currency | string | Collection currency |
mobile | string | Customer phone number |
reference | string | Your transaction reference |
narration | string | Description shown to customer (where supported) |
provider | string | Provider name (may be empty initially, populated after routing) |
mnoPaymentReference | string | MNO transaction reference (initially null, populated after payment) |
businessId | string | Your business ID |
createdAt | string | ISO 8601 timestamp |
updatedAt | string | ISO 8601 timestamp |
Status field: Returns collection_pending when the payment push is successfully initiated. The customer then receives the payment prompt on their phone.
Provider field: Automatically populated based on the customer’s mobile number (MSISDN).
Get Collection Status
Get the current status of a specific collection transaction.
GET /business/collections/{collectionId}Example Request
curl https://api.test.wakapay.io/business/collections/019abc... \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Response - Success
{
"id": "019abc...",
"amount": 1000,
"businessId": "biz_abc123",
"currency": "TZS",
"mobile": "+2557XXXXXXXX",
"provider": "airtel",
"reference": "INV-1001",
"status": "collection_success",
"statusMessage": "Success",
"mnoPaymentReference": "AIRTEL123456",
"createdAt": "2024-08-08T07:53:06Z",
"updatedAt": "2024-08-08T07:54:12Z"
}Response - Cancelled/Expired
{
"id": "019def...",
"amount": 1000,
"currency": "TZS",
"mobile": "+2557XXXXXXXX",
"provider": "mno_provider",
"reference": "INV-1002",
"status": "cancelled",
"statusMessage": "Collection expired"
}List Collections
Get recent collection transactions for reconciliation, history, support, or dashboards.
GET /business/collectionsQuery Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Maximum number of items (e.g., 20) |
Example Request
curl "https://api.test.wakapay.io/business/collections?limit=20" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Response
{
"items": [
{
"id": "019abc...",
"amount": 1000,
"currency": "TZS",
"mobile": "+2557XXXXXXXX",
"provider": "airtel",
"reference": "INV-1001",
"status": "collection_success",
"statusMessage": "Success",
"mnoPaymentReference": "AIRTEL123456",
"createdAt": "2024-08-08T07:53:06Z",
"updatedAt": "2024-08-08T07:54:12Z"
},
{
"id": "019def...",
"amount": 5000,
"currency": "TZS",
"mobile": "+2557XXXXXXXX",
"provider": "mno_provider",
"reference": "INV-1002",
"status": "cancelled",
"statusMessage": "Collection expired",
"createdAt": "2024-08-08T08:10:22Z",
"updatedAt": "2024-08-08T08:15:30Z"
}
]
}Collection Statuses
| Status | Meaning | Terminal? |
|---|---|---|
collection_pending | Push sent; awaiting customer/provider response | No |
collection_success | Payment completed; collection wallet credited | Yes |
collection_failure | Provider or customer payment failed | Yes |
cancelled | Transaction cancelled or timed out | Yes |
Status Flow
collection_pending- Payment push sent to customer after POST /business/collectionscollection_success- Customer approves payment (terminal state)collection_failure- Customer declines or provider fails (terminal state)cancelled- Transaction timeout/expiration (terminal state)
Collection Flow Notes
Behavior:
- Tanzania: Collections use USSD or wallet payment prompts depending on the customer’s mobile network
- Kenya: Collections use M-Pesa STK push with standard timeout behavior
Callbacks/Webhooks
Callback URL Types
There are two types of callback URLs:
- Business-level callbackUrl: Configured by WakaPay admin, applies to all collections
- Per-collection callbackUrl: Passed in the request, overrides business-level for that specific collection
Callback Payload
If a callback URL is configured, WakaPay sends a collection status update when the collection reaches a terminal status (collection_success, collection_failure, or cancelled).
{
"event": "business.collection.updated",
"collectionId": "019abc...",
"businessId": "biz_abc123",
"status": "collection_success",
"amount": 5000,
"currency": "TZS",
"mobile": "+2557XXXXXXXX",
"reference": "INV-1001",
"provider": "provider_name",
"mnoPaymentReference": "MNO_REF_123456",
"occurredAt": "2024-08-08T07:54:12Z"
}Callback Signature
Callbacks are signed with your API secret (same scheme as payout callbacks).
Partners can either rely on callbacks for terminal updates or poll GET /business/collections/{collectionId} when necessary.
Country-Specific Examples
Collection flows and responses by country.
Tanzania
Tanzania
UAT/Testing Request:
curl -X POST https://api.test.wakapay.io/business/collections \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": 1000,
"currency": "TZS",
"mobile": "+255700000001",
"reference": "INV-1001",
"narration": "Invoice Payment"
}'Production Request:
curl -X POST https://api.wakapay.io/business/collections \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": 1000,
"currency": "TZS",
"mobile": "+2557XXXXXXXX",
"reference": "INV-1001",
"narration": "Invoice Payment"
}'Supported Networks: All Tanzania mobile networks
Expected Flow: USSD or wallet payment prompt on customer’s mobile number.
Success Response Example:
{
"id": "019abc...",
"amount": 1000,
"currency": "TZS",
"mobile": "+2557XXXXXXXX",
"provider": "provider_name",
"reference": "INV-1001",
"status": "collection_success",
"statusMessage": "Success",
"mnoPaymentReference": "MNO_REF_123456"
}Note: The provider field will show the actual mobile network provider based on the customer’s phone number.
UAT Testing
For development and integration testing, use the UAT environment with these test numbers:
| Country | Test MSISDN | Currency | Behavior | Production Status |
|---|---|---|---|---|
| Kenya | +254700000001 | KES | Auto-success collection | Active |
| Tanzania | +255700000001 | TZS | Auto-success collection | Active |
| Uganda | +256700000001 | UGX | Auto-success collection | Active |
Environment: UAT base URL has TESTENV=1 flag set automatically.
Error Responses
Common Errors
| HTTP | Error Message | Cause / Resolution |
|---|---|---|
| 403 | collections not enabled for this business | Contact admin to enable collections |
| 400 | currency does not match mobile country | e.g., KES currency with +255 number |
| 409 | duplicate reference | Reference already used for this business |
| 400 | invalid payload | Check request format and required fields |
| 500 | Provider not configured | Provider outage - contact WakaPay support |
| 400 | unsupported mobile country | Only KE/TZ/UG supported |
Error Examples
Collections Not Enabled
{
"code": 0,
"error": "collections not enabled for this business"
}Currency Mismatch
{
"code": 0,
"error": "currency does not match mobile country"
}Duplicate Reference
{
"code": 0,
"error": "duplicate reference"
}Unsupported Country
{
"code": 0,
"error": "unsupported mobile country for collections (KE/TZ/UG only)"
}Phone Number Format
Phone numbers must be supplied in international E.164 format:
- Tanzania:
+255... - Kenya:
+254... - Uganda:
+256...
Best Practices
- Store collection IDs - Save the
idreturned from create request to query status later - Use unique references - Prevents duplicate collections (409 error)
- Handle timeouts gracefully - Some providers may timeout if customer doesn’t respond
- Monitor collection wallet - Check balance after successful collections to verify credit
- Set up webhooks - Use callbacks for real-time status updates instead of constant polling
- Use narration strategically - Kenya and Uganda show narration to customers; Tanzania does not
- Test in UAT first - Always test integration with UAT test numbers before production
Auto-Sweep (Settlement)
Auto-sweep transfers collected funds from your collection wallet to your designated settlement account.
Configuration
Set up by WakaPay admin (not available via partner API in v1).
Schedule
Nightly at 00:05 Africa/Dar_es_Salaam timezone
By Country
- Tanzania: Verified bank or mobile settlement account → automatic nightly sweep
- Kenya: Verified bank or mobile settlement account → automatic nightly sweep
- Other countries: Queued for admin manual payout; admin marks done with bank reference
To Enable
Contact your WakaPay account manager to:
- Set your sweep destination account
- Enable
autoSweepEnabledflag
Related
- Wallet & Balance - Check collection wallet balance
- Webhooks - Configure collection status callbacks
- Authentication - Generate access tokens
- Error Handling - Handle collection errors