Language SDKs

SaaS tenant. The MFI Suite is delivered as a fully managed service — there is nothing to install or configure at the OS level. Self-hosted one-time licence buyers receive a dedicated installation runbook with the licence delivery; this page describes the user-facing workflow only.

Use a language SDK instead of raw HTTP. Each SDK handles OAuth refresh, retries, idempotency keys, pagination, and typed responses so your application code stays clean.

API SDKs
SDK install instructions in each SDK README.
At a glance — Python: (install instructions are in each SDK's README; pick your language below). Node: npm install @bridgeerp/mfi-sdk. Java: Maven com.bridgeerp:mfi-sdk:1.x. Go: go get github.com/bridgeerp/mfi-sdk-go. All SDKs versioned 1.x against API v1; 2.x for v2.

Python SDK

from mfi_sdk import MfiClient

client = MfiClient(
    base_url='https://microfinance.mybridgeerp.com',
    client_id='svc_kcb_disbursement',
    client_secret='...',
    scopes=['loans:read', 'disbursements:write'],
)

# List loans
for loan in client.loans.list(state='ready_to_disburse'):
    print(loan.id, loan.member_name, loan.principal)

# Create member with idempotency
member = client.members.create(
    name='Jane Wambui Mwangi',
    national_id='22748561',
    phone='+254712345678',
    branch_id=3,
    idempotency_key='jane-wambui-2026-03-15',
)

# Disburse
disb = client.loans.disburse(
    loan_id=9183,
    amount=5000000,
    channel='mpesa_b2c',
    msisdn='+254712345678',
    idempotency_key='disburse-9183-2026-03-15',
)

Node.js SDK

import { MfiClient } from '@bridgeerp/mfi-sdk';

const client = new MfiClient({
  baseUrl: 'https://microfinance.mybridgeerp.com',
  clientId: 'svc_kcb_disbursement',
  clientSecret: process.env.MFI_SECRET,
  scopes: ['loans:read', 'disbursements:write'],
});

// List loans (async iterator handles pagination)
for await (const loan of client.loans.list({ state: 'ready_to_disburse' })) {
  console.log(loan.id, loan.memberName, loan.principal);
}

// Create member
const member = await client.members.create({
  name: 'Jane Wambui Mwangi',
  nationalId: '22748561',
  phone: '+254712345678',
  branchId: 3,
}, { idempotencyKey: 'jane-wambui-2026-03-15' });

// Verify webhook signature
import { verifyWebhook } from '@bridgeerp/mfi-sdk';
const ok = verifyWebhook(rawBody, signature, secret);

Java SDK

// pom.xml
// <dependency>
//   <groupId>com.bridgeerp</groupId>
//   <artifactId>mfi-sdk</artifactId>
//   <version>1.4.0</version>
// </dependency>

MfiClient client = MfiClient.builder()
    .baseUrl("https://microfinance.mybridgeerp.com")
    .clientId("svc_kcb_disbursement")
    .clientSecret(System.getenv("MFI_SECRET"))
    .scopes(List.of("loans:read", "disbursements:write"))
    .build();

List<Loan> loans = client.loans()
    .list()
    .state("ready_to_disburse")
    .execute();

Member member = client.members().create(
    MemberCreate.builder()
        .name("Jane Wambui Mwangi")
        .nationalId("22748561")
        .phone("+254712345678")
        .branchId(3)
        .build(),
    RequestOptions.builder()
        .idempotencyKey("jane-wambui-2026-03-15")
        .build()
);

Go SDK

package main

import (
    "context"
    "log"
    "github.com/bridgeerp/mfi-sdk-go"
)

func main() {
    client := mfi.NewClient(mfi.Config{
        BaseURL:      "https://microfinance.mybridgeerp.com",
        ClientID:     "svc_kcb_disbursement",
        ClientSecret: os.Getenv("MFI_SECRET"),
        Scopes:       []string{"loans:read", "disbursements:write"},
    })

    ctx := context.Background()

    loans, err := client.Loans.List(ctx, &mfi.LoanListParams{State: mfi.String("ready_to_disburse")})
    if err != nil { log.Fatal(err) }

    for _, l := range loans.Data {
        log.Printf("%d %s %d", l.ID, l.MemberName, l.Principal)
    }

    member, err := client.Members.Create(ctx, &mfi.MemberCreateParams{
        Name:       "Jane Wambui Mwangi",
        NationalID: "22748561",
        Phone:      "+254712345678",
        BranchID:   3,
    }, mfi.RequestOptions{IdempotencyKey: "jane-wambui-2026-03-15"})
}

Common SDK features

  • Automatic OAuth token caching and refresh
  • Exponential backoff on 429 and 5xx
  • Idempotency-Key support on all mutating methods
  • Webhook signature verification helper
  • Pluggable HTTP client for proxy / TLS customisation
  • Pluggable logger for structured request/response logging
  • Typed response models — full IDE auto-complete
  • Async iterators / streams for pagination

Worked scenarios

Scenario — Nightly disbursement job in Node.js

Setting: Mwananchi SACCO runs a nightly Node.js job that disburses approved loans via M-Pesa B2C using the Node SDK.

CharacterRole
Samuel KibetDevOps Engineer
Peter OtienoOperations Manager
Jane WambuiBorrower (first run)

Timeline

  1. Day 0, 14:00: Samuel writes job in TypeScript using SDK. (Job runs as Docker container on cron schedule.)
  2. Day 0, 18:00: Peter approves 23 loans during business close. (Loans state=ready_to_disburse, total KES 4.2M.)
  3. Day 1, 02:00: Cron fires. (SDK pulls 23 loans via async iterator.)
  4. Day 1, 02:00:30: SDK posts 23 disbursements with unique idempotency keys. (All 23 sent to M-Pesa B2C.)
  5. Day 1, 02:01: M-Pesa STK Push completes for Jane. (Webhook loan.disbursed fires; SMS dispatched.)
  6. Day 1, 02:03: All 23 disbursed. (Job logs success; alert if any failed.)
  7. Day 1, 06:00: Jane sees credit in her M-Pesa. (Receipt ref PBJ4S6X9DC linked to loan L-2026-09183.)

Outcome — End-to-end nightly disbursement automated in 40 lines of TypeScript. Idempotency keys make the job safely retryable on transient failure.

Reference

SDK version compatibility

SDKLatestAPI versionMin runtime
mfi-sdk (Python)1.5.0v1Python 3.10+
@bridgeerp/mfi-sdk (Node)1.4.2v1Node 18+
com.bridgeerp:mfi-sdk (Java)1.4.0v1Java 17+
github.com/bridgeerp/mfi-sdk-go1.3.0v1Go 1.21+

Common config options

OptionDefaultDescription
baseUrl(required)Tenant base URL
clientId / clientSecret(required)OAuth credentials
scopesall granted to clientSubset to request
timeout30sHTTP request timeout
maxRetries3Retry budget for 429/5xx
userAgentmfi-sdk//HTTP User-Agent
proxynoneHTTP proxy URL
loggerstdout (debug off)Structured logger

Troubleshooting

SymptomLikely causeFix
SDK throws 'token refresh failed' under load.Race condition refreshing token across many threads.Upgrade SDK to latest (token refresh now mutex-guarded).
Pagination iterator never terminates.Tenant returning malformed cursor.File a bug with reproduction; workaround: pass limit and iterate manually.
Webhook verifier rejecting valid signatures.Body parsed before passing to verifier (body must be raw bytes).Use raw request body, not parsed JSON, for HMAC computation.

See also

Was this page helpful?