Skip to content

safaricom/mpesa-node-library

Repository files navigation

Node.js M-Pesa API

M-Pesa Library for Node.js using REST API

Node Mpesa Rest API

JavaScript Standard Style Build Status Made in Africa Known Vulnerabilities

Prerequisites

  1. Node v6+, 8+ recommended.
  2. Yarn* (optional) You can still use npm
  3. ES6 knowledge

Installation

Use npm/yarn:

npm i mpesa-node

Pre-Usage

Please make sure you have read the documentation on Daraja before continuing.

You need the following before getting to use this library:

  1. Consumer Key and Consume Secret
  2. Test Credentials (Optional only for sandbox)

Getting Started

This library is extremely modular, meaning you can create more than one Mpesa instance

const Mpesa = require('mpesa-node')
const mpesaApi = new Mpesa({ consumerKey: '<your consumer key>', consumerSecret: '<your consumer secret>' })
// another instance
// const instance = new Mpesa({ consumerKey: 'test', consumerSecret: 'test', environment: 'production' })
mpesaApi
    .c2bSimulate(
        254708374149,
        500,
        'h6dk0Ue2'
    )
    .then((result) => {
        //do something
    })
    .catch((err) => {
        // retry?
    })

While working with the Mpesa Class, you only need two key-value items, ie: consumerKey and consumerSecret. Nonetheless, prefilling some things means you dont have to re-enter them again. A complete config object looks like this

new Mpesa({
    consumerKey: '<your consumer key>',
    consumerSecret: '<your consumer secret>',
    environment: 'sandbox',
    shortCode: '600111',
    initiatorName: 'Test Initiator',
    lipaNaMpesaShortCode: 123456,
    lipaNaMpesaShortPass: '<some key here>',
    securityCredential: '<credential here>',
    certPath: path.resolve('keys/myKey.cert')
})

API

Please note that this library is in active development, use in production with caution.

Current API:

const mpesaApi = new Mpesa({ consumerKey: '<your consumer key>', consumerSecret: '<your consumer secret>' })
const {
  accountBalance,
  b2b,
  b2c,
  c2bRegister,
  c2bSimulate,
  lipaNaMpesaOnline,
  lipaNaMpesaQuery,
  reversal,
  transactionStatus
} = mpesaApi

Ofcourse you dont need to import all methods, you can import the only ones you need.

All methods return a <Promise>, hence you can use .then or await. All calls are done by Axios, so for the response structure check Axios documentation.

Methods

B2C Request

This initiates a business to customer transactions from a company (shortcode) to end users (mobile numbers) of their services.

/*
 * b2c(senderParty, receiverParty, amount, queueUrl, resultUrl, commandId = 'BusinessPayment', initiatorName = null, remarks = 'B2C Payment', occasion = null)
 * Example:
*/
const { shortCode } = mpesaApi.configs
const testMSISDN = 254708374149
await mpesaApi.b2c(shortCode, testMSISDN, 100, URL + '/b2c/timeout', URL + '/b2c/success')

B2B Request

This initiates a business to business transaction between one company to another.

/*
 * b2c(senderParty, receiverParty, amount, queueUrl, resultUrl, senderType = 4, receiverType = 4, initiator = null, commandId = 'BusinessToBusinessTransfer', accountRef = null, remarks = 'B2B Request')
 * Example:
*/
const { shortCode } = mpesaApi.configs
const testShortcode2 = 600000
await mpesaApi.b2b(shortCode, testShortcode2, 100, URL + '/b2b/timeout', URL + '/b2b/success')

C2B Register

This initiates a C2B confirmation and validation registration for a company's URLs

/*
 * c2bRegister(confirmationUrl, validationUrl, shortCode = null, responseType = 'Completed')
 * Example:
 */

await mpesaApi.c2bRegister(URL + '/c2b/validation', URL + '/c2b/success')

C2B Simulate

This initiates a C2B transaction between an end-user and a company (paybill or till number)

/*
 * c2bSimulate(msisdn, amount, billRefNumber, commandId = 'CustomerPayBillOnline', shortCode = null)
 * Example:
 */
const testMSISDN = 254708374149
await mPesa.c2bSimulate(testMSISDN, 100, Math.random().toString(35).substr(2, 7))

M-Pesa Express Request - Lipa Na M-Pesa Online Payment API

This initiates a Lipa Na M-Pesa Online Payment transaction using STK Push.

/*
 * lipaNaMpesaOnline(senderMsisdn, amount, callbackUrl, accountRef, transactionDesc = 'Lipa na mpesa online', transactionType = 'CustomerPayBillOnline', shortCode = null, passKey = null)
 * Example:
 */
 const testMSISDN = 254708374149
 const amount = 100
 const accountRef = Math.random().toString(35).substr(2, 7)
await mpesaApi.lipaNaMpesaOnline(testMSISDN, amount, URL + '/lipanampesa/success', accountRef)

M-Pesa Express Query Request - Lipa Na M-Pesa Query Request API

This API checks the status of a Lipa Na M-Pesa Online Payment transaction

/*
 * lipaNaMpesaQuery(checkoutRequestId, shortCode = null, passKey = null)
 * Example:
 */
const checkoutRequestId ='ws_co_123456789'
await mpesaApi.lipaNaMpesaQuery(checkoutRequestId)

Reversal Request

This initiates an M-Pesa transaction reversal on B2B, B2C or C2B API

/*
 * reversal(transactionId, amount, queueUrl, resultUrl, shortCode = null, remarks = 'Reversal', occasion = 'Reversal', initiator = null, receiverIdType = '11', commandId = 'TransactionReversal')
 * Example:
 */
await mpesaApi.reversal('LKXXXX1234', 100, URL + '/reversal/timeout', URL + '/reversal/success')

Transaction Status Request

This API is used to check the status of B2B, B2C and C2B transactions

/*
 * transactionStatus(transactionId, receiverParty, idType, queueUrl, resultUrl, remarks = 'TransactionReversal', occasion = 'TransactionReversal', initiator = null, commandId = 'TransactionStatusQuery')
 * Example:
 */
await mpesaApi.transactionStatus('LKXXXX1234', shortCode, 4, URL + '/transactionstatus/timeout', URL + '/transactionstatus/success')

Account Balance Request

This initiates a request for the account balance of a shortcode

/*
 * accountBalance(shortCode, idType, queueUrl, resultUrl, remarks = 'Checking account balance', initiator = null, commandId = 'AccountBalance')
 * Example:
 */
const { shortCode } = mpesaApi.configs
await mpesaApi.accountBalance(shortCode, 4, URL + '/accountbalance/timeout', URL + '/accountbalance/success')

Testing

Testing needs you to clone this repo.

The command below runs both integration and unit test.

Integration tests launch a ngrok instance and await callbacks (you will need an active internet connection for this).

To run each separately, check package.json for the commands.

npm test

Going Live/Production

You will need to first click on "Going Live" on Daraja

The only thing you need to tweek in this Libs config is environment:

new Mpesa({
    consumerKey: '<your consumer key>',
    consumerSecret: '<your consumer secret>',
    environment: 'production', //<------
    .....
    })

Pending Stuff

  • E2E Integration Tests
  • Deploy to Npm
  • Reduce number of args
  • Detailed Documentation
  • Enumify
  • Validators for MSISDN and other expected inputs
  • More detailed Unit tests
  • Handle all Promises

Contributing

  1. Create your feature branch: git checkout -b my-new-feature
  2. Commit your changes: git commit -m 'Add some feature'
  3. Push to the branch: git push origin my-new-feature
  4. Submit a pull request :D

Credits

| Contributor |
| DGatere |
| geofmureithi |

License

MIT