Reputation: 11
Am trying to save MPesa Callback data, when a user has paid with Lipa Na Mpesa, ineed to save the CheckoutRequestID, with a decoded username from token, then if the payment is successful the cllback URL needs to update the associated CheckoutRequestID from mysql with the amount, from there it needs to update the user's wallet with the new value. Currently the code works well, but I cannot save, when I try to access the username or any value the callback doesn't return any data. Here is the LipaNaMpesa code and the STK Callback code.
router.get('/stk', middleware.access, middleware.checkToken, (req, res) => {
let endpoint = "https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest"
let auth = "Bearer " + req.access_token
let datenow = new Date()
//console.log(datenow.getUTCDate())
const timestamp = datenow.getFullYear() +"" + addZero((datenow.getMonth()+1))+"" +addZero(datenow.getUTCDate())+ ""+ addZero(datenow.getHours())+"" + addZero(datenow.getMinutes())+"" + addZero(datenow.getSeconds())
// console.log(timestamp)
const password = (new Buffer.from('174379' + 'bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919' + timestamp).toString('base64'))
request(
{
url: endpoint,
method: "POST",
headers: {
"Authorization": auth
},
json: {
"BusinessShortCode": 174379,
"Password": password,
//"MTc0Mzc5YmZiMjc5ZjlhYTliZGJjZjE1OGU5N2RkNzFhNDY3Y2QyZTBjODkzMDU5YjEwZjc4ZTZiNzJhZGExZWQyYzkxOTIwMjExMjExMDcyODAw"
"Timestamp": timestamp,
"TransactionType": "CustomerPayBillOnline",
"Amount": 1,
"PartyA": 254792482180,//254792482180,
"PartyB": 174379,
"PhoneNumber": 254792482180,//254704148972,
"CallBackURL": "https://9b68-41-80-113-243.ngrok.io/mrequests/stk_confirm",
"AccountReference": "GoChama",
"TransactionDesc": "Wallet Deposit"
}
},
function (error, response, body) {
if (error) {
console.log(error)
}
else {
// console.log(body.CheckoutRequestID)
//console.log(req.decoded.username)
res.status(200).json(body)
}
}
)
})
router.post('/stk_confirm', (req, res) => {
console.log('....................... stk_confirm .............')
console.log("Payload Received", req.body.Body.stkCallback)
/* const callbackData = req.body.Body.stkCallback
console.log("Payload Received", callbackData)
var resultCode = callbackData.ResultCode;
var checkoutId = callbackData.CheckoutRequestID
var username = req.decoded.username
if(resultCode === 0){
const details = callbackData.CallbackMetadata.Item
var mReceipt;
var mPhoneNumber;
var mAmount;
await details.forEach(entry =>{
switch (entry.Name){
case "MpesaReceiptNumber":
mReceipt = entry.Value
break;
case "PhoneNumber":
mPhoneNumber = entry.Value
break;
case "Amount":
mAmount = entry.Value
break;
default:
break;
}
})
}*/
res.status(200).json(req.body)
})
The commented part f the code doesnt return any value when added. Is there something I am doing wrong?
Upvotes: 1
Views: 1034
Reputation: 43
I had a similar problem earlier. You're not getting the callbackData because you have not parsed the json object. Just before you handle the callBackPost request from daraja, you need to use bodyParser.json() to parse it, like so...
//remember to import the module
//const bodyParser = require("body-parser")
router.use(bodyParser.json())
router.post("/stk_confirm", (req, res) => {
const callbackData = req.body.Body.stkCallback;/*Everything Should now work as anticipated*/
})
If you might not be having body-parser module installed yet, you may install it as follows: Navigate to your project folder(The one containing your server script) in the command line using the 'cd' command in Windows, run...
npm install body-parser
in Linux, run...
sudo npm install body-parser
Thank you for reading, for any further inquiry, you can contact me at [email protected], Good luck.
Upvotes: 0
Reputation: 533
This is how the Daraja API will work in reference to your problem. When you call the LipaNaMpesa Code and it executes the following response is returned.
{
"MerchantRequestID": "7758-32589747-1",
"CheckoutRequestID": "ws_CO_21072022121325565708374149",
"ResponseCode": "0",
"ResponseDescription": "Success. Request accepted for processing",
"CustomerMessage": "Success. Request accepted for processing"
}
You will save the CheckoutRequestID to the database at this point together with the decoded username from the token and anything else you would like to save. The LipaNaMpesa Code sends a prompt to the customer's phone and returns the above response.
If the customer does not enter their PIN or has an insufficient balance or for whatever reason, the transaction does not go through, the Callback URL does not return anything.
If the customer enters the PIN and pays, the Callback URL returns the following response
{
"Body":
{
"stkCallback":
{
"MerchantRequestID": "21605-295434-4",
"CheckoutRequestID": "ws_CO_04112017184930742",
"ResultCode": 0,
"ResultDesc": "The service request is processed successfully.",
"CallbackMetadata":
{
"Item":
[
{
"Name": "Amount",
"Value": 1
},
{
"Name": "MpesaReceiptNumber",
"Value": "LK451H35OP"
},
{
"Name": "Balance"
},
{
"Name": "TransactionDate",
"Value": 20171104184944
},
{
"Name": "PhoneNumber",
"Value": 254706506361
}
]
}
}
}
}
At this point now, you can update the DB row where you inserted CheckoutRequestID from LipaNaMpesa Code response. The CheckoutRequestID from both responses is the same.
Upvotes: 2