小程序支付调起失败,统一下单返回的prepay_id用不了?
我在做微信小程序支付,后端已经成功调用了统一下单接口,也拿到了prepay_id,但前端调wx.requestPayment时一直报“支付验证签名失败”。我确认了时间戳、nonceStr这些参数都按文档传了,但还是不行。
这是我的前端调用代码:
wx.requestPayment({
timeStamp: res.timeStamp, // 后端返回的时间戳字符串
nonceStr: res.nonceStr,
package: 'prepay_id=' + res.prepayId,
signType: 'RSA',
paySign: res.paySign,
success(res) {
console.log('支付成功', res)
},
fail(err) {
console.error('支付失败', err)
}
})
是不是signType写错了?还是package格式不对?真的搞不懂哪里漏了。
前端调起支付时的paySign需要单独计算,不能直接用统一下单接口返回的签名。你得在后端重新生成一个签名给前端用。
V3版本的签名串拼接规则是这样的:
appId + "n" + timeStamp + "n" + nonceStr + "n" + "prepay_id=" + prepay_id + "n"
注意最后有个换行符,别漏了。然后用商户私钥做SHA256withRSA签名,再base64编码。
给你一段后端生成的示例代码(假设用的是PHP):
还有几个容易踩坑的地方提醒一下:
timeStamp必须是字符串类型,而且要和签名时用的值完全一致。我见过有人前端又重新取了时间戳,导致签名验证失败。
signType用RSA是对的,说明你用的是V3接口,配套的签名方式没问题。
另外说个安全相关的,商户私钥文件一定要保管好,不要提交到git仓库,最好放环境变量或者配置中心,防止泄露。还有nonceStr要用加密安全的随机数生成,别用简单的rand()函数,防止被猜出来。
如果还是不行,把后端签名串的内容打印出来核对一下格式,看看换行符是不是真的换行了。