Skip to main content

Safaricom M-PESA TypesScript/JavaScript SDK

This package works with Bun, Cloudflare Workers, Node.js, Deno
JSR Score
41%
Published
a month ago (0.1.1)

M-Pesa TypeScript SDK

This is a simple wrapper for Mpesa Daraja API using typescript

Installation

Via npm

npm install --save @osenco/mpesa

Or yarn

yarn add @osenco/mpesa

Usage

Terms definitions

Term Description Type
env Your API environment. Either `sandbox` or 'live' string
type Identifier type 2 for Till, 4 for Paybill number
store Store number if using a till number number
shortcode Your Buy Goods number or Paybill number
key App consumer key from Daraja string
secret App consumer secret from Daraja string
passkey Your online passkey string
username Org portal username string
password Org portal password string
validationUrl A valid secure URL that is used to validate your transaction details string
confirmationUrl A valid secure URL that is used to receive payment notifications from C2B API. string
callbackUrl A valid secure URL that is used to receive payment notifications from M-Pesa API. string
timeoutUrl This is the URL to be specified in your request that will be used by API Proxy to send notification incase the payment request is timed out while awaiting processing in the queue. string
resultsUrl This is the URL to be specified in your request that will be used by M-PESA to send notification upon processing of the payment request. string

Import what you need

import { Mpesa, useMpesa } from "@osenco/mpesa"

or

const { Mpesa, useMpesa } = require("@osenco/mpesa")

Instantiation

const mpesa = new Mpesa(
    {
        env //"sandbox",
        type //4,
        shortcode //174379,
        store //174379,
        key // Your app consumer key,
        secret // Your app consumer secret,
        username // Your M-Pesa org username,
        password // Your M-Pesa org pass,
        passkey // Your online passkey "bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919",
        validationUrl //"/lipwa/validate",
        confirmationUrl //"/lipwa/confirm",
        callbackUrl //"/lipwa/reconcile",
        timeoutUrl //"/lipwa/timeout", OPTIONAL
        resultUrl //"/lipwa/results", OPTIONAL
        billingUrl //"/lipwa/billing", OPTIONAL
    }
)

Or, individual APIs

const { stkPush, registerUrls, billManager } = useMpesa(
    {
        env //"sandbox",
        type //4,
        shortcode //174379,
        store //174379,
        key // Your app consumer key,
        secret // Your app consumer secret,
        username // Your M-Pesa org username,
        password // Your M-Pesa org pass,
        passkey // Your online passkey "bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919",
        validationUrl //"/lipwa/validate",
        confirmationUrl //"/lipwa/confirm",
        callbackUrl //"/lipwa/reconcile",
        timeoutUrl //"/lipwa/timeout", OPTIONAL
        resultUrl //"/lipwa/results", OPTIONAL
        billingUrl //"/lipwa/billing", OPTIONAL
    }
)

Send an STK push request

mpesa.stkPush(
    254705459494,
    10,
    "ACCOUNT", // You can ignore this, the code will generate a unique string
    "Transaction Description", // Optional
    "Remark" // optional
).then(({ error, data }) => {
    if (data) {
        const {
            MerchantRequestID,
            CheckoutRequestID,
            ResponseCode,
            ResponseDescription,
            CustomerMessage
        } = data
        console.log(MerchantRequestID)
    }

    if (error) {
        const { errorCode, errorMessage } = error
        console.log(errorCode, errorMessage);
    }
})

// Or use the API directly

stkPush(
    254705459494,
    10,
    "ACCOUNT", // You can ignore this, the code will generate a unique string
    "Transaction Description", // Optional
    "Remark" // optional
).then(({
    error,
    data
}) => {
    if (data) {
        const {
            MerchantRequestID,
            CheckoutRequestID,
            ResponseCode,
            ResponseDescription,
            CustomerMessage
        } = data
        console.log(MerchantRequestID)
    }

    if (error) {
        const { errorCode, errorMessage } = error
        console.log(errorCode, errorMessage);
    }
})

Or, if inside an async function

async () => {
    const { error: { errorCode, errorMessage }, data: {
        MerchantRequestID,
        CheckoutRequestID,
        ResponseCode,
        ResponseDescription,
        CustomerMessage
    }
    } = await mpesa.stkPush(
        254705459494,
        10,
        "ACCOUNT",
        "Transaction Description",
        "Remark"
    )

    console.log(MerchantRequestID)

    // TIP: Save MerchantRequestID and update when you receive the IPN
}

C2B register callback URLs

mpesa.registerUrls("Completed" | "Cancelled").then(({
    error,
    data
}) => {
    if (data) {
        const {
            ResponseCode,
            ResponseDescription
        } = data
        console.log(ResponseDescription)
    }

    if (error) {
        const { errorCode, errorMessage } = error
        console.log(errorCode, errorMessage);
    }
})

Send B2C

mpesa.sendB2C(
    phone, 
    amount, 
    "BusinessPayment" | "SalaryPayment" | "PromotionPayment", 
    "Some remark", 
    "Some occasion"
).then(({
    error,
    data
}) => {
    if (data) {
        const {
            ConversationID,
            OriginatorConversationID,
            ResponseCode,
            ResponseDescription
        } = data
        console.log(OriginatorConversationID)

        // TIP: Save `OriginatorConversationID` in the database, and use it as a key once you receive the IPN
    }

    if (error) {
        const { errorCode, errorMessage } = error
        console.log(errorCode, errorMessage);
    }
})

Send B2B

mpesa.sendB2B(
    phone, 
    amount, 
    "BusinessPayBill" | "BusinessBuyGoods" | "DisburseFundsToBusiness" | "BusinessToBusinessTransfer" | "MerchantToMerchantTransfer", 
    "Some remark", 
    "Some occasion"
).then(({
    error,
    data
}) => {
    if (data) {
        const {
            ConversationID,
            OriginatorConversationID,
            ResponseCode,
            ResponseDescription
        } = data
        console.log(OriginatorConversationID)

        // TIP: Save `OriginatorConversationID` in the database, and use it as a key for update
    }

    if (error) {
        const { errorCode, errorMessage } = error
        console.log(errorCode, errorMessage);
    }
})

Generate QR Codes

mpesa
.generateQR(100, 'Osen Concepts', 254700900499, 'AC6G9GB', 'PB')
 .then(({ error, data: { QRCode } }) => {
  if (QRCode) {
   const imgSrc = `data:image/png;base64, ${QRCode}`;
  } else {
   console.log(error);
  }
 });

Bill Manager

Onboard

const onboard = mpesa.billing()
    .onboard()
    .then(({ error, data }) => {})
    .catch((e) => {});

Send Invoice(s)

const invoice = mpesa.billing()
    .sendInvoice({})
    .then(({ error, data }) => {})
    .catch((e) => {});

const invoices = billManager()
    .sendInvoices([{}])
    .then(({ error, data }) => {})
    .catch((e) => {});

Add Package

deno add @osenco/mpesa

Import symbol

import * as mod from "@osenco/mpesa";

Add Package

npx jsr add @osenco/mpesa

Import symbol

import * as mod from "@osenco/mpesa";

Add Package

yarn dlx jsr add @osenco/mpesa

Import symbol

import * as mod from "@osenco/mpesa";

Add Package

pnpm dlx jsr add @osenco/mpesa

Import symbol

import * as mod from "@osenco/mpesa";

Add Package

bunx jsr add @osenco/mpesa

Import symbol

import * as mod from "@osenco/mpesa";