使用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 相关文章推荐
TinyMCE 新增本地图片上传功能
Nov 05 Javascript
基于jquery的弹出提示框始终处于窗口的居中位置(类似于alert弹出框的效果)
Sep 28 Javascript
有关jquery与DOM节点操作方法和属性记录
Apr 15 Javascript
JavaScript与ActionScript3两者的同性与差异性
Sep 22 Javascript
js实现点击切换checkbox背景图片的简单实例
May 08 Javascript
node中使用es5/6以及支持性与性能对比
Aug 11 Javascript
微信小程序开发背景图显示功能
Aug 08 Javascript
详解如何在微信小程序开发中正确的使用vant ui组件
Sep 13 Javascript
微信小程序scroll-view隐藏滚动条的方法详解
Mar 25 Javascript
vue将文件/图片批量打包下载zip的教程
Oct 21 Javascript
解决iview table组件里的 固定列 表格不自适应的问题
Nov 13 Javascript
Vue 列表页带参数进详情页的操作(router-link)
Nov 13 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中使用excel的简单介绍
2013/08/02 PHP
php获取一定范围内取N个不重复的随机数
2016/05/28 PHP
Linux下 php7安装redis的方法
2018/11/01 PHP
Ajax+Jpgraph实现的动态折线图功能示例
2019/02/11 PHP
JS实现打开本地文件或文件夹
2021/03/09 Javascript
jquery 学习之一 对象访问
2010/11/23 Javascript
轻松创建nodejs服务器(7):阻塞操作的实现
2014/12/18 NodeJs
动态加载js的方法汇总
2015/02/13 Javascript
Js数组排序函数sort()介绍
2015/06/08 Javascript
nodejs实现发出蜂鸣声音(系统报警声)的方法
2017/01/18 NodeJs
使用Bootrap和Vue实现仿百度搜索功能
2017/10/26 Javascript
JavaScript程序设计高级算法之动态规划实例分析
2017/11/24 Javascript
浅析Node.js非对称加密方法
2018/01/29 Javascript
Koa2微信公众号开发之本地开发调试环境搭建
2018/05/16 Javascript
浅谈Vue.js 中的 v-on 事件指令的使用
2018/11/25 Javascript
推荐15个最好用的JavaScript代码压缩工具
2019/02/13 Javascript
vue 动态组件用法示例小结
2020/03/06 Javascript
Vue记住滚动条和实现下拉加载的完美方法
2020/07/31 Javascript
vue+element获取el-table某行的下标,根据下标操作数组对象方式
2020/08/07 Javascript
python数组复制拷贝的实现方法
2015/06/09 Python
python导出hive数据表的schema实例代码
2018/01/22 Python
Python OpenCV实现图片上输出中文
2018/01/22 Python
Python实现的简单读写csv文件操作示例
2018/07/12 Python
python实现坦克大战游戏 附详细注释
2020/03/27 Python
任意一块网页内容实现“活”的背景(目前火狐浏览器专有)
2014/05/07 HTML / CSS
Web时代变迁及html5与html4的区别
2016/01/06 HTML / CSS
瑞典快乐袜子:Happy Socks
2018/02/16 全球购物
50道外企软件测试面试题
2014/08/18 面试题
公司综合部的成员自我评价分享
2013/11/05 职场文书
大学校庆邀请函
2014/01/11 职场文书
打架检讨书400字
2014/01/17 职场文书
高二地理教学反思
2014/01/24 职场文书
艺术设计专业个人求职信
2014/04/10 职场文书
学习朴航瑛老师爱岗敬业先进事迹思想汇报
2014/09/17 职场文书
初三语文教学计划
2015/01/22 职场文书
淘宝文案策划岗位职责
2015/04/14 职场文书