使用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的文字自动截取(提供源代码)
Aug 09 Javascript
如何将JS的变量值传递给ASP变量
Dec 10 Javascript
解决JS浮点数运算出现Bug的方法
Mar 12 Javascript
JS获取键盘上任意按键的值(实例代码)
Nov 12 Javascript
jQuery点击自身以外地方关闭弹出层的简单实例
Dec 24 Javascript
jQuery实现表格行上移下移和置顶的方法
May 22 Javascript
配置Grunt的Task时通配符支持和动态生成文件名问题
Sep 06 Javascript
JavaScript实现自动跳转文本功能
May 25 Javascript
详细介绍RxJS在Angular中的应用
Sep 23 Javascript
Vue-Router2.X多种路由实现方式总结
Feb 09 Javascript
在Vue项目中使用d3.js的实例代码
May 01 Javascript
JS实现二维数组元素的排列组合运算简单示例
Jan 28 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图片上传代码
2013/11/04 PHP
php获取bing每日壁纸示例分享
2014/02/25 PHP
PHP获取数组中重复最多的元素的实现方法
2014/11/11 PHP
使用PHP生成二维码的方法汇总
2015/07/22 PHP
微信公众号支付之坑:调用支付jsapi缺少参数 timeStamp等错误解决方法
2016/01/12 PHP
PHP实现对文件锁进行加锁、解锁操作的方法
2017/07/04 PHP
浅谈PHPANALYSIS提取关键字
2019/03/08 PHP
JavaScript中的一些定位属性[图解]
2010/07/14 Javascript
JS运动基础框架实例分析
2015/03/03 Javascript
JQuery中$.each 和$(selector).each()的区别详解
2015/03/13 Javascript
浅谈bootstrap使用中的一些问题以及解决过程
2016/10/18 Javascript
为输入框加入数字js校验代码分享
2017/11/02 Javascript
JS设计模式之访问者模式定义与用法分析
2018/02/05 Javascript
Node.js爬取豆瓣数据实例分析
2018/03/05 Javascript
为什么使用koa2搭建微信第三方公众平台的原因
2018/05/16 Javascript
详解mpvue开发小程序小总结
2018/07/25 Javascript
JS实现盒子跟着鼠标移动及键盘方向键控制盒子移动效果示例
2019/01/29 Javascript
layui写后台表格思路和赋值用法详解
2019/11/14 Javascript
使用PreloadJS加载图片资源的基础方法详解
2020/02/03 Javascript
js实现滑动滑块验证登录
2020/07/24 Javascript
vue 接口请求地址前缀本地开发和线上开发设置方式
2020/08/13 Javascript
在Angular项目使用socket.io实现通信的方法
2021/01/05 Javascript
three.js 实现露珠滴落动画效果的示例代码
2021/03/01 Javascript
[34:41]夜魇凡尔赛茶话会 第二期02:你画我猜
2021/03/11 DOTA
Python对两个有序列表进行合并和排序的例子
2014/06/13 Python
PyCharm 常用快捷键和设置方法
2017/12/20 Python
在NumPy中创建空数组/矩阵的方法
2018/06/15 Python
python+PyQT实现系统桌面时钟
2020/06/16 Python
python实现异常信息堆栈输出到日志文件
2019/12/26 Python
在python中实现求输出1-3+5-7+9-......101的和
2020/04/02 Python
Django实现简单的分页功能
2021/02/22 Python
《石榴》教学反思
2014/03/02 职场文书
1亿有多大教学反思
2014/05/01 职场文书
公司离职证明范本(5篇)
2014/09/17 职场文书
2014年团支部工作总结
2014/11/17 职场文书
现货白银电话营销话术
2015/05/29 职场文书