Payfast Webhook(NodeJS)未收到ITN负载问题求助
排查Payfast ITN Webhook无负载问题的实操步骤
1. 先搞定NodeJS端的请求解析
Payfast的ITN请求是application/x-www-form-urlencoded格式,不是JSON。如果用Express,只加express.json()没用,必须补上表单解析中间件:
const express = require('express'); const app = express(); // 关键:解析表单格式的请求,没有这个req.body就是空的 app.use(express.urlencoded({ extended: true })); // 你的ITN端点 app.post('/payfast-itn', (req, res) => { console.log('收到ITN负载:', req.body); // 后续验证逻辑... res.sendStatus(200); // 必须返回200,Payfast才会认为接收成功 });
2. 核对Payfast侧的配置
- 沙箱商家后台的Notify URL必须和你的ngrok地址完全一致,比如
https://xxxx.ngrok.io/payfast-itn,别加尾斜杠,Payfast对URL匹配要求很严。 - 确认沙箱环境的ITN功能已经开启,商家后台里要单独勾选ITN选项。
3. 确认请求是否真的发过来了
打开ngrok的本地监控页(默认http://localhost:4040)看请求日志:
- 如果完全没记录,说明Payfast没触发ITN,检查React结账表单的
notify_url参数是否传对,表单必须是POST提交到沙箱地址https://sandbox.payfast.co.za/eng/process。 - 如果有请求但状态码不是200,排查你的端点是否报错(比如路由写错、服务挂了),Payfast的ITN是服务器间请求,不存在跨域问题。
4. 必须做ITN合法性验证(否则可能被静默丢弃)
Payfast要求收到ITN后必须先验证请求真实性,不然可能停止发送后续通知:
- 把
req.body里的所有参数按字母排序,拼接成查询字符串。 - 如果商家后台设置了
passphrase,要把它拼到字符串末尾。 - 生成MD5哈希,和Payfast发送的
signature对比。 - 再向Payfast沙箱地址
https://sandbox.payfast.co.za/eng/query/validate发POST请求,带上所有参数,确认请求真实有效。
跳过这步的话,Payfast可能直接丢弃你的ITN请求,自然收不到负载。
5. 本地测试的细节坑
- ngrok免费版每次重启域名都会变,要同步更新Payfast后台和React表单里的Notify URL。
- 确保本地Node服务没被防火墙挡着,端口也没被其他程序占用,ngrok能正常转发请求。
- 用Postman模拟发送
application/x-www-form-urlencoded格式的请求到你的端点,测试req.body能不能正常接收,先排除代码本身的问题。
内容的提问来源于stack exchange,提问作者ghulam__sabir
相关产品推荐
相关产品推荐

