This guide walks you through integrating the Bila SDK into your application. You’ll learn how to configure the SDK, manage accounts, initiate collections, and send payouts across local markets.
Overview
The Bila SDK provides a unified, type-safe interface to:
Collections Accept mobile money payments from customers in Zambia and beyond.
Payouts & Transfers Send funds to bank accounts and mobile money wallets with ease.
Account Management Check balances and manage sub-wallets programmatically.
Webhooks Receive real-time notifications for transaction status updates.
Installation
npm install @usebila/sdk
# or
yarn add @usebila/sdk
go get -u github.com/bilasdk/go
Configuration
Before making API calls, configure the SDK with your API credentials from the Bila Console . You can obtain your BILA_API_KEY from the dashboard under Settings → API Keys .
import Bila from '@usebila/sdk' ;
const client = new Bila ({
apiKey: process . env . BILA_API_KEY ,
environment: 'sandbox' , // Use 'production' for live transactions
});
Never hardcode your API key in production code. Always use environment variables or a secure secrets manager.
Core Flows
1. Check Account Balance
Verify your wallet balance before initiating payouts.
const ACCOUNT_ID = 'your-account-id' ;
const balance = await client . accounts . getBalance ( ACCOUNT_ID );
console . log ( `Balance: ${ balance . availableBalance } ${ balance . currency } ` );
2. Collect Mobile Money
Initiate a mobile money collection request from a customer. The customer receives a USSD push prompt on their phone to authorise the payment.
const collection = await client . collections . initiateMobileMoneyCollection ({
amount: 100.50 ,
country: 'zm' ,
operator: 'airtel' ,
phone: '0977000000' ,
reference: 'collection-001' ,
walletId: 'your-wallet-id' ,
bearer: 'customer' ,
customerName: 'John Doe' ,
narration: 'Payment for subscription' ,
});
console . log ( 'Collection initiated:' , collection );
Check Collection Status
Poll or verify the status of a collection using its reference.
const status = await client . collections . getStatusByReference ( 'collection-001' );
console . log ( 'Status:' , status );
3. Send a Mobile Money Payout
Send funds directly to a recipient’s mobile money wallet.
const payout = await client . transfers . initiateMobileMoneyTransfer ({
amount: 250 ,
country: 'zm' ,
operator: 'airtel' ,
phone: '0977433571' ,
reference: 'payout-001' ,
narration: 'Mobile money payout' ,
recipientName: 'Jane Doe' ,
walletId: 'your-wallet-id' ,
});
console . log ( 'Payout initiated:' , payout );
4. Send a Bank Transfer
Send funds to a recipient’s bank account.
const transfer = await client . transfers . initiateBankTransfer ({
accountId: 'your-account-id' ,
amount: 1000 ,
reference: 'transfer-001' ,
accountNumber: '1234567890' ,
bankId: 'bank-001' ,
country: 'zm' ,
narration: 'Payment for services' ,
recipientName: 'Jane Doe' ,
transferRecipientId: 'recipient-id' ,
walletId: 'your-wallet-id' ,
});
console . log ( 'Transfer initiated:' , transfer );
Webhook Integration
Use webhooks to receive real-time notifications when transactions are completed, failed, or updated — without polling the API.
Transfer Events
Event When it fires transfer.completedA bank or mobile money transfer was successful transfer.failedA transfer attempt was unsuccessful collection.completedA mobile money collection was approved payment.completedA payment was successfully processed
Create a Webhook
const webhook = await client . webhooks . create ({
url: 'https://yourapp.com/webhooks/bila' ,
events: [ 'payment.completed' , 'transfer.completed' , 'transfer.failed' ],
});
console . log ( 'Webhook created:' , webhook );
List Webhooks
const webhooks = await client . webhooks . list ();
console . log ( 'Webhooks:' , webhooks );
Handling Webhook Events
When Bila sends an event to your endpoint, verify the signature and process the payload.
app . post ( '/webhooks/bila' , ( req , res ) => {
const signature = req . headers [ 'x-bila-signature' ];
// Verify the signature matches your webhook secret
// Process the event payload
const event = req . body ;
switch ( event . type ) {
case 'payment.completed' :
console . log ( 'Payment received:' , event . data );
break ;
case 'transfer.completed' :
console . log ( 'Transfer sent:' , event . data );
break ;
case 'transfer.failed' :
console . log ( 'Transfer failed:' , event . data );
break ;
}
res . status ( 200 ). send ( 'OK' );
});
Complete Integration Example
Here’s a real-world example demonstrating the complete flow:
Configure the SDK with your API credentials
Retrieve your account balance
Initiate a mobile money collection
Set up a webhook to receive real-time status updates
import Bila from '@usebila/sdk' ;
const client = new Bila ({
apiKey: process . env . BILA_API_KEY ,
environment: 'sandbox' ,
});
async function runExample () {
// Step 1: Check balance before initiating
const balance = await client . accounts . getBalance ( 'your-account-id' );
console . log ( `Available balance: ${ balance . availableBalance } ZMW` );
// Step 2: Initiate a collection
const collection = await client . collections . initiateMobileMoneyCollection ({
amount: 100.50 ,
country: 'zm' ,
operator: 'airtel' ,
phone: '0977000000' ,
reference: 'collection-001' ,
walletId: 'your-wallet-id' ,
customerName: 'John Doe' ,
narration: 'Payment for order #1234' ,
});
console . log ( 'Collection initiated:' , collection . id );
// Step 3: Register webhook for real-time updates
const webhook = await client . webhooks . create ({
url: 'https://yourapp.com/webhooks/bila' ,
events: [ 'collection.completed' , 'payment.completed' ],
});
console . log ( 'Webhook registered:' , webhook . id );
}
runExample (). catch ( console . error );
Error Handling
All SDK methods may throw exceptions. Here are common error scenarios and how to handle them.
HTTP Code Error Type Description 400 Bad Request Invalid request parameters 401 Unauthorized Invalid or missing API credentials 403 Forbidden Insufficient permissions 404 Not Found Resource not found 422 Unprocessable Business logic validation failed 429 Rate Limited Too many requests
TypeScript Error Handling
try {
const collection = await client . collections . initiateMobileMoneyCollection ({
amount: 100.50 ,
country: 'zm' ,
operator: 'airtel' ,
phone: '0977000000' ,
reference: 'collection-001' ,
walletId: 'your-wallet-id' ,
});
} catch ( error ) {
if ( error instanceof Bila . BilaError ) {
console . error ( `Status: ${ error . status } ` );
console . error ( `Message: ${ error . message } ` );
} else {
console . error ( 'Unexpected error:' , error );
}
}
from usebila import APIStatusError
try :
collection = client.collections.initiate_mobile_money_collection(
amount = 100.50 ,
country = "zm" ,
operator = "airtel" ,
phone = "0977000000" ,
reference = "collection-001" ,
wallet_id = "your-wallet-id" ,
)
except APIStatusError as e:
print ( f "Status: { e.status_code } " )
print ( f "Response: { e.response } " )
collection , err := client . Collections . InitiateMobileMoneyCollection ( ctx ,
bila . CollectionInitiateMobileMoneyCollectionParams {
Amount : bila . Float ( 100.50 ),
Country : bila . String ( "zm" ),
Operator : bila . String ( "airtel" ),
Phone : bila . String ( "0977000000" ),
Reference : bila . String ( "collection-001" ),
WalletID : bila . String ( "your-wallet-id" ),
},
)
if err != nil {
var apiErr * bila . Error
if errors . As ( err , & apiErr ) {
fmt . Printf ( "Status: %d \n " , apiErr . StatusCode )
fmt . Printf ( "Body: %s \n " , apiErr . Body )
}
log . Fatal ( err )
}
Best Practices
Secure Your Credentials
Always use environment variables or a secrets manager for API credentials. Never commit credentials to version control.
Implement Webhook Signature Verification
Always verify webhook signatures to ensure events are legitimately from Bila and haven’t been tampered with.
Handle Errors Gracefully
Implement proper error handling with retry logic for transient failures (5xx errors, rate limits).
Use Idempotent References
Always pass a unique reference on transfers and collections. This prevents duplicate transactions if a request is retried.
Use Webhooks Over Polling
Rely on webhook events for transaction status updates rather than polling the status endpoint repeatedly.
Next Steps
TypeScript SDK Reference Full method-by-method reference for the TypeScript SDK.
API Reference Explore the underlying REST API directly.
Webhooks Overview Deep dive into webhook events and security.
Collections Guide Learn more about mobile money collections.