使用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 相关文章推荐
js 事件小结 表格区别
Aug 13 Javascript
JavaScript中使用正则匹配多条,且获取每条中的分组数据
Nov 30 Javascript
基于jquery可配置循环左右滚动例子
Sep 09 Javascript
JavaScript将取代AppleScript?
Sep 18 Javascript
jQuery动态添加及删除表单上传元素的方法(附demo源码下载)
Jan 15 Javascript
基于jQuery实现中英文切换导航条效果
Sep 18 Javascript
vue 和vue-touch 实现移动端左右导航效果(仿京东移动站导航)
Apr 22 Javascript
JS实现按钮颜色切换效果
Sep 05 Javascript
JS写谷歌浏览器chrome的外挂实例
Jan 11 Javascript
Vue实现todolist删除功能
Jun 26 Javascript
原生js实现随机点名功能
Nov 05 Javascript
js实现计算器功能
Aug 10 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
深入探讨<br />和 \r\n两者有什么区别??
2013/06/05 PHP
php中让上传的文件大小在上传前就受限制的两种解决方法
2013/06/24 PHP
PHP的文件操作与算法实现的面试题示例
2015/08/10 PHP
PHP单元测试配置与使用方法详解
2019/12/27 PHP
2020最新版 PhpStudy V8.1版本下载安装使用详解
2020/10/30 PHP
php慢查询日志和错误日志使用详解
2021/02/27 PHP
Jquery AJAX 用于计算点击率(统计)
2010/06/30 Javascript
form表单中去掉默认的enter键提交并绑定js方法实现代码
2013/04/01 Javascript
JS实现的页面自定义滚动条效果
2015/10/26 Javascript
JavaScript基础知识及常用方法总结
2016/01/10 Javascript
AngularJs Javascript MVC 框架
2016/06/20 Javascript
JS实现的验证身份证及获取地区功能示例
2017/01/16 Javascript
在页面中引入js的两种方法(推荐)
2017/08/29 Javascript
node.js+express+mySQL+ejs+bootstrop实现网站登录注册功能
2018/01/12 Javascript
vue iview实现动态路由和权限验证功能
2018/04/17 Javascript
JS实现判断数组是否包含某个元素示例
2019/05/24 Javascript
Node.js 在本地生成日志文件的方法
2020/02/07 Javascript
javascript实现前端成语点击验证优化
2020/06/24 Javascript
JS+CSS实现动态时钟
2021/02/19 Javascript
python发腾讯微博代码分享
2014/01/10 Python
Python+Selenium自动化实现分页(pagination)处理
2017/03/31 Python
Python实现简单遗传算法(SGA)
2018/01/29 Python
python使用magic模块进行文件类型识别方法
2018/12/08 Python
对Python _取log的几种方式小结
2019/07/25 Python
利用python-docx模块写批量生日邀请函
2019/08/26 Python
快速解决docker-py api版本不兼容的问题
2019/08/30 Python
pygame实现俄罗斯方块游戏(AI篇1)
2019/10/29 Python
Python基于paramunittest模块实现excl参数化
2020/04/26 Python
使用python-Jenkins批量创建及修改jobs操作
2020/05/12 Python
HTML5实现WebSocket协议原理浅析
2014/07/07 HTML / CSS
Html5 audio标签样式的修改
2016/01/28 HTML / CSS
英国精品买手店:Browns Fashion
2016/09/29 全球购物
Nº21官方在线商店:numeroventuno.com
2019/09/26 全球购物
教师试用期自我鉴定
2014/02/12 职场文书
2014年班务工作总结
2014/12/02 职场文书
FP-growth算法发现频繁项集——构建FP树
2021/06/24 Python