使用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 相关文章推荐
location.href 在IE6中不跳转的解决方法与推荐使用代码
Jul 08 Javascript
获取select元素被选中的文本内容的js代码
Jan 29 Javascript
超级简单实现JavaScript MVC 样式框架
Mar 24 Javascript
js无法获取到html标签的属性的解决方法
Jul 26 Javascript
d3绘制基本的柱形图的实现代码
Dec 12 Javascript
Element UI框架中巧用树选择器的实现
Dec 12 Javascript
微信小程序外卖选购页实现切换分类与数量加减功能案例
Jan 15 Javascript
微信小程序使用canvas的画图操作示例
Jan 18 Javascript
LayUI动态设置checkbox不显示的解决方法
Sep 02 Javascript
Bootstrap实现模态框效果
Sep 30 Javascript
vue数据更新UI不刷新显示的解决办法
Aug 06 Javascript
vue 获取到数据但却渲染不到页面上的解决方法
Nov 19 Vue.js
解决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获取mysql版本的几种方法小结
2008/03/25 PHP
php使用str_replace替换多维数组的实现方法分析
2017/06/15 PHP
PHP基于递归算法解决兔子生兔子问题
2018/05/11 PHP
PHP操作redis实现的分页列表,新增,删除功能封装类与用法示例
2018/08/04 PHP
ThinkPHP5.1框架页面跳转及修改跳转页面模版示例
2019/05/06 PHP
jQuery学习3:操作元素属性和特性
2010/02/07 Javascript
JQuery 获得绝对,相对位置的坐标方法
2010/02/09 Javascript
IE不支持getElementsByClassName最终完美解决方案
2012/12/17 Javascript
JavaScript 命名空间 使用介绍
2013/08/29 Javascript
js 剪切板的用法(clipboardData.setData)与js match函数介绍
2013/11/19 Javascript
jquery ui resize 中border-box的bug修正
2015/04/26 Javascript
js实现仿百度风云榜可重复多次调用的TAB切换选项卡效果
2015/08/31 Javascript
一不小心就做错的JS闭包面试题
2015/11/25 Javascript
Bootstrap布局组件教程之Bootstrap下拉菜单
2016/06/12 Javascript
Ionic2系列之使用DeepLinker实现指定页面URL
2016/11/21 Javascript
js Canvas绘制圆形时钟效果
2017/02/17 Javascript
几行js代码实现自适应
2017/02/24 Javascript
80%应聘者都不及格的JS面试题
2017/03/21 Javascript
带你快速理解javascript中的事件模型
2017/08/14 Javascript
全新打包工具parcel零配置vue开发脚手架
2018/01/11 Javascript
微信小程序实现城市列表选择
2018/06/05 Javascript
说说Vue.js中的functional函数化组件的使用
2019/02/12 Javascript
Angular 多模块项目构建过程
2020/02/13 Javascript
Vue-resource安装过程及使用方法解析
2020/07/21 Javascript
JS绘图Flot如何实现可选显示曲线图功能
2020/10/16 Javascript
python虚拟环境virtualenv的使用教程
2017/10/20 Python
python3.6.3安装图文教程 TensorFlow安装配置方法
2020/06/24 Python
SpringBoot实现登录注册常见问题解决方案
2020/03/04 Python
Python创建简单的神经网络实例讲解
2021/01/04 Python
Optimalprint加拿大:在线打印服务
2020/04/03 全球购物
授权委托书怎么写
2014/04/03 职场文书
小学生三分钟演讲稿
2014/08/18 职场文书
开展党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
检察院对照“四风”认真查找问题落实整改措施
2014/09/26 职场文书
2014年超市员工工作总结
2014/11/18 职场文书
Python first-order-model实现让照片动起来
2022/06/25 Python