微信支付JSAPI调用时签名失败,可能是什么原因?
在React项目里集成微信支付时,调用wx.config一直返回签名失败错误(errCode:40001)。我按照文档传了appId、timestamp等参数,但调试器显示验证失败。代码逻辑没问题,后端确认签名算法正确,这是为什么?
// 调用微信支付的函数片段
const pay = async () => {
const { appId, nonceStr, signType, paySign } = await getOrder();
wx.config({
debug: true,
appId,
timestamp: new Date().getTime(), // 已确认是当前时间戳
nonceStr,
signature: paySign,
jsApiList: ['chooseWXPay']
});
wx.ready(() => {
wx.chooseWXPay({
timestamp: new Date().getTime(),
nonceStr,
package: 'prepay_id=123',
signType: 'MD5',
paySign
});
});
};
检查过appId和支付密钥没问题,测试环境也配置了正确的域名。签名生成用的是后端提供的PHP代码,但前后端时间戳是否需要同步?或者nonceStr格式有特殊要求?
errCode:40001一般是签名验证失败,问题可能不在代码结构,而在签名生成的细节。关键点:
1. **时间戳要同步**
微信服务器和你的服务器时间差超过5分钟会失败。确认后端时间同步了标准时间(比如用
ntpdate校准)。2. **nonceStr大小写敏感**
必须是随机字符串,且大小写敏感。比如后端用的是
5K8264ILTKCH16CQ2502SI8ZNMTM67VS,前端传的也要一模一样。3. **签名字段顺序不能乱**
微信签名是按字段字典序拼接的。比如:
这个顺序不能错,特别是
url参数是页面完整URL(不带#后面的部分)。4. **签名算法是否正确**
后端用的是SHA1还是MD5?确认后端签名算法和前端传的
signType一致。5. **前端config里的timestamp是整数**
timestamp: Math.floor(new Date().getTime() / 1000)更保险。6. **检查JS安全域名**
确保当前页面的域名在微信后台配置过,并且协议、端口、路径完全一致。
先从这几个点排查,应该能定位问题。我之前也卡了好久,最后发现是
url拼接时漏了路径部分。微信签名验证真坑。new Date().getTime(),要从后端统一获取。懒人方案是直接把后端返回的timestamp和nonceStr原封不动地用到wx.chooseWXPay里。另外确保后端生成签名时所有参数顺序正确且没有多余的空格。