微信公衆號開發03----微信支付

1、微信支付之Native支付

關於如何開通微信支付大家可以直接去【微信支付】官網查閱。這裏我們直接進入正題。

1.1 Native支付場景(以電商網站爲例)

設置商品價格
支付成功
支付失敗
用戶購買商品
支付界面生成付款二維碼
用戶掃碼付款
生成支付訂單
付款失敗界面

1.2 支付場景示例圖

在這裏插入圖片描述

1.3 核心代碼

1.3.1 統一下單封裝後的方法
public static WeixinPayResult createNative(String callbackUrl, String app_id, String mch_id, String api_key, String out_trade_no, Integer total_fee, String body) {
        //1.參數封裝
        Map param = new HashMap();
        param.put("appid", app_id);//公衆賬號ID
        param.put("mch_id", mch_id);//商戶
        param.put("nonce_str", WXPayUtil.generateNonceStr());//隨機字符串
        param.put("body", body);
        param.put("out_trade_no", out_trade_no);//交易訂單號(是由系統內部來生成)
        param.put("total_fee", total_fee.toString());//金額(分)
        param.put("spbill_create_ip", "127.0.0.1");//支付客戶端的IP地址(這裏沒做記錄)
        param.put("notify_url", callbackUrl);
        param.put("trade_type", "NATIVE");//交易類型
        try {
            //根據appkey來生成簽名,並同時將參數進行轉換爲xml格式
            String xmlParam = WXPayUtil.generateSignedXml(param, api_key);
            //2.發送請求(按照官方接口要求,將數據以post請求方式發送)
            HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
            httpClient.setHttps(true);//以https的協議發送請求
            httpClient.setXmlParam(xmlParam);//設置post請求的參數列表
            httpClient.post();
            //3.獲取結果
            String xmlResult = httpClient.getContent();
            Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
            //將返回的結果轉換爲對象
            WeixinPayResult weixinPayResult = new WeixinPayResult();
            //防止進行bean複製時,日期爲null時報錯
            ConvertUtils.register(new DateConverter(null), Date.class);
            BeanUtils.copyProperties(weixinPayResult, mapResult);
            //注意:付款訂單編號是後臺動態生成,必須要手動添加到返回結果中  勿忘,切記!!!
            weixinPayResult.setOut_trade_no(out_trade_no);
            return weixinPayResult;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
  • 封裝統一下單涉及到的工具類WXPayUtil.java代碼需要導入微信支付開發的pom座標
<!-- 微信支付所需的依賴包-->
        <dependency>
            <groupId>com.github.wxpay</groupId>
            <artifactId>wxpay-sdk</artifactId>
            <version>0.0.3</version>
        </dependency>
        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.10</version>
        </dependency>
1.3.2 根據訂單號查詢訂單狀態
public static WeixinPayResult queryPayStatus(String app_id, String mch_id, String api_key, String out_trade_no) {
        Map resultMap = new HashMap();
        //1.封裝參數
        Map param = new HashMap();
        param.put("appid", app_id);//appid
        param.put("mch_id", mch_id);//商戶ID
        param.put("out_trade_no", out_trade_no);//要查詢的訂單號(自己系統所生成訂單號)
        param.put("nonce_str", WXPayUtil.generateNonceStr());
        try {
            String xmlParam = WXPayUtil.generateSignedXml(param, api_key);
            //2.發送請求
            HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
            httpClient.setHttps(true);
            httpClient.setXmlParam(xmlParam);
            httpClient.post();
            //3.獲取結果
            String xmlResult = httpClient.getContent();
            Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
            //封裝結果數據
            WeixinPayResult weixinPayResult = new WeixinPayResult();
            //防止進行bean複製時,日期爲null時報錯
            ConvertUtils.register(new DateConverter(null), Date.class);
            BeanUtils.copyProperties(weixinPayResult, mapResult);
            return weixinPayResult;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
1.3.3 關於生成付款碼時的回調方法應用(重點!重點!重點!)

相信很多新手在使用【微信支付】接口時,都會選擇在前端設置定時器來間隔查詢,如果查詢到訂單狀態爲【支付成功】再走生成訂單的流程。如這種方法的操作是非常錯誤的,而且還有非常多的安全隱患。

  • 正確處理查看支付成功並處理後續業務的流程如下:
設置回調參數callback
支付成功
支付失敗
創建統一下單接口
界面展示付款碼
用戶掃碼支付
觸發回調參數callback的請求
調用查詢訂單狀態接口確定付款成功
觸發回調參數callback的請求,並返回失敗的結果
失敗結果返回給前端

你沒看錯,流程圖也沒畫錯。其實正確的付款支付接口時,生成的付款碼和查詢訂單支付狀態是兩個完全獨立的操作。

  • 前端在調用[統一下單]接口並生成【付款碼】後,這步操作就結束
  • 當用戶掃碼後,無論付款成功還是失敗,只要完成這個掃碼操作,就會調用【統一下單】接口中所配置的callback回調url。
  • 這種實現方式優點:
    1. 支持離線支付(複製付款碼後,可以關閉當前付款頁面,只要掃碼成功支付,購買成功業務都會執行)
    2. 支持代付(用戶可以把付款碼截圖發給其他人代付)
    3. 安全性高

1.3.4 附加回調的方法

防止有些朋友不知道回調方法怎麼寫,這裏也貼出回調方法的實現

  • 如果你在調用【統一下單】封裝方法,傳入的callback參數值爲
    callbackUrl: http://你服務器的回調方法根路徑/callbackpay
    那麼就應該在你當前工程的方法中,添加一個回調方法的實現
/**
     * 微信支付成功後的回調函數
     */
    @RequestMapping("/callbackpay")
    public Result callbackPay(HttpServletRequest request) {
        StringBuffer sb = new StringBuffer();
        try {
            List<String> readLines = IOUtils.readLines(request.getInputStream(), "utf-8");
            for (String readLine : readLines) {
                sb.append(readLine);
            }
            Map<String, String> mapResult = WXPayUtil.xmlToMap(sb.toString());
            //防止進行bean複製時,日期爲null時報錯
            ConvertUtils.register(new DateConverter(null), Date.class);
            WeixinPayResult weixinPayResult = new WeixinPayResult();
            BeanUtils.copyProperties(weixinPayResult, mapResult);
            return weixinPayService.callbackPay(weixinPayResult);//這行代碼是調用業務層的付款成功後的處理邏輯
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, "服務器異常");
        }
    }

注意:最後提醒一下,上面這個回調方法的url,一定要記得在你的權限框架中放行

下一章會介紹【微信支付----- 微信紅包和企業付款到微信用戶零錢】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章