天天看點

微信支付之認識微信支付開發

這一篇開始對微信支付細節進行解釋和開發

1.擷取openid,這個比較簡單,上一篇已經講到,通過appid,appsecret請求微信接口擷取,具體看https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_4

2.設定測試授權目錄,這個目錄(也就是請求位址)就是你調用支付請求的位址。比如我調用支付的位址是http:/user/userPay.do,那麼測試授權目錄就填寫http:/user/即可,要注意大小寫要完全一緻

3.擷取微信版本号https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_5,這個步驟就是用來驗證使用者的微信版本支不支援微信支付功能

4.擷取預支付回話辨別prepay_id,擷取prepay_id,就是通過https協定,用POST方式,向微信統一下單接口https://api.mch.weixin.qq.com/pay/unifiedorder發送xml格式請求,傳回資料也是xml格式;

a.這是微信官方文檔所要求的請求參數清單

微信支付之認識微信支付開發
微信支付之認識微信支付開發
微信支付之認識微信支付開發

注意看參數清單,參數名稱都為小寫字母,而且有些參數是必填,有些是非必填的。

要注意的第一個參數是:簽名(sign),簽名的擷取就是對其他所有參數進行處理後的結果,具體操作如下

微信支付之認識微信支付開發

第一步,先把所有參數放到一個map中(要十分注意,這裡的參數名全是小寫!小寫!小寫)

<span style="font-family:SimSun;"><span style="font-size:18px;">Map map = new HashMap();
            map.put("appid",appid);
            map.put("mch_id",mch_id);
            map.put("nonce_str",noncestr);
            map.put("body","test");
            map.put("out_trade_no",out_trade_no);
            map.put("total_fee","1");
            map.put("spbill_create_ip",add);
            map.put("notify_url",notify_url);
            map.put("trade_type","JSAPI");
	    //trade_type=JSAPI,此參數必傳,使用者在商戶appid下的唯一辨別</span>
            <span style="white-space:pre">	</span>  <span style="font-size:18px;">map.put("openid",openid);</span></span>
           

第二步,在工具類中建立一個擷取sign的方法

<span style="font-family:SimSun;font-size:18px;">public static String getSign(Map<String,Object> map){
        ArrayList<String> list = new ArrayList<String>();
        for(Map.Entry<String,Object> entry:map.entrySet()){
            if(entry.getValue()!=""){
                list.add(entry.getKey() + "=" + entry.getValue() + "&");
            }
        }
        int size = list.size();
        String [] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < size; i ++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();</span>
           
<span style="font-family:SimSun;font-size:18px;"><span style="white-space:pre">	</span><span style="background-color: rgb(255, 204, 153);">//這裡的key就是在微信支付商戶平台中的賬戶設定--API安全--設定秘鑰中設定</span>
        result += "key=" + Constant.key;
        result = MD5.MD5Encode(result).toUpperCase();
        return result;
    }</span>
           

這樣就可以獲得參數sign;

第二個要注意的參數是商戶訂單号,其實這個倒沒什麼難度的,官方文檔的解釋是:商戶系統内部的訂單号,32個字元内、可包含字母。我自己的做法是用10位的時間戳再加上22位的随機字元串。

第三個要注意的參數是open_id,當參數trade_type為JSAPI時,open_id必填,很多人也是忽略了這一點,導緻了簽名錯誤!!

b.參數了解清楚和擷取後,就可以構造xml格式資料請求微信統一下單接口https://api.mch.weixin.qq.com/pay/unifiedorder,必須是通過https協定,以POST方式請求

String xml="<xml>"+
                    "<appid>"+appid+"</appid>"+
                    "<mch_id>"+mch_id+"</mch_id>"+
                    "<nonce_str>"+noncestr+"</nonce_str>"+
                    "<body><![CDATA["+"test"+"]]></body>"+
                    "<out_trade_no>"+out_trade_no+"</out_trade_no>"+
                    //金額,這裡寫的1 分到時修改
                    "<total_fee>"+1+"</total_fee>"+
                    "<spbill_create_ip>"+add+"</spbill_create_ip>"+
                    "<notify_url>"+notify_url+"</notify_url>"+
                    "<trade_type>"+"JSAPI"+"</trade_type>"+
                    "<openid>"+openid+"</openid>"+
                    "<sign>"+signature+"</sign>"+
                    "</xml>";
           

如果請求的資料正确的話,就會出現xml傳回資料,其中就有我們需要的prepay_id,若是沒有成功傳回資料,肯定是參數錯誤、參數名大小寫問題,或者請求的方法不對,回頭細心檢查一下。(官方文檔也有列舉出錯誤代碼,可以對應不同的錯誤碼進行檢查https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)

微信支付之認識微信支付開發

(騰訊還自動識别了一個OK的表情,有點萌萌的)

好啦,這樣第一個難題就解決了。得到所需的prepay_id。

5.現在就可以進入網頁調用支付接口的步驟了。這是官方文檔:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7

微信支付之認識微信支付開發

問題來了,一定要千萬注意這裡的變量名,第二個單詞的首字母變成了大寫,就是這麼坑,不注意的話,等一下生成簽名就會報錯!!!

公衆号id,時間戳,随機字元串,簽名方式都不是難題,package的值就是我們上面擷取的prepay_id,送出格式如:prepay_id=***,簽名paysign的值,就是把對應的參數名和參數放到map裡,通過上面的擷取簽名的方法來獲得簽名。

這些參數都是我們在背景獲得,然後傳到前端調用,調用微信支付接口的方法,官方文檔已經給出來了:

微信支付之認識微信支付開發

如果參數計算正确的話,将會出現支付視窗

微信支付之認識微信支付開發

大功告成,但是很多人在這裡傳回的接口是get_brand_wcpay_request:fail,如果出現這個錯誤,基本是就是參數錯誤或者支付測試目錄填寫有誤!

第一次編輯,有點亂,大家将就着看吧。

繼續閱讀