M-Pesa Daraja API STK Push Callback Not Triggering in Node.js Application

36 Views Asked by At

I am currently working on integrating the M-Pesa Daraja API into my Node.js application to initiate an STK push for mobile payments. The STK push itself is working fine; however, I am encountering issues with the callback functionality.

Here is a simplified version of my code for initiating the STK push:

const express = require('express');
const axios = require('axios');

const app = express();
require("dotenv").config();
const cors = require('cors');

app.listen(process.env.PORT, () => {
    console.log(`Server is running on port ${process.env.PORT}`);
});

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.use(cors());

app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(500).send('Something went wrong!');
});


app.get('/', (req, res) => {
    res.send('Hello World');
});

// app.get('/token', async (req, res) => {
//     generateToken();
// });


const generateToken = async (req, res, next) => {
    const auth = new Buffer.from(`${process.env.SAFARICOM_CONSUMER_KEY}:${process.env.SAFARICOM_CONSUMER_SECRET}`).toString('base64');

    await axios.get("https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials", {
        headers: {
            authorization: `Basic ${auth}`
        },
    }
    ).then((response) => {
        // console.log(data.data.access_token);
        token = response.data.access_token;
        next();
    }).catch((err) => {
        console.log(err);
    })
}

app.post ("/stk", generateToken, async(req, res) => {
    const phone = req.body.phone;
    const amount = req.body.amount;


    const date = new Date();

    const timestamp = 
    date.getFullYear().toString() +
    ("0" + (date.getMonth() + 1)).slice(-2) +
    ("0" + date.getDate()).slice(-2) +
    ("0" + date.getHours()).slice(-2) +
    ("0" + date.getMinutes()).slice(-2) +
    ("0" + date.getSeconds()).slice(-2);

    const password = new Buffer.from(process.env.BUSINESS_SHORT_CODE + process.env.PASS_KEY + timestamp).toString('base64');


    await axios.post (
        "https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest",
        {
            BusinessShortCode: process.env.BUSINESS_SHORT_CODE,
            Password: password,
            Timestamp: timestamp,
            TransactionType: "CustomerPayBillOnline",
            Amount: amount,
            PartyA: phone, // Use the tenant's phone number here
            PartyB: process.env.BUSINESS_SHORT_CODE,
            PhoneNumber: phone,
            CallBackURL: 'https://e3a9-41-80-113-159.ngrok-free.app/callback',
            AccountReference: "Moja Nexus",
            TransactionDesc: "Paid online"
        },
        {
            headers: {
                Authorization: `Bearer ${token}`,
            },
        }
    ).then ((data) => {
        res.status(200).json(data.data);
    }).catch((err) => {
        console.log(err.message);
    })
})

app.post('/callback', (req, res) => {
    const callbackData = req.body;
  
    // Log the callback data to the console
    console.log(callbackData);
  
    // Send a response back to the M-Pesa
    res.json({ status: 'success' });
  });

The STK push is successfully initiated, but when the payment is completed, the callback URL specified in the request does not seem to be triggered. I have verified that the callback URL is correct and accessible.

I have also checked the logs on my server, and there are no incoming requests hitting the callback URL endpoint when a payment is completed.

Could someone please guide me on how to troubleshoot and resolve this issue with the M-Pesa Daraja API callback not working? Are there any specific configurations or additional steps I need to take to ensure that the callback functionality functions as expected?

Any help or insights would be greatly appreciated. Thank you!

0

There are 0 best solutions below