使用 weixin-java-tools 完成微信受权登陆、微信支付

做者码云地址:点我php

// 受权登陆用到
        <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跳转到指定页面在指定页面调用方法:java

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("登陆失败");
        }
    }

前端保存下用户信息就完事了。git

我的理解的微信支付流程:用户页面点击<微信支付>按钮 后端调用 <微信统一下单> 统一下单返回参数 ,前端使用 <统一下单>返回的参数唤起微信支付。
商户中须要在api安全中设置不少东西... 就不一一赘述了
微信支付官方api 前端:点我
后端api点我
商户登陆地址 点我github

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会提示一些具体信息ajax

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后的支付和受权仍是很方便的,麻烦的是微信方面的一些配置和流程... 很坑。
感谢sdk做者。
至此微信支付完成。
记录下代码方便下次使用。api

相关文章
相关标签/搜索