alipay/alipay-sdk-nodejs-all

设置了 passbackParams 会导致 alipaySdk.checkNotifySign 失败

fjc0k opened this issue · 6 comments

fjc0k commented

如下,去除 passbackParams 后 alipaySdk.checkNotifySign 才会成功:

    formData.addField('bizContent', {
      // 商户订单号,64个字符以内、可包含字母、数字、下划线;需保证在商户端不重复
      outTradeNo: 'out_trade_no222333324',
      // 销售产品码,与支付宝签约的产品码名称。注:目前仅支持FAST_INSTANT_TRADE_PAY
      productCode: 'FAST_INSTANT_TRADE_PAY',
      // 订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]。
      totalAmount: '0.01',
      // 	订单标题
      subject: 'xxxx',
      // passbackParams: encodeURIComponent(JSON.stringify({ id: 1 })),
    })
fjc0k commented

发现了问题所在:

https://github.com/alipay/alipay-sdk-nodejs/blob/3108aa3448b00243836fdc4e45de020ed05f64e2/lib/alipay.ts#L257

此处对 value 进行了 decodeURIComponent 操作,而对于 passbackParams 官方文档又说:本参数必须进行UrlEncode之后才可以发送给支付宝。,这导致生成签名和验证签名所使用的不再是同一个 passbackParams。

临时解决办法,在 checkNotifySign 前对 passback_params 进行一次 encodeURIComponent:

    payload.passback_params = encodeURIComponent(payload.passback_params)
    const verified = alipaySdk.checkNotifySign(payload)

这...这个例子下你的方案可能就是最好的方案了,SDK 也知道哪个参数需要 encode 哪个不需要 encode

fjc0k commented

@tudou527 我是觉得不应该对值进行 decodeURIComponent 操作吧,传给 checkNotifySign 的数据应该默认是正规化的。而且 POST 这么一段数据给服务器 id=1&name=ff%E6%88%91%E5%B0%B1,一般的服务端程序都会把它解析成这样 { id: 1, name: 'ff我就' },而不是这样 { id: 1, name: 'ff%E6%88%91%E5%B0%B1' },checkNotifySign 里又对参数进行了一道解码,就会导致一些问题了。

遇到相同的问题。建议官方在文档里稍微加点说明。https://www.yuque.com/chenqiu/alipay-node-sdk/notify_verify

我也遇到了这个问题,我把解码函数删掉了,传过来的既然是json,函数默认入参是object ,就没必要再解码一次了把

2023年11月23日,此问题还没解决,文档没有一点说明,排查此问题-5小时,so alibaba fuck u!