npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mpesalib

v3.0.0

Published

A robust Node.js library for Safaricom's Daraja API with complete TypeScript support and modern async/await patterns

Readme

M-Pesa Daraja API - Node.js Library

npm version TypeScript License: MIT Build Status Coverage Status

A robust, modern Node.js library for integrating with Safaricom's M-Pesa Daraja API. Built with TypeScript, comprehensive error handling, and extensive testing.

Features

  • 🚀 Modern TypeScript - Full TypeScript support with comprehensive type definitions
  • 🔒 Secure - Built-in security credential generation and token management
  • 🛡️ Error Handling - Comprehensive error handling and validation
  • 📝 Well Documented - Extensive documentation and examples
  • 🧪 Thoroughly Tested - 95%+ test coverage
  • 🔄 Retry Logic - Built-in retry mechanism for network failures
  • 📱 Phone Number Formatting - Automatic phone number formatting and validation
  • 🌍 Environment Support - Support for both sandbox and production environments
  • 📊 Callback Handling - Built-in utilities for handling M-Pesa callbacks

Supported APIs

  • STK Push (Lipa Na M-Pesa Online)
  • STK Push Query (Check payment status)
  • C2B Register URLs (Customer to Business)
  • C2B Simulate (Test C2B payments)
  • B2C Payment (Business to Customer)
  • B2B Payment (Business to Business)
  • Account Balance (Check account balance)
  • Transaction Status (Query transaction status)
  • Transaction Reversal (Reverse transactions)

Installation

npm install mpesalib

⚠️ Upgrading from v1.x? This is a complete rewrite with breaking changes. See the Migration Guide for detailed upgrade instructions.

Quick Start

1. Configuration

Create a .env file based on .env.example:

MPESA_CONSUMER_KEY=your_consumer_key
MPESA_CONSUMER_SECRET=your_consumer_secret
MPESA_ENVIRONMENT=sandbox
MPESA_SHORT_CODE=174379
MPESA_PASSKEY=your_passkey

2. Basic Usage

import { Mpesa } from 'mpesalib';

// Initialize from environment variables
const mpesa = Mpesa.fromEnv();

// Or initialize with config object
const mpesa = new Mpesa({
  consumerKey: 'your_consumer_key',
  consumerSecret: 'your_consumer_secret',
  environment: 'sandbox',
  shortCode: '174379',
  passkey: 'your_passkey',
});

// STK Push (Customer Payment)
const response = await mpesa.paybillPayment(
  1000,                           // Amount
  '254712345678',                 // Phone number
  'INV001',                       // Account reference
  'Payment for services',         // Description
  'https://yourdomain.com/callback' // Callback URL
);

console.log(response);

API Reference

STK Push (Lipa Na M-Pesa Online)

Initiate a payment request to customer's phone:

// Paybill payment
const response = await mpesa.paybillPayment(
  amount,
  phoneNumber,
  accountReference,
  description,
  callbackURL
);

// Buy goods payment
const response = await mpesa.buyGoodsPayment(
  amount,
  phoneNumber,
  accountReference,
  description,
  callbackURL
);

// Custom STK Push
const response = await mpesa.stkPush({
  BusinessShortCode: '174379',
  TransactionType: 'CustomerPayBillOnline',
  Amount: 1000,
  PartyA: '254712345678',
  PartyB: '174379',
  PhoneNumber: '254712345678',
  CallBackURL: 'https://yourdomain.com/callback',
  AccountReference: 'TEST001',
  TransactionDesc: 'Test payment',
});

STK Push Query

Check the status of an STK Push request:

const status = await mpesa.stkPushQuery('ws_CO_12345678');

C2B (Customer to Business)

Register callback URLs and simulate C2B transactions:

// Register URLs
await mpesa.registerC2BUrls({
  ShortCode: '600000',
  ResponseType: 'Completed',
  ConfirmationURL: 'https://yourdomain.com/confirmation',
  ValidationURL: 'https://yourdomain.com/validation',
});

// Simulate C2B payment
await mpesa.simulateC2B({
  ShortCode: '600000',
  CommandID: 'CustomerPayBillOnline',
  Amount: 1000,
  Msisdn: '254712345678',
  BillRefNumber: 'INV001',
});

B2C (Business to Customer)

Send money to customers:

// Business payment
await mpesa.businessPayment(
  5000,
  '254712345678',
  'Business payment',
  'https://yourdomain.com/timeout',
  'https://yourdomain.com/result'
);

// Salary payment
await mpesa.salaryPayment(
  50000,
  '254712345678',
  'Monthly salary',
  'https://yourdomain.com/timeout',
  'https://yourdomain.com/result'
);

// Custom B2C
await mpesa.b2cPayment({
  InitiatorName: 'testapi',
  SecurityCredential: 'credential',
  CommandID: 'BusinessPayment',
  Amount: 1000,
  PartyA: '600000',
  PartyB: '254712345678',
  Remarks: 'Payment',
  QueueTimeOutURL: 'https://yourdomain.com/timeout',
  ResultURL: 'https://yourdomain.com/result',
});

B2B (Business to Business)

Transfer money between businesses:

await mpesa.b2bPayment({
  InitiatorName: 'testapi',
  SecurityCredential: 'credential',
  CommandID: 'BusinessPayBill',
  Amount: 1000,
  PartyA: '600000',
  PartyB: '600001',
  RecieverIdentifierType: 4,
  Remarks: 'B2B Payment',
  QueueTimeOutURL: 'https://yourdomain.com/timeout',
  ResultURL: 'https://yourdomain.com/result',
  AccountReference: 'TEST001',
});

Account Balance

Check account balance:

await mpesa.getAccountBalance({
  InitiatorName: 'testapi',
  SecurityCredential: 'credential',
  CommandID: 'AccountBalance',
  PartyA: '600000',
  IdentifierType: '4',
  Remarks: 'Balance inquiry',
  QueueTimeOutURL: 'https://yourdomain.com/timeout',
  ResultURL: 'https://yourdomain.com/result',
});

Transaction Status

Query transaction status:

await mpesa.getTransactionStatus({
  InitiatorName: 'testapi',
  SecurityCredential: 'credential',
  CommandID: 'TransactionStatusQuery',
  TransactionID: 'OEI2AK4Q16',
  PartyA: '600000',
  IdentifierType: '4',
  ResultURL: 'https://yourdomain.com/result',
  QueueTimeOutURL: 'https://yourdomain.com/timeout',
  Remarks: 'Status query',
});

Transaction Reversal

Reverse a transaction:

await mpesa.reverseTransaction({
  InitiatorName: 'testapi',
  SecurityCredential: 'credential',
  CommandID: 'TransactionReversal',
  TransactionID: 'OEI2AK4Q16',
  Amount: 1000,
  ReceiverParty: '600000',
  RecieverIdentifierType: '4',
  ResultURL: 'https://yourdomain.com/result',
  QueueTimeOutURL: 'https://yourdomain.com/timeout',
  Remarks: 'Reversal',
});

Callback Handling

Handle M-Pesa callbacks in your Express.js application:

import express from 'express';

const app = express();
app.use(express.json());

// STK Push callback
app.post('/mpesa/stkpush/callback', (req, res) => {
  const callbackData = req.body;
  
  if (callbackData.Body?.stkCallback?.ResultCode === 0) {
    console.log('Payment successful!');
    // Update your database
  } else {
    console.log('Payment failed:', callbackData.Body.stkCallback.ResultDesc);
  }
  
  res.status(200).json({ status: 'OK' });
});

// B2C result callback
app.post('/mpesa/b2c/result', (req, res) => {
  const result = req.body.Result;
  
  if (result.ResultCode === 0) {
    console.log('B2C payment successful:', result.TransactionID);
  } else {
    console.log('B2C payment failed:', result.ResultDesc);
  }
  
  res.status(200).json({ status: 'OK' });
});

Utilities

The library includes helpful utilities:

import { MpesaUtils } from 'mpesalib';

// Format phone numbers
const formatted = MpesaUtils.formatPhoneNumber('0712345678');
// Returns: '254712345678'

// Generate timestamp
const timestamp = MpesaUtils.generateTimestamp();
// Returns: '20231201120000'

// Generate password for STK Push
const password = MpesaUtils.generatePassword(
  shortCode,
  passkey,
  timestamp
);

// Generate security credential
const credential = MpesaUtils.generateSecurityCredential(
  initiatorPassword,
  certificatePath
);

// Retry failed operations
const result = await MpesaUtils.retry(
  async () => mpesa.stkPush(request),
  3, // max retries
  1000 // delay in ms
);

Error Handling

The library provides comprehensive error handling:

try {
  const response = await mpesa.stkPush(request);
  console.log('Success:', response);
} catch (error) {
  if (error.status === 401) {
    console.error('Authentication failed');
  } else if (error.status === 400) {
    console.error('Bad request:', error.data);
  } else {
    console.error('Network error:', error.message);
  }
}

Environment Configuration

Required Environment Variables

MPESA_CONSUMER_KEY=your_consumer_key
MPESA_CONSUMER_SECRET=your_consumer_secret
MPESA_ENVIRONMENT=sandbox|production
MPESA_SHORT_CODE=your_shortcode

Optional Environment Variables

MPESA_INITIATOR_NAME=your_initiator_name
MPESA_SECURITY_CREDENTIAL=your_security_credential
MPESA_CERTIFICATE_PATH=./path/to/certificate.cer
MPESA_PASSKEY=your_passkey

Getting Started with Daraja API

1. Create Daraja Account

  1. Visit Daraja Portal
  2. Create an account and verify your email
  3. Login to the portal

2. Create an App

  1. Go to "My Apps" section
  2. Click "Add a new app"
  3. Fill in app details:
    • App Name: Your application name
    • Description: Brief description of your app
    • Select APIs: Choose the APIs you need (STK Push, C2B, B2C, etc.)

3. Get Credentials

After creating the app, you'll get:

  • Consumer Key: Used for authentication
  • Consumer Secret: Used for authentication

4. Test Credentials (Sandbox)

For sandbox testing, use these test credentials:

  • Short Code: 174379
  • Test MSISDN: 254708374149
  • Passkey: Get from Daraja portal

5. Production Setup

For production:

  1. Request production access from Safaricom
  2. Get production credentials
  3. Update your configuration to use production environment

Testing

Run the test suite:

npm test

Run tests with coverage:

npm run test:coverage

Run tests in watch mode:

npm run test:watch

Contributing

  1. Fork the repository
  2. Create your feature branch: git checkout -b feature/amazing-feature
  3. Make your changes and add tests
  4. Ensure tests pass: npm test
  5. Commit your changes: git commit -m 'Add amazing feature'
  6. Push to the branch: git push origin feature/amazing-feature
  7. Submit a pull request

Changelog

v2.0.0 (Latest)

  • ✨ Complete TypeScript rewrite
  • ✨ Modern async/await API
  • ✨ Comprehensive error handling
  • ✨ Built-in retry mechanism
  • ✨ Phone number formatting utilities
  • ✨ 95%+ test coverage
  • ✨ Updated Daraja API endpoints
  • ✨ Environment variable support
  • ✨ Callback handling utilities

v0.0.2 (Legacy)

  • Basic JavaScript implementation
  • Limited error handling
  • No TypeScript support

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

Acknowledgments

  • Safaricom for providing the Daraja API
  • M-Pesa for the mobile payment platform
  • All contributors who have helped improve this library

Related Projects


Made with ❤️ by John Simiyu