使用 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

相關文章
相關標籤/搜索