我目前正在致力于将 M-Pesa Daraja API 集成到我的 Node.js 应用程序中,以启动移动支付的 STK 推送。 STK推送本身运行良好;但是,我遇到了回调功能的问题。
这是我启动 STK 推送的代码的简化版本:
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' });
});
STK推送成功发起,但是支付完成后,请求中指定的回调URL似乎没有被触发。我已验证回调 URL 正确且可访问。
我还检查了服务器上的日志,付款完成后没有传入请求到达回调 URL 端点。
有人可以指导我如何排查并解决 M-Pesa Daraja API 回调不起作用的问题吗?我需要采取任何特定配置或额外步骤来确保回调功能按预期运行吗?
任何帮助或见解将不胜感激。谢谢!
我知道有点晚了,但希望这会有所帮助。
尝试使用 ngrok 或本地隧道等隧道。这可确保您的回调 URL 位于互联网上并且可由 Safaricom 访问。同时删除该 url 可能拥有的所有 csrf 过滤器。 (不过,请记住将生产中 safaricom 的 IP 列入白名单,以避免回调 url 被操纵)
如果这不起作用,请尝试将您的应用程序部署在您可能可用的域上,然后重试。这应该比平常更有效。确保该 url 具有 SSL 证书。 希望有帮助🍻!