umojasdk
v0.1.1
Published
One SDK. Every African payment. TypeScript SDK for M-Pesa, Airtel Money, and more.
Maintainers
Readme
umojasdk
One SDK. Every African payment.
UmojaSDK is the unified TypeScript/Node.js SDK for African mobile money integrations — M-Pesa (Safaricom Daraja 3.0), Airtel Money, and more.
Built by Synapse Softwares.
Installation
npm install umojasdkQuickstart — M-Pesa STK Push
import { UmojaMpesa } from 'umojasdk';
const mpesa = new UmojaMpesa({
consumerKey: process.env.MPESA_CONSUMER_KEY!,
consumerSecret: process.env.MPESA_CONSUMER_SECRET!,
shortcode: process.env.MPESA_SHORTCODE!,
passkey: process.env.MPESA_PASSKEY!,
callbackUrl: 'https://yourapp.com/api/mpesa/callback',
env: 'sandbox'
});
// Trigger STK Push — prompts customer on their phone
const result = await mpesa.stkPush({
phone: '0712345678', // accepts 07XX, +2547XX, 2547XX — auto-normalized
amount: 1500,
reference: 'ORDER-001'
});
console.log(result.checkoutRequestId);// Parse incoming Daraja callback — one line
const payment = mpesa.parseCallback(req.body);
if (payment.success) {
console.log(payment.mpesaReceiptNumber); // e.g. "NLJ7RT61SV"
console.log(payment.amount); // e.g. 1500
}
// CRITICAL: Always return 200 to stop Daraja retries
res.json({ ResultCode: 0, ResultDesc: 'Accepted' });Quickstart — Airtel Money
import { UmojaAirtel } from 'umojasdk';
const airtel = new UmojaAirtel({
clientId: process.env.AIRTEL_CLIENT_ID!,
clientSecret: process.env.AIRTEL_CLIENT_SECRET!,
env: 'sandbox'
});
const result = await airtel.requestToPay({
phone: '0733123456',
amount: 500,
reference: 'ORDER-002'
});Features
| Feature | Status | |---------|--------| | STK Push (Lipa Na M-Pesa) | ✓ | | STK Push status query | ✓ | | C2B URL registration & callbacks | ✓ | | B2C disbursements | ✓ | | B2B transfers | ✓ | | Transaction status query | ✓ | | Transaction reversal | ✓ | | SIM Swap detection (Daraja 3.0) | ✓ | | Tax remittance to KRA (Daraja 3.0) | ✓ | | Airtel Money collections | ✓ | | Airtel Money disbursements | ✓ | | Webhook parsing | ✓ | | Phone number normalization | ✓ | | Automatic token refresh | ✓ | | Exponential backoff retry | ✓ | | Typed errors | ✓ |
Error Handling
import { UmojaAuthError, UmojaValidationError, UmojaApiError } from 'umojasdk';
try {
const result = await mpesa.stkPush({ phone, amount, reference });
} catch (err) {
if (err instanceof UmojaAuthError) { /* bad credentials */ }
else if (err instanceof UmojaValidationError) { /* bad input */ }
else if (err instanceof UmojaApiError) { /* Daraja/Airtel error — check err.raw */ }
}SIM Swap Fraud Prevention (Daraja 3.0)
async function securePayment(phone: string, amount: number) {
if (amount >= 10_000) {
const check = await mpesa.checkSimSwap({ phone, daysToCheck: 30 });
if (check.swapped) {
return { blocked: true, reason: 'Additional verification required.' };
}
}
return mpesa.stkPush({ phone, amount, reference: 'ORDER-001' });
}Multi-Carrier Routing
import { UmojaMpesa, UmojaAirtel, normalizeKenyanPhone } from 'umojasdk';
async function pay(phone: string, amount: number, orderId: string) {
const prefix = normalizeKenyanPhone(phone).slice(3, 6);
const safaricomPrefixes = ['712', '722', '700', '711', '710'];
if (safaricomPrefixes.includes(prefix)) {
return mpesa.stkPush({ phone, amount, reference: orderId });
}
return airtel.requestToPay({ phone, amount, reference: orderId });
}Environment Variables
MPESA_CONSUMER_KEY=
MPESA_CONSUMER_SECRET=
MPESA_SHORTCODE=174379
MPESA_PASSKEY=
MPESA_CALLBACK_URL=
MPESA_ENV=sandbox # "sandbox" | "production"
AIRTEL_CLIENT_ID=
AIRTEL_CLIENT_SECRET=
AIRTEL_ENV=sandboxRelated
- Python SDK:
pip install umojasdk - CLI:
npx @umojasdk/cli init - Docs: umojasdk.dev
License
MIT — github.com/Knelso/Umoja_SDK
Built with precision in Nairobi, Kenya. For Africa, by Africa.
