微信H5支付

當咱們脫離微信瀏覽器進行微信支付(以前的微信支付只能在微信瀏覽器下完成支付)時,就須要使用H5來調整到不一樣的瀏覽器頁面來完成微信支付。最佳場景就是手機端wap完成微信支付。php

 

本篇文件來聊聊微信服務商模式以及商戶模式下微信H5支付git

先說一個事情。8月1號開始微信公衆平臺支付的開發配置頁面遷移至商戶平臺 詳細說明參考這個或者看下面的截圖web

平臺公告   微信支付商戶平臺.png

官方文檔 
普通商戶版-微信H5支付 
服務商版-微信H5支付ajax

一、申請開通微信H5支付

服務商模式下H5支付

服務商模式下點擊申請開通會當即開通,邀請子商戶時須要填寫子商戶的信息。服務商模式下與商戶模式下主要的區別在於商戶模式下不用填寫特約商戶信息、只須要填寫商戶H5支付相關的信息 以下圖api

服務商H5支付

服務商H5支付產品設置 - 微信支付商戶平臺

注意 
填寫的H5支付域名必須是對應網站備案的域名且備案主體還得與商戶的主體信息一致。不然申請的時候不給予經過。審覈反饋的週期不是很長通常是隔天就能夠給出反饋。瀏覽器

二、接口流程圖以及常見錯誤

接口流程圖

簡單點歸納 
一、用戶使用非微信客戶端瀏覽器下單 
二、調用微信支付接口下單獲得H5支付URL的跳轉連接 
三、跳轉到微信喚起微信支付 
四、支付成功異步經過 
五、處理支付結果安全

詳細流程介紹微信

一、用戶在商戶側完成下單,使用微信支付進行支付 
二、由商戶後臺向微信支付發起下單請求(調用統一下單接口)注:交易類型trade_type=MWEB 
三、統一下單接口返回支付相關參數給商戶後臺,如支付跳轉url(參數名「mweb_url」),商戶經過mweb_url調起微信支付中間頁 
四、中間頁進行H5權限的校驗,安全性檢查(此處常見錯誤請見下文) 
五、如支付成功,商戶後臺會接收到微信側的異步通知 
六、用戶在微信支付收銀臺完成支付或取消支付,返回商戶頁面(默認爲返回支付發起頁面) 
七、商戶在展現頁面,引導用戶主動發起支付結果的查詢 
8,九、商戶後臺判斷是否接到收微信側的支付結果通知,如沒有,後臺調用咱們的訂單查詢接口確認訂單狀態 
十、展現最終的訂單支付結果給用戶網絡

常見錯誤:微信公衆平臺

一、網絡環境未能經過安全驗證,請稍後再試(IP改變致使的) 
二、商家參數格式有誤,請聯繫商家解決(H5支付的referer爲空致使) 
三、商家存在未配置的參數,請聯繫商家解決(H5支付的域名問題) 
四、支付請求已失效,請從新發起支付(有效期爲5分鐘) 
五、請在微信外打開訂單,進行支付(H5支付不能直接在微信客戶端內調起)

三、統一下單獲取支付的URL

你作過掃碼支付、公衆號支付以及App支付嗎?若是作過那H5支付就至關簡單了,與前面的提到的幾種支付方式統一下單的URL是同樣的只是個別請求參數不一樣而已(trade_type爲MWEB、scene_info必填)。若是沒有作過也沒有關係下面就是詳細的案例了。

/**
     * 微信H5 支付
     */
    public void wapPay(){
        String ip = IpKit.getRealIp(getRequest());
        if (StrKit.isBlank(ip)) {
            ip = "127.0.0.1";
        }

        H5ScencInfo sceneInfo = new H5ScencInfo();

        H5 h5_info = new H5();
        h5_info.setType("Wap");
        h5_info.setWap_url("https://pay.qq.com");
        h5_info.setWap_name("騰訊充值");
        sceneInfo.setH5_info(h5_info);

        Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig()
                .setAttach("IJPay H5支付測試  -By Javen")
                .setBody("IJPay H5支付測試  -By Javen")
                .setSpbillCreateIp(ip)
                .setTotalFee("520")
                .setTradeType(TradeType.MWEB)
                .setNotifyUrl(notify_url)
                .setOutTradeNo(String.valueOf(System.currentTimeMillis()))
                .setSceneInfo(h5_info.toString())
                .build();

        String xmlResult = WxPayApi.pushOrder(false,params);
log.info(xmlResult);
        Map<String, String> result = PaymentKit.xmlToMap(xmlResult);

        String return_code = result.get("return_code");
        String return_msg = result.get("return_msg");
        if (!PaymentKit.codeIsOK(return_code)) {
            ajax.addError(return_msg);
            renderJson(ajax);
            return;
        }
        String result_code = result.get("result_code");
        if (!PaymentKit.codeIsOK(result_code)) {
            ajax.addError(return_msg);
            renderJson(ajax);
            return;
        }
        // 如下字段在return_code 和result_code都爲SUCCESS的時候有返回

        String prepay_id = result.get("prepay_id");
        String mweb_url = result.get("mweb_url");

        renderText("prepay_id:"+prepay_id+" mweb_url:"+mweb_url);
    }

在手機瀏覽器中訪問mweb_url便可喚起微信進行支付

更正 20170830 
一、上面複製mweb_url到手機瀏覽器訪問會出現網絡環境未能經過安全驗證,請稍後再試 爲何呢? 由於發起支付與喚起支付的IP不一致 
二、微信H5支付必須在設置的域名(商戶平臺–」產品中心」–」開發配置」)網頁中發起支付否則會出現商家參數格式有誤,請聯繫商家解決 爲何呢? 由於微信H5支付須要驗證支付的referer

更正後的代碼以下:

/**
     * 微信H5 支付
     * 注意:必須再web頁面中發起支付且域名已添加到開發配置中
     */
    public void wapPay(){
        String ip = IpKit.getRealIp(getRequest());
        if (StrKit.isBlank(ip)) {
            ip = "127.0.0.1";
        }

        H5ScencInfo sceneInfo = new H5ScencInfo();

        H5 h5_info = new H5();
        h5_info.setType("Wap");
        //此域名必須在商戶平臺--"產品中心"--"開發配置"中添加
        h5_info.setWap_url("https://pay.qq.com");
        h5_info.setWap_name("騰訊充值");
        sceneInfo.setH5_info(h5_info);

        Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig()
                .setAttach("IJPay H5支付測試  -By Javen")
                .setBody("IJPay H5支付測試  -By Javen")
                .setSpbillCreateIp(ip)
                .setTotalFee("520")
                .setTradeType(TradeType.MWEB)
                .setNotifyUrl(notify_url)
                .setOutTradeNo(String.valueOf(System.currentTimeMillis()))
                .setSceneInfo(h5_info.toString())
                .build();

        String xmlResult = WxPayApi.pushOrder(false,params);
log.info(xmlResult);
        Map<String, String> result = PaymentKit.xmlToMap(xmlResult);

        String return_code = result.get("return_code");
        String return_msg = result.get("return_msg");
        if (!PaymentKit.codeIsOK(return_code)) {
            ajax.addError(return_msg);
            renderJson(ajax);
            return;
        }
        String result_code = result.get("result_code");
        if (!PaymentKit.codeIsOK(result_code)) {
            ajax.addError(return_msg);
            renderJson(ajax);
            return;
        }
        // 如下字段在return_code 和result_code都爲SUCCESS的時候有返回

        String prepay_id = result.get("prepay_id");
        String mweb_url = result.get("mweb_url");

        System.out.println("prepay_id:"+prepay_id+" mweb_url:"+mweb_url);
        redirect(mweb_url);
    }

在Web頁面中發起支付

若是你下載的是Jfinal版本的Demo 訪問的URL爲 
http://域名:端口號/toWxH5Pay

具體實現能夠參考開源項目 IJPay 讓支付觸手可及