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

mpesa-nodejs-sdk-unofficial-version

v1.0.0

Published

A Node.js SDK for M-Pesa API integration

Downloads

5

Readme

M-Pesa Node.js SDK

A comprehensive Node.js SDK for integrating with the M-Pesa payment API. This library provides easy-to-use methods for all major M-Pesa operations including C2B, B2C, B2B transactions, transaction status queries, reversals, and customer name queries.

Table of Contents

Installation

npm install mpesa-nodejs-sdk

Quick Start

const Mpesa = require('mpesa-nodejs-sdk');

// Initialize the client
const mpesa = new Mpesa({
  apiKey: 'your-api-key',
  publicKey: 'your-public-key',
  baseUrl: 'https://api.sandbox.vm.co.mz', // Use sandbox for testing
  ssl: true
});

// Make a C2B transaction
async function makePayment() {
  try {
    const result = await mpesa.c2b({
      input_TransactionReference: 'T12344C',
      input_CustomerMSISDN: '258843330333',
      input_Amount: '10.00',
      input_ThirdPartyReference: Mpesa.generateThirdPartyReference(),
      input_ServiceProviderCode: '171717'
    });
    
    console.log('Transaction successful:', result.isSuccess);
    console.log('Transaction ID:', result.output_TransactionID);
  } catch (error) {
    console.error('Transaction failed:', error.message);
  }
}

makePayment();

Configuration

The SDK requires the following configuration parameters:

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | apiKey | string | Yes | Your M-Pesa API key | | publicKey | string | Yes | Your M-Pesa public key | | baseUrl | string | No | API base URL (defaults to sandbox) | | environment | string | No | API environment ( SANDBOX or PRODUCTION, defaults to SANDBOX) | | ssl | boolean | No | Enable SSL (default: true) | | origin | string | No | CORS origin (default: developer.mpesa.vm.co.mz) | | timeout | number | No | Request timeout in ms (default: 30000) |

Environment Configuration

You can specify the environment parameter in the configuration to switch between SANDBOX and PRODUCTION.

// For Sandbox environment (default)
const mpesaSandbox = new Mpesa({
  apiKey: process.env.MPESA_SANDBOX_API_KEY,
  publicKey: process.env.MPESA_SANDBOX_PUBLIC_KEY,
  environment: 'SANDBOX' // Optional, as it's the default
});

// For Production environment
const mpesaProduction = new Mpesa({
  apiKey: process.env.MPESA_PRODUCTION_API_KEY,
  publicKey: process.env.MPESA_PRODUCTION_PUBLIC_KEY,
  environment: 'PRODUCTION'
});

If the environment parameter is not provided, it defaults to SANDBOX.

API Methods

Customer to Business (C2B)

Initiate a payment from a customer to your business.

const result = await mpesa.c2b({
  input_TransactionReference: 'T12344C',
  input_CustomerMSISDN: '258843330333',
  input_Amount: '10.00',
  input_ThirdPartyReference: 'unique-ref-123',
  input_ServiceProviderCode: '171717'
});

Business to Customer (B2C)

Send money from your business to a customer.

const result = await mpesa.b2c({
  input_TransactionReference: 'T12345C',
  input_CustomerMSISDN: '258843330333',
  input_Amount: '15.50',
  input_ThirdPartyReference: 'unique-ref-124',
  input_ServiceProviderCode: '171717'
});

Business to Business (B2B)

Transfer money between business accounts.

const result = await mpesa.b2b({
  input_TransactionReference: 'T12346C',
  input_Amount: '100.00',
  input_ThirdPartyReference: 'unique-ref-125',
  input_PrimaryPartyCode: '171717',
  input_ReceiverPartyCode: '979797'
});

Query Transaction Status

Check the status of a transaction.

const result = await mpesa.queryTransactionStatus({
  input_ThirdPartyReference: 'unique-ref-123',
  input_QueryReference: '5C1400CVRO',
  input_ServiceProviderCode: '171717'
});

console.log('Status:', result.output_ResponseTransactionStatus);

Transaction Reversal

Reverse a completed transaction.

const result = await mpesa.reversal({
  input_TransactionID: '49XCDF6',
  input_SecurityCredential: 'your-security-credential',
  input_InitiatorIdentifier: 'your-initiator-id',
  input_ThirdPartyReference: 'unique-ref-126',
  input_ServiceProviderCode: '171717',
  input_ReversalAmount: '10.00' // Optional for partial reversal
});

Query Customer Masked Name

Get the masked name of a customer.

const result = await mpesa.queryCustomerMaskedName({
  input_CustomerMSISDN: '258843330333',
  input_ThirdPartyReference: 'unique-ref-127',
  input_ServiceProviderCode: '171717'
});

console.log('Customer name:', result.output_CustomerName);

Error Handling

The SDK provides comprehensive error handling with specific error types for different scenarios.

Error Types

  • MpesaError: Base error class for all M-Pesa related errors
  • MpesaAuthenticationError: Authentication and authorization errors
  • MpesaValidationError: Input validation errors
  • MpesaApiError: API response errors
  • MpesaNetworkError: Network and connectivity errors

Error Handling Example

const { MpesaError, MpesaAuthenticationError, MpesaValidationError } = require('mpesa-nodejs-sdk/lib/utils/errors');

try {
  const result = await mpesa.c2b({
    input_TransactionReference: 'T12344C',
    input_CustomerMSISDN: '258843330333',
    input_Amount: '10.00',
    input_ThirdPartyReference: 'unique-ref-123',
    input_ServiceProviderCode: '171717'
  });
} catch (error) {
  if (error instanceof MpesaAuthenticationError) {
    console.error('Authentication failed:', error.message);
    // Handle authentication error
  } else if (error instanceof MpesaValidationError) {
    console.error('Validation error:', error.message);
    console.error('Field:', error.field);
    // Handle validation error
  } else if (error instanceof MpesaError) {
    console.error('M-Pesa error:', error.message);
    console.error('Code:', error.code);
    console.error('Response:', error.response);
    // Handle other M-Pesa errors
  } else {
    console.error('Unexpected error:', error.message);
    // Handle unexpected errors
  }
}

Response Codes

The SDK automatically parses API response codes and provides human-readable descriptions:

| Code | Description | |------|-------------| | INS-0 | Request processed successfully | | INS-1 | Internal Error | | INS-2 | Invalid API Key | | INS-4 | User is not active | | INS-5 | Transaction cancelled by customer | | INS-6 | Transaction Failed | | INS-9 | Request timeout | | INS-10 | Duplicate Transaction | | INS-13 | Invalid Shortcode Used | | INS-14 | Invalid Reference Used | | INS-15 | Invalid Amount Used |

For a complete list of response codes, see the API Reference section.

Utilities

The SDK includes several utility functions to help with common operations.

Static Methods

// Generate unique references
const thirdPartyRef = Mpesa.generateThirdPartyReference(); // Returns: "A1B2C3"
const transactionRef = Mpesa.generateTransactionReference(); // Returns: "T12A34B5"

// Format and validate data
const formattedMSISDN = Mpesa.formatMSISDN('843330333'); // Returns: "258843330333"
const formattedAmount = Mpesa.formatAmount('10'); // Returns: "10.00"

// Validation
const isValidMSISDN = Mpesa.validateMSISDN('258843330333'); // Returns: true
const isValidAmount = Mpesa.validateAmount('10.50'); // Returns: true

Helper Functions

const { 
  getResponseDescription, 
  isSuccessResponse, 
  formatMSISDN, 
  generateTransactionReference 
} = require('mpesa-nodejs-sdk/lib/utils/helpers');

// Get description for response code
const description = getResponseDescription('INS-0'); // Returns: "Request processed successfully"

// Check if response indicates success
const isSuccess = isSuccessResponse('INS-0'); // Returns: true

// Format MSISDN
const msisdn = formatMSISDN('843330333'); // Returns: "258843330333"

// Generate transaction reference
const ref = generateTransactionReference(); // Returns: "A1B2C3D4"

Examples

Complete Transaction Flow

const Mpesa = require('mpesa-nodejs-sdk');

const mpesa = new Mpesa({
  apiKey: 'your-api-key',
  publicKey: 'your-public-key',
  baseUrl: 'https://api.sandbox.vm.co.mz'
});

async function completeTransactionFlow() {
  try {
    // Step 1: Initiate C2B transaction
    const thirdPartyRef = Mpesa.generateThirdPartyReference();
    
    const c2bResult = await mpesa.c2b({
      input_TransactionReference: 'ORDER-001',
      input_CustomerMSISDN: '258843330333',
      input_Amount: '25.00',
      input_ThirdPartyReference: thirdPartyRef,
      input_ServiceProviderCode: '171717'
    });
    
    if (c2bResult.isSuccess) {
      console.log('Payment initiated successfully');
      console.log('Transaction ID:', c2bResult.output_TransactionID);
      
      // Step 2: Query transaction status
      const statusResult = await mpesa.queryTransactionStatus({
        input_ThirdPartyReference: thirdPartyRef,
        input_QueryReference: c2bResult.output_TransactionID,
        input_ServiceProviderCode: '171717'
      });
      
      console.log('Transaction Status:', statusResult.output_ResponseTransactionStatus);
      
      // Step 3: If needed, reverse the transaction
      if (statusResult.output_ResponseTransactionStatus === 'Completed') {
        const reversalResult = await mpesa.reversal({
          input_TransactionID: c2bResult.output_TransactionID,
          input_SecurityCredential: 'your-security-credential',
          input_InitiatorIdentifier: 'your-initiator-id',
          input_ThirdPartyReference: Mpesa.generateThirdPartyReference(),
          input_ServiceProviderCode: '171717'
        });
        
        if (reversalResult.isSuccess) {
          console.log('Transaction reversed successfully');
        }
      }
    }
  } catch (error) {
    console.error('Transaction flow failed:', error.message);
  }
}

completeTransactionFlow();

Batch Processing

async function processBatchPayments(payments) {
  const results = [];
  
  for (const payment of payments) {
    try {
      const result = await mpesa.b2c({
        input_TransactionReference: payment.reference,
        input_CustomerMSISDN: payment.msisdn,
        input_Amount: payment.amount,
        input_ThirdPartyReference: Mpesa.generateThirdPartyReference(),
        input_ServiceProviderCode: '171717'
      });
      
      results.push({
        reference: payment.reference,
        success: result.isSuccess,
        transactionId: result.output_TransactionID,
        error: null
      });
      
      // Add delay between requests to avoid rate limiting
      await new Promise(resolve => setTimeout(resolve, 1000));
      
    } catch (error) {
      results.push({
        reference: payment.reference,
        success: false,
        transactionId: null,
        error: error.message
      });
    }
  }
  
  return results;
}

// Usage
const payments = [
  { reference: 'PAY-001', msisdn: '258843330333', amount: '10.00' },
  { reference: 'PAY-002', msisdn: '258843330334', amount: '15.00' },
  { reference: 'PAY-003', msisdn: '258843330335', amount: '20.00' }
];

processBatchPayments(payments).then(results => {
  console.log('Batch processing results:', results);
});

API Reference

Constructor

new Mpesa(config)

Creates a new M-Pesa client instance.

Parameters:

  • config (Object): Configuration object
    • apiKey (string): Your M-Pesa API key
    • publicKey (string): Your M-Pesa public key
    • baseUrl (string, optional): API base URL (default: sandbox)
    • ssl (boolean, optional): Enable SSL (default: true)
    • origin (string, optional): CORS origin
    • timeout (number, optional): Request timeout in milliseconds

Instance Methods

mpesa.c2b(params)

Initiates a Customer to Business transaction.

Parameters:

  • input_TransactionReference (string): Transaction reference
  • input_CustomerMSISDN (string): Customer mobile number (format: 258XXXXXXXXX)
  • input_Amount (string): Transaction amount
  • input_ThirdPartyReference (string): Unique third party reference
  • input_ServiceProviderCode (string): Service provider code

Returns: Promise - API response with transaction details

mpesa.b2c(params)

Initiates a Business to Customer transaction.

Parameters:

  • input_TransactionReference (string): Transaction reference
  • input_CustomerMSISDN (string): Customer mobile number
  • input_Amount (string): Transaction amount
  • input_ThirdPartyReference (string): Unique third party reference
  • input_ServiceProviderCode (string): Service provider code

Returns: Promise - API response with transaction details

mpesa.b2b(params)

Initiates a Business to Business transaction.

Parameters:

  • input_TransactionReference (string): Transaction reference
  • input_Amount (string): Transaction amount
  • input_ThirdPartyReference (string): Unique third party reference
  • input_PrimaryPartyCode (string): Primary party (sender) code
  • input_ReceiverPartyCode (string): Receiver party code

Returns: Promise - API response with transaction details

mpesa.queryTransactionStatus(params)

Queries the status of a transaction.

Parameters:

  • input_ThirdPartyReference (string): Third party reference
  • input_QueryReference (string): Transaction ID or Conversation ID
  • input_ServiceProviderCode (string): Service provider code

Returns: Promise - API response with transaction status

mpesa.reversal(params)

Reverses a completed transaction.

Parameters:

  • input_TransactionID (string): Transaction ID to reverse
  • input_SecurityCredential (string): Security credential
  • input_InitiatorIdentifier (string): Initiator identifier
  • input_ThirdPartyReference (string): Unique third party reference
  • input_ServiceProviderCode (string): Service provider code
  • input_ReversalAmount (string, optional): Amount to reverse (partial reversal)

Returns: Promise - API response with reversal details

mpesa.queryCustomerMaskedName(params)

Queries the masked name of a customer.

Parameters:

  • input_CustomerMSISDN (string): Customer mobile number
  • input_ThirdPartyReference (string): Unique third party reference
  • input_ServiceProviderCode (string): Service provider code

Returns: Promise - API response with customer name

Static Methods

Mpesa.generateThirdPartyReference()

Generates a unique third party reference.

Returns: string - 6-character uppercase alphanumeric string

Mpesa.generateTransactionReference()

Generates a unique transaction reference.

Returns: string - 8-character uppercase alphanumeric string

Mpesa.formatMSISDN(msisdn)

Formats an MSISDN to the standard format.

Parameters:

  • msisdn (string): Mobile number to format

Returns: string - Formatted MSISDN (258XXXXXXXXX)

Mpesa.formatAmount(amount)

Formats an amount to the standard format.

Parameters:

  • amount (string|number): Amount to format

Returns: string - Formatted amount with 2 decimal places

Mpesa.validateMSISDN(msisdn)

Validates an MSISDN format.

Parameters:

  • msisdn (string): Mobile number to validate

Returns: boolean - True if valid, false otherwise

Mpesa.validateAmount(amount)

Validates an amount format.

Parameters:

  • amount (string|number): Amount to validate

Returns: boolean - True if valid, false otherwise

Response Object Structure

All API methods return a response object with the following structure:

{
  // Original API response fields
  output_ConversationID: "AG_20180206_00005e7dccc6da08efa8",
  output_TransactionID: "4XDF12345",
  output_ResponseDesc: "Request processed successfully",
  output_ResponseCode: "INS-0",
  output_ThirdPartyReference: "11114",
  
  // Additional fields added by SDK
  isSuccess: true,
  responseDescription: "Request processed successfully"
}

Complete Response Codes Reference

| HTTP Status | Code | Description | |-------------|------|-------------| | 200/201 | INS-0 | Request processed successfully | | 500 | INS-1 | Internal Error | | 401 | INS-2 | Invalid API Key | | 401 | INS-4 | User is not active | | 401 | INS-5 | Transaction cancelled by customer | | 401 | INS-6 | Transaction Failed | | 408 | INS-9 | Request timeout | | 409 | INS-10 | Duplicate Transaction | | 400 | INS-13 | Invalid Shortcode Used | | 400 | INS-14 | Invalid Reference Used | | 400 | INS-15 | Invalid Amount Used | | 503 | INS-16 | Unable to handle the request due to a temporary overloading | | 400 | INS-17 | Invalid Transaction Reference. Length Should Be Between 1 and 20. | | 400 | INS-18 | Invalid TransactionID Used | | 400 | INS-19 | Invalid ThirdPartyReference Used | | 400 | INS-20 | Not All Parameters Provided. Please try again. | | 400 | INS-21 | Parameter validations failed. Please try again. | | 400 | INS-22 | Invalid Operation Type | | 400 | INS-23 | Unknown Status. Contact M-Pesa Support | | 400 | INS-24 | Invalid InitiatorIdentifier Used | | 400 | INS-25 | Invalid SecurityCredential Used | | 400 | INS-26 | Not authorized | | 400 | INS-993 | Direct Debit Missing | | 400 | INS-994 | Direct Debit Already Exists | | 400 | INS-995 | Customer's Profile Has Problems | | 400 | INS-996 | Customer Account Status Not Active | | 400 | INS-997 | Linking Transaction Not Found | | 400 | INS-998 | Invalid Market | | 400 | INS-2001 | Initiator authentication error. | | 400 | INS-2002 | Receiver invalid. | | 422 | INS-2006 | Insufficient balance | | 400 | INS-2051 | MSISDN invalid. | | 400 | INS-2057 | Language code invalid. |

Transaction Status Values

| Status | Description | |--------|-------------| | Cancelled | Transaction was cancelled | | Completed | Transaction completed successfully | | Expired | Transaction expired | | N/A | Status not available |

Best Practices

Security

  1. Never expose credentials in client-side code

    // ❌ Don't do this
    const mpesa = new Mpesa({
      apiKey: 'your-api-key-here', // Exposed in client code
      publicKey: 'your-public-key-here'
    });
       
    // ✅ Do this instead
    const mpesa = new Mpesa({
      apiKey: process.env.MPESA_API_KEY,
      publicKey: process.env.MPESA_PUBLIC_KEY
    });
  2. Use environment variables for configuration

    # .env file
    MPESA_API_KEY=your-api-key
    MPESA_PUBLIC_KEY=your-public-key
    MPESA_BASE_URL=https://api.sandbox.vm.co.mz
  3. Validate input data before making API calls

    if (!Mpesa.validateMSISDN(customerMSISDN)) {
      throw new Error('Invalid MSISDN format');
    }
       
    if (!Mpesa.validateAmount(amount)) {
      throw new Error('Invalid amount');
    }

Error Handling

  1. Always wrap API calls in try-catch blocks

    try {
      const result = await mpesa.c2b(params);
      // Handle success
    } catch (error) {
      // Handle error
      console.error('Transaction failed:', error.message);
    }
  2. Implement retry logic for network errors

    async function retryTransaction(params, maxRetries = 3) {
      for (let i = 0; i < maxRetries; i++) {
        try {
          return await mpesa.c2b(params);
        } catch (error) {
          if (error instanceof MpesaNetworkError && i < maxRetries - 1) {
            await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
            continue;
          }
          throw error;
        }
      }
    }

Performance

  1. Reuse client instances

    // ✅ Create once, use multiple times
    const mpesa = new Mpesa(config);
       
    // Use the same instance for multiple transactions
    await mpesa.c2b(params1);
    await mpesa.b2c(params2);
  2. Implement rate limiting for batch operations

    async function processBatch(items, delayMs = 1000) {
      for (const item of items) {
        await processItem(item);
        await new Promise(resolve => setTimeout(resolve, delayMs));
      }
    }
  3. Use connection pooling for high-volume applications

    const mpesa = new Mpesa({
      ...config,
      timeout: 30000, // Adjust timeout based on your needs
    });

Contributing

We welcome contributions to the M-Pesa Node.js SDK! Please follow these guidelines:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

# Clone the repository
git clone https://github.com/your-username/mpesa-nodejs-sdk.git
cd mpesa-nodejs-sdk

# Install dependencies
npm install

# Run tests
npm test

# Run examples
node examples.js

Testing

Before submitting a pull request, ensure all tests pass:

npm test

License

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

Support

For support and questions:

Changelog

Version 1.0.0

  • Initial release
  • Support for all major M-Pesa API operations
  • Comprehensive error handling
  • Utility functions for common operations
  • Full TypeScript support (coming soon)

Disclaimer: This SDK is not officially endorsed by Vodacom or M-Pesa. Use at your own risk and ensure compliance with M-Pesa's terms of service.