收藏
回答

微信jsapi支付:支付签名验证失败(五天了!!!百度翻个遍)

// 后端: php
// wx.chooseWXPay签名数据, 这个已经到校验工具试过,签名没有问题
$sign_data = [
    'appId' => $config['appID'],
    'timeStamp' => strval($info['timestamp']), // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。
    //但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
    'nonceStr' => $info['nonceStr'], // 支付签名随机串,不长于 32 位
    'package' => $info['package'], // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
    'signType' => 'HMAC-SHA256' //  签名方式,默认为'SHA1',使用新版支付需传入'MD5'
];

// wx.config签名数据 拼接字符串然后使用sha1加密 strtoupper(hash_hmac("sha1", $str, $mach_key))
$signature = [
    'noncestr' => $info['nonceStr'],
    'jsapi_ticket' => $info['ticket'],
    'timestamp' => strval($info['timestamp']),
    'url' => 'https://m.***.com/'
];

我想知道, 我后端sdk使用的是V3版本, 这个加密key究竟使用API还是apiV3的key????两种都试了,还是签名失败,整个人都被你们微信支付折磨疯了
菜是原罪,我承认,可是翻过百度几十页, 实在没办法了,也不是知道是jsapi jsdk的问题还是什么问题,jsdk使用的是vue的,就是支付签名失败,也没有详细错误
想骂人但是没有资格,微信技术,能否救俺一命或者饶俺一命???????
I need help!
回答关注问题邀请回答
收藏

4 个回答

  • 北望沣渭
    北望沣渭
    2021-11-09

    你应该使用的是「php_sdk_v3.0.10」这个包的吧,SDK版本与API版本不是一回事,比如都叫「老王」,到底是哪个老王,得带入场景而言。

    建议你换 composer require wechatpay/wechatpay 新包, readme上就有二次签名指南。

    2021-11-09
    有用 1
    回复 9
    • 戚岁辰(锦淼网络科技)
      戚岁辰(锦淼网络科技)
      2021-11-09
      很有可能是sdk和api不同步,我先尝试下您的建议, 感谢!
      2021-11-09
      回复
    • 戚岁辰(锦淼网络科技)
      戚岁辰(锦淼网络科技)
      2021-11-09
      我刚看了下,后端使用的是wechatpay/wechatpay 1.2的sdk,前端我刚把jweixin-module换成了weixin-js-sdk, 还是不行,我自己再看一遍文档找找原因
      2021-11-09
      1
      回复
    • 北望沣渭
      北望沣渭
      2021-11-09回复戚岁辰(锦淼网络科技)
      问下后端,预下单用的是不是v3?如果用的v3,就要用rsa二次签名;如果用的是v2,二次签名的sign type要跟预下单一致
      2021-11-09
      1
      回复
    • 戚岁辰(锦淼网络科技)
      戚岁辰(锦淼网络科技)
      2021-11-09
      预下单用的是v3, 我这里没做rsa二次签名,我查下资料再试试,非常感谢
      2021-11-09
      回复
    • 北望沣渭
      北望沣渭
      2021-11-09回复戚岁辰(锦淼网络科技)
      wechatpay/wechatpay readme上就有 RSA 方式的二次签名方法
      2021-11-09
      回复
    查看更多(4)
  • ?,!。
    ?,!。
    2022-02-24

    折腾了一下午和一晚上终于解决了。我这边的问题是:我们之前已经对接 过app的微信支付,后台直接返回了{ "package": "Sign=WXPay", "appid": "wx666", "sign": "7E9360EE36", "partnerid": "1116401", "prepayid": "wx66000", "noncestr": "345332", "timestamp": "1625620895" } 这样的数据各式我当时的做法是拿着后台返回的这些参数 格式化后直接去调用微信支付。

    但是注意注意,JSAPI加密sign的方法和app不一样, sign不能混用,它是是 需要把appId , timeStamp, nonceStr,package, signType 5个参数拼接key 以后 再使用md5加密


    2022-02-24
    有用 1
    回复
  • 戚岁辰(锦淼网络科技)
    戚岁辰(锦淼网络科技)
    2021-11-09

    问题已经解决

    首先感谢楼上两位朋友的帮助,特别感谢北望沣渭兄弟明确的指出了问题所在和解决方法!!

    前端使用的是微信jssdk, 后端使用的是微信php sdk_v3, v2请略过

    本次开发,支付验证签名失败的原因有以下几点:

    1. 签名字段大小写问题, 签名字段多余问题
    2. sdk_v3发起的预支付,签名必须对应的使用用rsa二次签名
    3. 阅读文档时没有分清v2和v3, 导致加密签名试过了MD5和HMAC_SH2都不行


    简单附上本次流程和容易踩的坑

    //第一步: 获取微信授权链接, 主要是用来获取用户openId的,参数scope选择的是静默跳转
    // https://open.weixin.qq.com/connect/oauth2/authorize?appid={$app_id}&redirect_uri={$redirect_uri}&response_type=code&scope=snsapi_base&state={$state}#wechat_redirect
    // 这里的$redirect_uri 必须要url编码
    
    // 第二步: 利用上一步得到的get参数code 获取授权token网页授权
    // appsecret 在公众号平台->设置与开发->基本配置里设置 
    // https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appid}&secret={$appsecret}&code={$code}&grant_type=authorization_code
    // 成功后会得到jsapi预支付必传参数openId
    
    // 第三步: 利用v3_sdk jsapi发起预支付, 请求成功后会获得 预支付标识prepay_id
    
    // 然后就开始加密了,jssdk的wx.chooseWXPay方法使用
    // 签名数据, 4个参数,不要传多,也不需要拼接什么, 注意大小写. 加密方法要和发起预支付的方法相同,楼上朋友有提供,v3只支持RSH加密 我就是这里耽误几天各种尝试,什么md5加密,hmac-sha256加密(估计我看错了文档)
    $sign_data = [
        'appId' => $config['appID'],
        'timeStamp' => strval($info['timestamp']),  // 11位时间戳
        'nonceStr' => $info['nonceStr'], // 支付签名随机串,不长于 32 位
        'package' => $info['package'], // 这个地方很关键, 时面是预支付标识prepay_id=xxxxxxxxx,必须加上prepay_id=
    ];
    
    // jssdk的wx.config参数加密, 这里的键都要小写, noncestr和timestamp参数必须和上面相同,而且只能使用sha1加密,把参数键值拼接后还要加上商户平台设置的密钥key
    // url不要进行编码,不然会把url参数中的特殊字符转义
    //  jsapi_ticket根据token到链接 https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' . $app_token['token'] . '&type=jsapi' 获取
    //  access_token是公众号的access_token, 不是上面获取openid返回的access_token, 而且公众号token和jsapi_ticket有请求次数限制,都要做缓存(2小时左右)
    $signature = [
        'noncestr' => $info['nonceStr'],
        'jsapi_ticket' => $info['ticket'], 
        'timestamp' => strval($info['timestamp']),
        'url' => 'https://xxx.com/'
    ];
    
    // 最后jssdk参数参考文档https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#3,还是要注意大小写
    // wx.config参数: debug  appId   timestamp  nonceStr jsApiList signature
    // wx.chooseWXPay参数: timestamp nonceStr package signType paySign
    
    // url未注册问题: 到商户平台->产品中心->开发配置里面添加SAPI支付 支付授权目录
    
    
    
    
    2021-11-09
    有用
    回复
  • 青寒
    青寒
    2021-11-09

    5天!

    2021-11-09
    有用
    回复 1
登录 后发表内容