使用weixin-java-tools完成微信授权登录、微信支付的示例


Posted in Javascript onSeptember 26, 2018

本文为学习记录weixin-java-tools实现公众号微信支付.

码云地址:点我

// 授权登录用到
    <dependency>
      <groupId>com.github.binarywang</groupId>
      <artifactId>weixin-java-mp</artifactId>
      <version>3.1.0</version>
    </dependency>
// 微信支付用到
    <dependency>
      <groupId>com.github.binarywang</groupId>
      <artifactId>weixin-java-pay</artifactId>
      <version>3.1.0</version>
    </dependency>

授权登录官方 api:点我

个人理解的授权登录流程:引导用户点击唤起授权登录的地址,打开页面后携带微信返回的code参数;使用code参数获取AccessToken;获取用户数据。

引导客户打开授权登录地址后,携带code跳转到指定页面在指定页面调用方法:

public Result getAccessToken(@RequestParam(name = "code") String code, HttpServletRequest request, HttpServletResponse response) {
    if (StringUtils.isBlank(code)) {
      return Result.error("code不存在");
    }
    try {
      WxMpOAuth2AccessToken wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
      String accessToken = wxMpOAuth2AccessToken.getAccessToken();
      // 获取用户微信账户信息
      WxMpUser wxMpUser = wxMpService.getUserService().userInfo(wxMpOAuth2AccessToken.getOpenId());
      if (StringUtils.isBlank(wxMpUser.getOpenId())) {
        return Result.error("用户数据不存在");
      }
      return Result.success(wxMpUser);
    } catch (WxErrorException e) {
      e.printStackTrace();
      log.info("授权异常:{}", e);
      return Result.error("授权登录失败");
    } catch (Exception e) {
      e.printStackTrace();
      return Result.error("登录失败");
    }
  }

前端保存下用户信息就完事了。

个人理解的微信支付流程:用户页面点击<微信支付>按钮 后端调用 <微信统一下单> 统一下单返回参数 ,前端使用 <统一下单>返回的参数唤起微信支付。

商户中需要在api安全中设置很多东西... 就不一一赘述了

微信支付官方api 前端:点我

后端api点我

商户登录地址 点我

public Result pay(Long orderNo, HttpServletRequest request) {
    
    //查询订单信息
    Order order = orderService.findByOrderNo(orderNo);

    try {
      WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
      //获取当前用户
      UserInfo userInfo = RequestContextHolderUtil.getUserInfo();
      orderRequest.setBody("支付内容的说明");
      //商户号
      orderRequest.setMchId(mchId);
      orderRequest.setAttach("xxx公司");
      orderRequest.setOutTradeNo(orderNo.toString());
      orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(order.getPayment().toString()));//元转成分
      orderRequest.setOpenid(userInfo.getOpenId());
      orderRequest.setSpbillCreateIp(HttpUtils.getIp(request));
      //我这里是微信公众号内打开的h5页面 type使用 JSAPI 根据业务场景变更
      orderRequest.setTradeType(WxPayConstants.TradeType.JSAPI);

      // 支付成功后跳转页面  这里需要对url进行编码
      orderRequest.setNotifyUrl("http://xxxxxxxxx");
      orderRequest.setAppid(appId);
      
      // 调用sdk提供的统一下单方法 createOrder会返回重新组装后的对象 建议使用这个 
      Object unOrder = wxService.createOrder(orderRequest);
      // 这个可能是偏向原生一点的统一下单,返回的参数有很多没用的 或者null值 建议使用 createOrder下单
      // wxService.unifiedOrder(orderRequest); 
      
      return Result.success(unOrder);
    } catch (Exception e) {
      log.error("微信支付失败!订单号:{},原因:{}", orderNo, e.getMessage());
      e.printStackTrace();
      return Result.error("支付失败,请稍后重试!");
    }
  }

前端js代码:

前端唤起微信支付的时候可能会出一些问题,这里建议使用 console.log(res.err_desc);输出错误信息

res.err_msg 只会提示支付失败... desc会提示一些具体信息

function onBridgeReady(){
  WeixinJSBridge.invoke(
    'getBrandWCPayRequest', {
      "appId":"wx31fd1e1bad23db37",   //公众号名称,由商户传入
      "timeStamp":wxData.timeStamp,     //时间戳,自1970年以来的秒数
      "nonceStr":wxData.nonceStr, //随机串
      "package":wxData.packageValue,
      "signType":wxData.signType,     //微信签名方式:
      "paySign":wxData.paySign //微信签名

    },
    function(res){
      console.log(res.err_desc)
      if(res.err_msg == "get_brand_wcpay_request:ok" ){
        // 使用以上方式判断前端返回,微信团队郑重提示:
        //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
      }
    });
}
var wxData={};
function pay(orderId){
  $.ajax({
    url:"统一下单方法url",
    type:'get',
    data:{orderNo:orderId},
    beforeSend: function (xhr) {
      xhr.setRequestHeader("token", $.cookie("token"));
    },
    crossDomain: true,
    success:function(result){
      wxData=result.data;
      if (typeof WeixinJSBridge == "undefined") {
        if (document.addEventListener) {
          document.addEventListener('WeixinJSBridgeReady',
            onBridgeReady, false);
        } else if (document.attachEvent) {
          document.attachEvent('WeixinJSBridgeReady',
            onBridgeReady);
          document.attachEvent('onWeixinJSBridgeReady',
            onBridgeReady);
        }
      } else {
        onBridgeReady();
      }
    }
  });
}

注:商户中心支付路径设置 所有调起微信支付的页面都要在此注册,否则微信支付会一闪而过。
微信开发工具上可以模拟授权登录,但是无法模拟微信支付,所以微信支付在微信开发工具上出现的错误都不用管,直接拿到真机上去测试!

使用了sdk后的支付和授权还是很方便的,麻烦的是微信方面的一些配置和流程... 很坑。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery 页面滚动到指定DIV实现代码
Sep 25 Javascript
JS记录用户登录次数实现代码
Jan 15 Javascript
浅析JS操作DOM的一些常用方法
May 13 Javascript
利用node.js写一个爬取知乎妹纸图的小爬虫
May 03 Javascript
JavaScript全屏和退出全屏事件总结(附代码)
Aug 17 Javascript
一个有意思的鼠标点击文字特效jquery代码
Sep 23 jQuery
详解Webpack + ES6 最新环境搭建与配置
Jun 04 Javascript
Vue中使用的EventBus有生命周期
Jul 12 Javascript
微信小程序首页的分类功能和搜索功能的实现思路及代码详解
Sep 11 Javascript
微信小程序监听用户登录事件的实现方法
Nov 11 Javascript
js找出5个数中最大的一个数和倒数第二大的数实现方法示例小结
Mar 04 Javascript
如何用Node.js编写内存效率高的应用程序
Apr 30 Javascript
解决vuejs 使用value in list 循环遍历数组出现警告的问题
Sep 26 #Javascript
深入理解react-router 路由的实现原理
Sep 26 #Javascript
node.js使用redis储存session的方法
Sep 26 #Javascript
详解Axios统一错误处理与后置
Sep 26 #Javascript
Vue监听一个数组id是否与另一个数组id相同的方法
Sep 26 #Javascript
vue 循环加载数据并获取第一条记录的方法
Sep 26 #Javascript
基于vue v-for 多层循环嵌套获取行数的方法
Sep 26 #Javascript
You might like
PHP获取搜索引擎关键字来源的函数(支持百度和谷歌等搜索引擎)
2012/10/03 PHP
php不允许用户提交空表单(php空值判断)
2013/11/12 PHP
thinkphp如何获取客户端IP
2015/11/03 PHP
PHP实现的进度条效果详解
2016/05/03 PHP
php伪静态验证码不显示的解决方案
2019/09/26 PHP
Nigma vs Alliance BO5 第二场2.14
2021/03/10 DOTA
JS获取各种宽度、高度的简单介绍
2014/12/19 Javascript
jquery实现的用户注册表单提示操作效果代码分享
2015/08/28 Javascript
JavaScript实现窗口抖动效果
2016/10/19 Javascript
JS一个简单的注册页面实例
2017/09/05 Javascript
postman+json+springmvc测试批量添加实例
2018/03/31 Javascript
原生JS+HTML5实现跟随鼠标一起流动的粒子动画效果
2018/05/03 Javascript
iview Upload组件多个文件上传的示例代码
2018/09/30 Javascript
Element-ui自定义table表头、修改列标题样式、添加tooltip、:render-header使用
2019/04/11 Javascript
js单线程的本质 Event Loop解析
2019/10/29 Javascript
python实现的简单FTP上传下载文件实例
2015/06/30 Python
Python的Django框架中自定义模版标签的示例
2015/07/20 Python
python3中int(整型)的使用教程
2017/03/23 Python
对numpy中布尔型数组的处理方法详解
2018/04/17 Python
python实现对输入的密文加密
2019/03/20 Python
Python 中list ,set,dict的大规模查找效率对比详解
2019/10/11 Python
基于Python获取照片的GPS位置信息
2020/01/20 Python
浅谈python 类方法/静态方法
2020/09/18 Python
CSS3 input框的实现代码类似Google登录的动画效果
2020/08/04 HTML / CSS
html5-Canvas可以在web中绘制各种图形
2012/12/26 HTML / CSS
英国一家专门出售品牌鞋子的网站:Allsole
2016/08/07 全球购物
荷兰鞋子在线:Nelson Schoenen
2017/12/25 全球购物
专业实习自我鉴定
2013/10/29 职场文书
毕业生个人投资创业计划书
2014/01/04 职场文书
市场营销毕业生自荐信范文
2014/04/01 职场文书
授权委托书范本(单位)
2014/09/28 职场文书
爸爸的三轮车观后感
2015/06/16 职场文书
党员公开承诺书(2016最新版)
2016/03/24 职场文书
导游词之晋城蟒河
2019/12/12 职场文书
基于Redis位图实现用户签到功能
2021/05/08 Redis
关于python中readlines函数的参数hint的相关知识总结
2021/06/24 Python