天天看點

微信支付01

最近因為項目要做微信支付、是以把過程記錄下來以備以後會需要到。

1.微信支付文檔:https://open.swiftpass.cn/openapi/doc?index_1=5&index_2=1&chapter_1=30&chapter_2=32#

2.因為項目是Java的、是以我下載下傳了Java的demo

如下:

這裡的servlet就是主要的方法:測試支付、訂單狀态查詢、通知、測試退款、退款查詢幾個方法、這些都有針對的APi文檔可以檢視;

1.測試支付

1 public String wechatPay(HttpServletRequest req, HttpServletResponse resp, DOPayBean bean) throws ServletException, IOException {
  2         Map<String,String> orderResult = new HashMap<String, String>(); //用來存儲訂單的交易狀态(key:訂單号,value:狀态(0:未支付,1:已支付))  ---- 這裡可以根據需要存儲在資料庫中
  3         req.setCharacterEncoding("utf-8");
  4         resp.setCharacterEncoding("utf-8");
  5         
  6         SortedMap<String,String> map = XmlUtils.getParameterMap(req);
  7         
  8           9         map.put("mch_id", "175510359638");
 10         //重複送出的時候直接查詢本地的狀态
 11        /* if(orderResult != null && orderResult.containsKey(map.get("out_trade_no"))){
 12             String status = "0".equals(orderResult.get(map.get("out_trade_no"))) ? "未支付" : "已支付";
 13             resp.setHeader("Content-type", "text/html;charset=UTF-8");
 14             resp.getWriter().write(status);
 15         }else{*/
 16             map.put("notify_url", "http://wasdsad.net/card/swpay/pay_notify_alipay_pay.html");
 17            // map.put("out_trade_no", "2017060612004115998");
 18             map.put("out_trade_no", "2017060612004115999");
 19             
 20             map.put("service", "pay.weixin.wappay");
 21             map.put("version", "2.0");
 22             map.put("charset", "UTF-8");
 23             map.put("sign_type", "MD5");
 24             map.put("body", "測試購買商品");
 25             map.put("attach", "附加資訊");
 26             map.put("total_fee", "1");
 27             map.put("mch_create_ip", "127.0.0.1");
 28             
 29             map.put("nonce_str", String.valueOf(new Date().getTime()));
 30             map.put("callback_url","https://www.baidu.com/");//前端頁面跳轉位址(包括支付成功和關閉時都會跳到這個位址)
 31             
 32             //注意:device_info、mch_app_name、mch_app_id這三個具體傳值必須以文檔說明為準,傳真實有效的,否則有可能無法正常支付!!!
 33             map.put("device_info", "AND_SDK");
 34             map.put("mch_app_name", "王者榮耀");
 35             map.put("mch_app_id", "com.tencent.tmgp.sgame");
 36             Map<String,String> params = SignUtils.paraFilter(map);
 37             StringBuilder buf = new StringBuilder((params.size() +1) * 10);
 38             SignUtils.buildPayParams(buf,params,false);
 39             String preStr = buf.toString();
 40             String sign = MD5.sign(preStr, "&key=" + "61307e5f2aebcacecb****fe5296df9c", "utf-8");
 41             map.put("sign", sign);
 42             
 43             String reqUrl = "https://pay.swiftpass.cn/pay/gateway";
 44             System.out.println("reqUrl:" + reqUrl);
 45             
 46             System.out.println("reqParams:" + XmlUtils.parseXML(map));
 47             CloseableHttpResponse response = null;
 48             CloseableHttpClient client = null;
 49             String res = null;
 50             try {
 51                 HttpPost httpPost = new HttpPost(reqUrl);
 52                 StringEntity entityParams = new StringEntity(XmlUtils.parseXML(map),"utf-8");
 53                 httpPost.setEntity(entityParams);
 54                 //httpPost.setHeader("Content-Type", "text/xml;charset=ISO-8859-1");
 55                 client = HttpClients.createDefault();
 56                 response = client.execute(httpPost);
 57                 if(response != null && response.getEntity() != null){
 58                     Map<String,String> resultMap = XmlUtils.toMap(EntityUtils.toByteArray(response.getEntity()), "utf-8");
 59                     res = XmlUtils.toXml(resultMap);
 60                     System.out.println("請求結果:" + res);
 61                     
 62                     if(resultMap.containsKey("sign")){
 63                         if(!SignUtils.checkParam(resultMap, SwiftpassConfig.key)){
 64                             res = "驗證簽名不通過";
 65                         }else{
 66                             if("0".equals(resultMap.get("status")) && "0".equals(resultMap.get("result_code"))){
 67                                 if(orderResult == null){
 68                                     orderResult = new HashMap<String,String>();
 69                                 }
 70                                 orderResult.put(map.get("out_trade_no"), "0");//初始狀态
 72                                 String pay_info = resultMap.get("pay_info");
 75                                 resp.sendRedirect(pay_info);   //這裡直接挑轉到微信支付的頁面
 81                             }else{
 82                                 req.setAttribute("result", res);
 83                             }
 84                         }
 85                     } 
 86                 }else{
 87                     res = "操作失敗";
 88                 }
 89             } catch (Exception e) {
 90                 e.printStackTrace();
 91                 res = "系統異常";
 92             } finally {
 93                 if(response != null){
 94                     response.close();
 95                 }
 96                 if(client != null){
 97                     client.close();
 98                 }
 99             }
100             if(res.startsWith("<")){
101                 resp.setHeader("Content-type", "text/xml;charset=UTF-8");
102             }else{
103                 resp.setHeader("Content-type", "text/html;charset=UTF-8");
104             }
105             resp.getWriter().write(res);
106             return res;
107         //}
108     }
109           

注 :1.因為是用于測試,是以目前把所有參數都是寫死的。這樣根據以上代碼就可以完成支付了,給自己開發的時候就要換上自己的key和商戶号這些參數了

        2. notify_url這個參數必須要傳給一個可以在公網上接收到的接口中、可以是接口、可以是方法(我本地用的是nat123 -- 友善開發測試、這個工具把本地的端口映射到公網、然後在支付的時候配置的接收通知的接口);下篇将講述接受通知的方法。