使用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 相关文章推荐
原生javascript获取元素样式属性值的方法
Dec 25 Javascript
getElementByIdx_x js自定义getElementById函数
Jan 24 Javascript
使用indexOf等在JavaScript的数组中进行元素查找和替换
Sep 18 Javascript
javascript遍历控件实例详细解析
Jan 10 Javascript
window.onload与$(document).ready()的区别分析
May 30 Javascript
js仿微博实现统计字符和本地存储功能
Dec 22 Javascript
angular源码学习第一篇 setupModuleLoader方法
Oct 20 Javascript
AngularJS模板加载用法详解
Nov 04 Javascript
js实现textarea限制输入字数
Feb 13 Javascript
微信小程序之GET请求的实例详解
Sep 29 Javascript
JQuery animate动画应用示例
May 14 jQuery
vue 父组件通过$refs获取子组件的值和方法详解
Nov 07 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之第七天
2006/10/09 PHP
PHP实现批量修改文件后缀名的方法
2015/07/30 PHP
PHP下的浮点运算不准的解决方法
2016/10/27 PHP
一实用的实现table排序的Javascript类库
2007/09/12 Javascript
一行代码告别document.getElementById
2012/06/01 Javascript
解析js中获得父窗口链接getParent方法以及各种打开窗口的方法
2013/06/19 Javascript
JS获取键盘上任意按键的值(实例代码)
2013/11/12 Javascript
javascript列表框操作函数集合汇总
2013/11/28 Javascript
jquery插件冲突(jquery.noconflict)解决方法分享
2014/03/20 Javascript
浅谈 javascript 事件处理
2015/01/04 Javascript
JS组件Bootstrap Table表格行拖拽效果实现代码
2020/08/27 Javascript
浅析Bootstrap验证控件的使用
2016/06/23 Javascript
浅谈vue项目优化之页面的按需加载(vue+webpack)
2017/12/11 Javascript
vue父组件向子组件(props)传递数据的方法
2018/01/02 Javascript
JavaScript字符和ASCII实现互相转换
2020/06/03 Javascript
python删除特定文件的方法
2015/07/30 Python
用python记录运行pid,并在需要时kill掉它们的实例
2017/01/16 Python
分数霸榜! python助你微信跳一跳拿高分
2018/01/08 Python
pandas 按照特定顺序输出的实现代码
2018/07/10 Python
python requests 库请求带有文件参数的接口实例
2019/01/03 Python
Python Tornado实现WEB服务器Socket服务器共存并实现交互的方法
2020/05/26 Python
Python3如何在服务器打印资产信息
2020/08/27 Python
python与idea的集成的实现
2020/11/20 Python
Move Free官方海外旗舰店:美国骨关节健康专业品牌
2017/12/06 全球购物
施华洛世奇中国官网:SWAROVSKI中国
2020/06/16 全球购物
基督教婚礼主持词
2014/03/14 职场文书
经理秘书求职自荐信范文
2014/03/23 职场文书
大跃进口号
2014/06/16 职场文书
2014年党员整改措施
2014/10/24 职场文书
投标承诺函范文
2015/01/21 职场文书
2015年城市管理工作总结
2015/05/23 职场文书
大学生党员暑假实践(活动总结)
2019/08/21 职场文书
使用CSS实现一个搜索引擎的原理解析
2021/09/25 HTML / CSS
详解Oracle块修改跟踪功能
2021/11/07 Oracle
DIV CSS实现网页背景半透明效果
2021/12/06 HTML / CSS
浅析Python OpenCV三种滤镜效果
2022/04/11 Python