Node.js沙箱环境下Cashfree Webhook签名验证不匹配问题:如何正确验证签名?
Node.js沙箱环境下Cashfree Webhook签名验证不匹配问题:如何正确验证签名?
我太懂你这种卡在Webhook签名验证上的烦躁了!之前我也踩过Cashfree的这个坑,现在给你理清楚关键问题:
首先明确回答你的核心疑问:Cashfree确实提供专门的Webhook签名密钥,和Client ID、API的Client Secret都不是一回事,你之前用Client ID来哈希肯定会导致签名不匹配,这就是问题根源!
第一步:获取正确的Webhook专属密钥
你需要登录Cashfree的沙箱商家后台,找到Webhook配置的页面(一般在「设置」或者「Webhooks」的菜单入口里),对应的Webhook端点下面会有一个专门的「Webhook Secret」(或者叫「Signature Secret」),这个才是你要用来做HMAC哈希的密钥,千万不能用Client ID或者API的Client Secret代替。
第二步:修正你的验证代码&避坑点
把代码里的密钥替换成上面拿到的Webhook Secret,同时再检查几个容易踩坑的细节:
- 必须确保拿到的是原始请求体(rawBody):如果你的Node.js框架(比如Express)自动帮你解析了JSON请求体,那你拿到的就不是Cashfree发送的原始字符串了——这时候要配置框架跳过自动解析,直接获取请求的原始Buffer再转成UTF-8字符串,不然序列化后的JSON可能和原始体有细微差异(比如空格、换行),导致哈希结果不一致。
- 确认timestamp的来源:Cashfree会在Webhook请求的Header里带上一个类似
X-Cashfree-Timestamp的字段,你要准确获取这个字段的值,不能自己生成或者用其他时间戳。 - 拼接顺序不能错:必须是
timestamp + rawBody的顺序,反过来的话哈希结果肯定不对。
给你修正后的代码示例:
const crypto = require('crypto'); function verifyCashfreeWebhook(rawBody, signature, timestamp) { // 替换为从Cashfree沙箱后台获取的Webhook专属Secret const webhookSecret = process.env.CASHFREE_WEBHOOK_SECRET; if (!webhookSecret) throw new Error("Missing webhook secret"); const message = timestamp + rawBody; const expectedSignature = crypto .createHmac("sha256", webhookSecret) .update(message) .digest("base64"); console.log({ received: signature, expected: expectedSignature, matches: signature === expectedSignature }); if (signature !== expectedSignature) { throw new Error("Signature mismatch"); } return JSON.parse(rawBody); }
沙箱环境额外注意点
沙箱环境的Webhook Secret和生产环境是完全独立的,一定要确保你拿的是沙箱后台里的密钥,别不小心用了生产环境的。
如果还是有问题,可以把message、收到的签名、生成的预期签名都打印出来对比,看看是不是原始体或者timestamp有细微差异——大部分签名不匹配问题都是这两个环节出了错。
内容来源于stack exchange
相关产品推荐
相关产品推荐

