V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
licoycn
V2EX  ›  程序员

微信公众号支付一直“支付验证签名失败”

  •  
  •   licoycn ·
    Licoy · 2018-10-29 12:16:08 +08:00 · 12169 次点击
    这是一个创建于 1977 天前的主题,其中的信息可能已经有所发展或是发生改变。

    上周做了微信支付的公众号支付,在上周的测试的时候 10 次可能会出现一两次“支付验证签名失败”,但是这周来了测试每次都是“支付验证签名失败”,下方是调用微信的WeixinJSBridge传递的数据体 1.png 具体的前端调用代码是:

    let wxPayData = {
        "appId":res.appId, 
        "timeStamp":Math.round(new Date().getTime()/1000).toString(),  
        "nonceStr":res.nonceStr,  
        "package":res.packageValue,     
        "signType":res.signType,
        "paySign":res.paySign
    }
    WeixinJSBridge.invoke('getBrandWCPayRequest',wxPayData ,(res)=>{
        if(res.err_msg == "get_brand_wcpay_request:ok" ){
            this.getPayStatus(data.id)
        }else if(res.err_msg == "get_brand_wcpay_request:cancel" ){
            this.$dialog.alert({
                message: "您取消了支付,请重新支付",
                className:"tc"
            }).then(() => {});
        }else if(res.err_msg == "get_brand_wcpay_request:fail" ){
            this.$dialog.alert({
                message: "支付失败,请重新支付",
                className:"tc"
            }).then(() => {});
        }else{
            this.getPayStatus(data.id)
        }
    });
    

    后端采用的是weixin-java-pay,其 dependency 是:

    <dependency>
       <groupId>com.github.binarywang</groupId>
       <artifactId>weixin-java-pay</artifactId>
       <version>3.2.0</version>
    </dependency>
    

    而且后端调用微信统一下单接口一切都是正常,无任何异常抛出。

    所以想问问有没有朋友遇到过或者有好的解决方案?已知坑timeStamp的大小写等

    第 1 条附言  ·  2018-10-29 14:54:32 +08:00
    已解决,前端拉起支付时候的 timeStamp 需要与后端返回的的 timeStamp 是同一个(注:我的签名那些信息都是在后端进行的,所以说所以需要与你最后一次签名的时间一致)
    第 2 条附言  ·  2018-10-29 14:54:55 +08:00
    不得不说微信的文档真实让人看着头疼
    39 条回复    2018-12-17 17:52:09 +08:00
    xgfan
        1
    xgfan  
       2018-10-29 13:05:21 +08:00 via iPhone
    ts 不是应该后端给吗?
    cnit
        2
    cnit  
       2018-10-29 13:08:39 +08:00
    时间戳 十位
    cnit
        3
    cnit  
       2018-10-29 13:10:43 +08:00
    断点看下是不是 ip 白名单的问题
    ETiV
        4
    ETiV  
       2018-10-29 13:22:44 +08:00 via iPhone
    碰到过的坑:
    单页应用,路由走的是 # Hash 锚点,会出问题
    测试偶现,上线必现

    换掉#,走 History API,然后签名拿当页完整 URL 签
    pytth
        5
    pytth  
       2018-10-29 13:27:22 +08:00
    看我写的吧,200 行代码实现微信支付-公众号支付,不再踩坑: https://segmentfault.com/a/1190000013051299
    licoycn
        6
    licoycn  
    OP
       2018-10-29 13:32:59 +08:00
    @xgfan 公众号的时间戳是"当前的时间,其他详见时间戳规则" https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
    licoycn
        7
    licoycn  
    OP
       2018-10-29 13:34:04 +08:00
    @cnit 是 10 位的,IP 没有设置应该是没有限制
    licoycn
        8
    licoycn  
    OP
       2018-10-29 13:34:41 +08:00
    @ETiV 是走的 History API,没有#
    cnit
        9
    cnit  
       2018-10-29 13:34:53 +08:00
    licoycn
        10
    licoycn  
    OP
       2018-10-29 13:35:40 +08:00
    @pytth 方法都是一样的,无异,主要是上周测试都是 Ok 的,这周就突然不行了,期间也没有改动代码
    licoycn
        11
    licoycn  
    OP
       2018-10-29 13:36:49 +08:00
    @cnit 这个在之前已经完全看过一遍并检测了一遍,这里面所提到的都是没有问题的,但是就是会出现“支付验证签名失败”,还有一点就是上周测试都是 Ok 的,这周就突然不行了,期间也没有改动代码
    lsongiu
        12
    lsongiu  
       2018-10-29 13:57:54 +08:00
    中文乱码?
    licoycn
        13
    licoycn  
    OP
       2018-10-29 14:03:11 +08:00
    @lsongiu 没有
    sobigfish
        14
    sobigfish  
       2018-10-29 14:11:46 +08:00
    "这周就突然不行了,期间也没有改动代码"
    假设有版本控制吧,是完全没有 commit 还是 commit 没涉及到?
    会不会是代码里控制符之类的被换过 crlf > cr 之类的
    或者返回的 res 里有其他看不见的控制符
    licoycn
        15
    licoycn  
    OP
       2018-10-29 14:14:02 +08:00
    @sobigfish 并没有,都是通过 SpringBoot 返回的 JavaBean 来自动映射的 JSON
    tanranran
        16
    tanranran  
       2018-10-29 14:28:33 +08:00
    检查一下支付验证签名失败 中哪个参数失败了?
    licoycn
        17
    licoycn  
    OP
       2018-10-29 14:35:23 +08:00
    @tanranran 毫无疑问 肯定是 paySign 这个参数和他们官方加密出来不同
    liuzhedash
        18
    liuzhedash  
       2018-10-29 14:48:22 +08:00
    感觉是 timestamp 的问题,应当使用后端生成 paysign 时使用的 timestamp
    WildCat
        19
    WildCat  
       2018-10-29 14:52:12 +08:00
    timeStamp 是后端你 sign 的时候的,不是你前端生成的。
    licoycn
        20
    licoycn  
    OP
       2018-10-29 14:55:16 +08:00
    @liuzhedash
    @WildCat 是的 已解决
    WildCat
        21
    WildCat  
       2018-10-29 14:56:28 +08:00
    我觉得微信支付这块的坑,我都可以写一篇文章总结了,微信的文档狗屎都不如。
    liuzhedash
        22
    liuzhedash  
       2018-10-29 15:00:12 +08:00   ❤️ 1
    @WildCat #21
    是的,微信的开发文档非常傲慢
    zhangwugui
        23
    zhangwugui  
       2018-10-29 15:01:27 +08:00
    微信支付的接口经常会调整,但也不通知开发者,文档这块很坑。
    zhangwugui
        24
    zhangwugui  
       2018-10-29 15:01:46 +08:00
    完全不像大公司应有的模样。
    WildCat
        25
    WildCat  
       2018-10-29 15:04:45 +08:00
    @liuzhedash 不仅仅是傲慢,而且不完整,感觉微信的前端是初中毕业水平。

    1. 支付接口有 2 个,一个是你用的 JSBridge,一个是微信网页 js sdk,这块对比没有说
    2. js sdk 的返回值只有 success 的回调,坑死了
    3. 两个接口的 timestamp 拼写不一致
    4. sandbox 无法用来调试,只能线上肉测
    licoycn
        26
    licoycn  
    OP
       2018-10-29 16:22:35 +08:00
    @WildCat 对的
    landi
        27
    landi  
       2018-10-29 16:25:30 +08:00
    想问下支付功能用的是企业账号吗,还是个体户。
    licoycn
        28
    licoycn  
    OP
       2018-10-29 16:28:33 +08:00   ❤️ 1
    @landi 企业认证
    WildCat
        29
    WildCat  
       2018-10-29 16:49:35 +08:00
    Batmand
        30
    Batmand  
       2018-10-29 17:02:06 +08:00
    看到大家说微信的支付文档坑我就放心了,刚踩过坑的路过
    Batmand
        31
    Batmand  
       2018-10-29 17:03:06 +08:00
    @WildCat 我也是好奇微信支付两个不同的 JS 支付功能有什么区别
    licoycn
        32
    licoycn  
    OP
       2018-10-29 17:06:36 +08:00
    @Batmand 是不同的两个文件,一个是需要引入 js-sdk,另外一个就是微信浏览器的内置对象
    yyhuaisha
        33
    yyhuaisha  
       2018-12-14 10:47:29 +08:00
    @lico “ timeStamp 需要与后端返回的的 timeStamp 是同一个”
    但是现在的后端统一下单是不需要 timeStamp 的,请问一下你是怎么解决的?后端的 timeStamp 在统一下单的时候要传给微信吗还是在其他地方传?要传的话是传什么格式的? 10 位数字还是字符串?
    licoycn
        34
    licoycn  
    OP
       2018-12-14 13:33:24 +08:00
    @yyhuaisha 不要了吗
    yyhuaisha
        35
    yyhuaisha  
       2018-12-14 14:23:04 +08:00
    @licoycn 我看到文档是不需要的,我不知道你是在哪里传的哦,可以告知一下吗
    yyhuaisha
        36
    yyhuaisha  
       2018-12-14 14:23:38 +08:00
    因为我这里一直提示“支付验证签名失败”,排查了好多问题都没找到办法。
    yyhuaisha
        37
    yyhuaisha  
       2018-12-14 14:24:26 +08:00
    yyhuaisha
        38
    yyhuaisha  
       2018-12-17 15:59:27 +08:00
    查了两天资料终于看到了一点希望。
    这里的传到微信的签名不是统一下单获取的签名,而是 将 appId,timeStamp,nonceStr, package,signType 这五个参数 用签名方法去微信生成一个新的签名,然后再传给前端。所以 timeStamp 不是指的统一下单需要用到时间戳,而是 二次签名的时候要用到。这就解释了为何网上的例子 timeStamp 等参数都是后端传过来的,而不是前端自己生成的原因了。
    希望这个巨坑微信 api 可以备注一下。也希望这个回答对其他开发者有点帮助吧……
    licoycn
        39
    licoycn  
    OP
       2018-12-17 17:52:09 +08:00
    @yyhuaisha 是这样的,验签名的参数都要从后端传递过来
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1668 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 16:45 · PVG 00:45 · LAX 09:45 · JFK 12:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.