1. 程式人生 > >Java呼叫微信掃碼支付介面(模式二)

Java呼叫微信掃碼支付介面(模式二)

前些天幫朋友實現了一個微信掃碼的介面,在之前也是不會搞這個東西,抱著試試的心態就開始看各種文件和blogs,大多數人都在吐槽微信給的java呼叫微信介面文件太含糊,而且網上的查到的資料也不詳細,只有大概的開發流程沒有太多細節上的講解,最後還是花了一些錢買了一套視訊和demo(理清了我的思路),最後完成了開發,如果有同學需要的話可以給我留言,我將免費提供幫助(可能不能及時回覆)。

(在這之間我們需要申請商家號)首先我們要理清思路要怎麼進行掃碼介面呼叫開發:
這裡寫圖片描述
圖自己畫的不太好,見諒。

從圖中可以看出微信掃碼支付的大概流程,首先是下單,我們需要拼接一個xml(包含商戶平臺ID,價格,隨機數等資訊)傳送給微信介面,首先我們要知道,我們和微信介面之間的資訊傳遞都需要使用xml,所以在開發中xml資訊的拼接和解析是至關重要的。


傳送統一下單的xml,首先我們應該知道需要將哪些資訊拼接成xml資訊:
這裡寫圖片描述

這個是我們的一些必須清單:
APP_ID
這裡寫圖片描述
這個APP_ID我就填錯了(當時沒找到APP_ID),一直報空指標錯誤。

MCH_ID這個是商家號:
這裡寫圖片描述
就是我塗鴉的那個部分,申請過商戶平臺賬號後會給你分配一個賬號。

API_KEY:
這裡寫圖片描述

這裡寫圖片描述
在這個頁面可以檢視API_KEY,如果忘了就重置一下。

NOTIFY_URL:這個是回撥地址(支付成功後,微信介面返回給我們的url,一定要是公網可以訪問的,不能是我們的本地localhost)。

CREATE_IP:這個東西可有可無,隨便填寫一個ip就行了。

//返回可生成二維碼的urlCode,這裡面用到了一些工具(拼接解析xml和傳送http請求)
String out_trade_no = "" + System.currentTimeMillis(); //訂單號 
        // 賬號資訊 
        String appid = PayConfigUtil.APP_ID;  // appid  
        //String appsecret = PayConfigUtil.APP_SECRET; // appsecret  
        String mch_id = PayConfigUtil.MCH_ID; // 商業號  
        String
key = PayConfigUtil.API_KEY; // key String currTime = PayToolUtil.getCurrTime(); String strTime = currTime.substring(8, currTime.length()); String strRandom = PayToolUtil.buildRandom(4) + ""; String nonce_str = strTime + strRandom; // 獲取發起電腦 ip String spbill_create_ip = PayConfigUtil.CREATE_IP; // 回撥介面 String notify_url = PayConfigUtil.NOTIFY_URL; String trade_type = "NATIVE"; SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>(); packageParams.put("appid", appid); //packageParams.put("appsecret", appsecret); packageParams.put("mch_id", mch_id); //隨機字串 packageParams.put("nonce_str", nonce_str); packageParams.put("body", "報名費用"); //(調整為自己的名稱) packageParams.put("out_trade_no", out_trade_no); if(productId.equals("1")) { packageParams.put("total_fee", "1");//一級費用240元,價格的單位為分 }else if(productId.equals("2")) { packageParams.put("total_fee", "28000"); }else if(productId.equals("3")) { packageParams.put("total_fee", "32000"); }else if(productId.equals("4")) { packageParams.put("total_fee", "36000"); }else if(productId.equals("5")) { packageParams.put("total_fee", "42000"); }else{ packageParams.put("total_fee", "48000"); } packageParams.put("spbill_create_ip", spbill_create_ip); packageParams.put("notify_url", notify_url); packageParams.put("trade_type", trade_type); String sign = PayToolUtil.createSign("UTF-8", packageParams,key); packageParams.put("sign", sign); String requestXML = PayToolUtil.getRequestXml(packageParams); requestXML= requestXML.replaceAll("__", "_"); System.out.println("請求xml:"+requestXML); //記錄請求商戶訂單號 Map<String,String> out_map = XMLUtil4jdom.doXMLParse(requestXML); String out_no = (String) out_map.get("out_trade_no"); System.out.println("第一次商戶號:"+out_no); //接下來儲存商戶訂單號和使用者(身份證號)對應關係 //////////////這裡執行資料庫邏輯//////////////////// String resXml = HttpUtil.postData(PayConfigUtil.UFDODER_URL, requestXML); System.out.println("響應xml:"+resXml); Map<String,String>map = XMLUtil4jdom.doXMLParse(resXml); String urlCode = (String) map.get("code_url"); //code_url //System.out.println(urlCode); return urlCode;

我們需要知道首先我們應該將需要傳送的資訊放入map中,然後將它們拼接成xml,然後傳送給微信,然後接收來自微信的xml,我們解析這個xml,獲得url_code,就是生成二維碼的content,然後使用谷歌的生成程式碼zxing進行生成二維碼,最後將生成的二維碼通過你想要的方式傳送給前臺。

——————————————————————————————

接下來就是掃碼過後進行資訊的回調了(例如對使用者下單進行資料庫操作),可以使用外部訂單號來唯一標識訂單和使用者。
需要對微信介面回撥的資料(xml)進行解析,比對result_code結果,如果是SUCCESS就是支付成功,如果是FALSE就是支付失敗。

         //讀取引數
        //System.out.println("haha");
        InputStream inputStream ;  
        StringBuffer sb = new StringBuffer();  
        inputStream = request.getInputStream();  
        String s ;  
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));  
        while ((s = in.readLine()) != null){  
            sb.append(s);  
        }  
        in.close();  
        inputStream.close();  
        System.out.println("回撥xml:"+sb.toString());//測試
        //解析xml成map  
        Map<String, String> m = new HashMap<String, String>();  
        try {
            m = XMLUtil4jdom.doXMLParse(sb.toString());
        } catch (JDOMException e) {
            e.printStackTrace();
        }  

        SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();        
        Iterator it = m.keySet().iterator();  
        while (it.hasNext()) {  
            String parameter = (String) it.next();  
            String parameterValue = m.get(parameter);  

            String v = "";  
            if(null != parameterValue) {  
                v = parameterValue.trim();  
            }  
            packageParams.put(parameter, v);  
        }  

        // 賬號資訊  
        String key = PayConfigUtil.API_KEY; // key  


        //判斷簽名是否正確  
        if(PayToolUtil.isTenpaySign("UTF-8", packageParams,key)) {

            //------------------------------  
            //處理業務開始  
            //------------------------------  
            String resXml = "";  
            if("SUCCESS".equals((String)packageParams.get("result_code"))){
               String fee = (String)packageParams.get("total_fee");
               int level;
                if(fee.equals("24000")) {
                    level = 1;
                }else if(fee.equals("28000")) {
                    level = 2;
                }else if(fee.equals("32000")) {
                    level = 3;
                }else if(fee.equals("36000")) {
                    level = 4;
                }else if(fee.equals("42000")) {
                    level = 5;
                }else{
                    level = 6;
                }


                // 這裡是支付成功  
                //接下來對資料庫進行操作 ,先查詢訂單號對應的身份證號
                String out_no = (String)packageParams.get("out_trade_no");
                System.out.println("商家訂單號:"+out_no);

//              Connection conn = DBUtils.getConnection();
//              String sql="insert into uers values(?,?)";
//              
//                try {
//                  PreparedStatement pstmt=(PreparedStatement) conn.prepareStatement(sql);
//                  pstmt.setInt(0, 321333);
//                  pstmt.setInt(1,level);
//              } catch (SQLException e) {
//                  e.printStackTrace();
//              }



                //通知微信.非同步確認成功.必寫.不然會一直通知後臺.八次之後就認為交易失敗了.  
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"  
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";  

            } else {   
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"  
                        + "<return_msg><![CDATA[報文為空]]></return_msg>" + "</xml> ";  
            }  
            //------------------------------  
            //處理業務完畢  
            //------------------------------  
            BufferedOutputStream out = new BufferedOutputStream(  
                    response.getOutputStream());  
            out.write(resXml.getBytes());
            System.out.println("success");
            out.flush();  
            out.close();  
        }  

這些是用到的工具類:
這裡寫圖片描述
關於工具類有點多,這裡就不一一給出了,如果有需要的小夥伴可以留言你的郵箱,我會一一發給你們(可能不及時),如果有不懂的地方也可以和我進行探討(QQ:1399405683),我會給你們講解。

這個例子是自己第一次做的,所以有很多不好的地方,所以還請包含。

限於篇幅,就講到這裡,如有錯誤歡迎指正。