微信支付JSAPI调用时签名失败,可能是什么原因?

Designer°菲菲 阅读 44

在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格式有特殊要求?

我来解答 赞 9 收藏
二维码
手机扫码查看
2 条解答
Mr.艺涵
Mr.艺涵 Lv1
这个问题我也踩过坑。errCode:40001 一般是签名验证失败,问题可能不在代码结构,而在签名生成的细节。

关键点:

1. **时间戳要同步**
微信服务器和你的服务器时间差超过5分钟会失败。确认后端时间同步了标准时间(比如用ntpdate校准)。

2. **nonceStr大小写敏感**
必须是随机字符串,且大小写敏感。比如后端用的是5K8264ILTKCH16CQ2502SI8ZNMTM67VS,前端传的也要一模一样。

3. **签名字段顺序不能乱**
微信签名是按字段字典序拼接的。比如:
const str = appId=${appId}&nonceStr=${nonceStr}&timestamp=${timestamp}&url=${location.href.split('#')[0]};

这个顺序不能错,特别是url参数是页面完整URL(不带#后面的部分)。

4. **签名算法是否正确**
后端用的是SHA1还是MD5?确认后端签名算法和前端传的signType一致。

5. **前端config里的timestamp是整数**
timestamp: Math.floor(new Date().getTime() / 1000) 更保险。

6. **检查JS安全域名**
确保当前页面的域名在微信后台配置过,并且协议、端口、路径完全一致。

先从这几个点排查,应该能定位问题。我之前也卡了好久,最后发现是url拼接时漏了路径部分。微信签名验证真坑。
点赞 7
2026-02-03 08:04
码农珮青
问题出在时间戳和签名参数的生成上。微信支付要求前后端的时间戳必须一致,而且wx.config里的timestamp不能用new Date().getTime(),要从后端统一获取。懒人方案是直接把后端返回的timestamp和nonceStr原封不动地用到wx.chooseWXPay里。

const pay = async () => {
const { appId, timestamp, nonceStr, package: pkg, signType, paySign } = await getOrder();
wx.config({
debug: true,
appId,
timestamp,
nonceStr,
signature: paySign,
jsApiList: ['chooseWXPay']
});
wx.ready(() => {
wx.chooseWXPay({
timestamp,
nonceStr,
package: pkg,
signType,
paySign
});
});
};


另外确保后端生成签名时所有参数顺序正确且没有多余的空格。
点赞 13
2026-01-31 17:02