Skip to main content
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

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

EventWhen 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.
TypeScript
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:
  1. Configure the SDK with your API credentials
  2. Retrieve your account balance
  3. Initiate a mobile money collection
  4. 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 CodeError TypeDescription
400Bad RequestInvalid request parameters
401UnauthorizedInvalid or missing API credentials
403ForbiddenInsufficient permissions
404Not FoundResource not found
422UnprocessableBusiness logic validation failed
429Rate LimitedToo many requests
    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

1

Secure Your Credentials

Always use environment variables or a secrets manager for API credentials. Never commit credentials to version control.
2

Implement Webhook Signature Verification

Always verify webhook signatures to ensure events are legitimately from Bila and haven’t been tampered with.
3

Handle Errors Gracefully

Implement proper error handling with retry logic for transient failures (5xx errors, rate limits).
4

Use Idempotent References

Always pass a unique reference on transfers and collections. This prevents duplicate transactions if a request is retried.
5

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.