使用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 相关文章推荐
ECMA5数组的新增方法有哪些及forEach()模仿实现
Nov 03 Javascript
基于BootStrap Metronic开发框架经验小结【五】Bootstrap File Input文件上传插件的用法详解
May 12 Javascript
浅谈javascript:两种注释,声明变量,定义函数
Oct 05 Javascript
原生JavaScript制作计算器
Oct 16 Javascript
JavaScript实现修改伪类样式
Nov 27 Javascript
基于Vue2x实现响应式自适应轮播组件插件VueSliderShow功能
May 16 Javascript
vue 解决循环引用组件报错的问题
Sep 06 Javascript
vue ssr 实现方式(学习笔记)
Jan 18 Javascript
浅谈Vue CLI 3结合Lerna进行UI框架设计
Apr 14 Javascript
详解webpack引用jquery(第三方模块)的三种办法
Aug 21 jQuery
JavaScript简易计算器制作
Jan 17 Javascript
小程序实现图片移动缩放效果
May 26 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设计模式 php实现门面模式(Facade)
2015/12/07 PHP
PHP的时间戳与具体时间转化的简单实现
2016/06/13 PHP
javascript函数中的arguments参数
2010/08/01 Javascript
JQuery实现鼠标滑过显示导航下拉列表
2013/09/12 Javascript
JavaScript代码简单实现求杨辉三角给定行的最大值
2013/10/29 Javascript
使用js判断数组中是否包含某一元素(类似于php中的in_array())
2013/12/12 Javascript
JavaScript的21条基本知识点
2014/03/04 Javascript
node.js中的fs.close方法使用说明
2014/12/17 Javascript
基于javascript如何传递特殊字符
2015/11/30 Javascript
Bootstrap Table服务器分页与在线编辑应用总结
2016/08/08 Javascript
通过命令行生成vue项目框架的方法
2017/07/12 Javascript
微信小程序文字显示换行问题
2019/07/28 Javascript
使用layer弹窗,制作编辑User信息页面的方法
2019/09/27 Javascript
layui实现form表单同时提交数据和文件的代码
2019/10/25 Javascript
vue 导航内容设置选中状态样式的例子
2019/11/01 Javascript
js实现无缝轮播图特效
2020/05/09 Javascript
JS sort方法基于数组对象属性值排序
2020/07/10 Javascript
微信小程序基于ColorUI构建皮皮虾短视频去水印组件
2020/11/04 Javascript
python修改操作系统时间的方法
2015/05/18 Python
Python找出文件中使用率最高的汉字实例详解
2015/06/03 Python
Python获取SQLite查询结果表列名的方法
2017/06/21 Python
Python2.7+pytesser实现简单验证码的识别方法
2017/12/29 Python
python利用requests库进行接口测试的方法详解
2018/07/06 Python
python使用opencv驱动摄像头的方法
2018/08/03 Python
django项目登录中使用图片验证码的实现方法
2019/08/15 Python
Python While循环语句实例演示及原理解析
2020/01/03 Python
python+opencv3.4.0 实现HOG+SVM行人检测的示例代码
2021/01/28 Python
CSS3 重置iphone浏览器按钮input,select等表单元素的默认样式
2014/10/11 HTML / CSS
BOSE德国官网:尽探索之力,享音乐之极
2016/12/11 全球购物
yy婚礼司仪主持词
2014/03/14 职场文书
红色故事演讲稿
2014/05/22 职场文书
美术第二课堂活动总结
2014/07/08 职场文书
西安兵马俑导游词
2015/02/02 职场文书
生死抉择观后感
2015/06/09 职场文书
浅析Python OpenCV三种滤镜效果
2022/04/11 Python
ORACLE中dbms_output.put_line输出问题的解决过程
2022/06/28 Oracle