最近接觸了一些比較新奇的東西,記錄一下php
先貼出微信官方的API地址,感覺一下微信的魅力。。。html
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_6java
瞭解完微信下載帳單的一些注意事項以後,我們正式開始數據庫
下面是具體實現:apache
先貼出主方法,其餘工具類會有具體說明:json
public static void main(String[] args) throws Exception { // downloadBill(); } public static void downloadBill() throws Exception { //這裏的MyConfig工具類是本身封裝的一些配置,爲了方便本身使用,你們能夠跳過這一步 MyConfig myConfig = new MyConfig(); SortedMap<Object,Object> parameters =new TreeMap<Object,Object>(); //這裏面的value值,你們本身根據本身的微信商戶參數配置一下 parameters.put("appid", myConfig.getAppID());//appid parameters.put("mch_id", myConfig.getMchID());//商戶號 parameters.put("nonce_str", CreateNoncestr());//隨機字符串 parameters.put("bill_date", "20180125");//對帳單日期 parameters.put("bill_type", "ALL");//對帳單類型 //這裏調用方法生成微信須要的簽名(這裏是一個坑點,當時在作微信退款的時候由於簽名不符合規範被卡一天時間) String sign = createSign("utf-8", parameters);//簽名 parameters.put("sign", sign); //這裏的getRequestXml方法是轉xml的工具方法,下面我會貼出來 String reuqestXml = getRequestXml(parameters); /** * 這裏的CommonUtil是一個https通用工具類,我也會在下面貼出來 * download_bill_url是微信官方提供的對帳單下載地址 * download_bill_url = 「https://api.mch.weixin.qq.com/pay/downloadbill「 */ String result=CommonUtil.httpsRequest(myConfig.download_bill_url, "POST", reuqestXml); //微信對帳單生成時間是第二天的9點以後,因此查詢日期爲當天時,錯誤信息提示日期無效 if(result.startsWith("<xml>")){ System.out.println(result); System.out.println("無訂單"); }else { String tradeMsg = result.substring(result.indexOf("`")); String tradeInfo = tradeMsg.substring(0, tradeMsg.indexOf("總")).replace("`", "");// 去掉彙總數據,而且去掉'`' String tradeInfo = tradeMsg.substring(0,tradeMsg.indexOf("總")); String tradeTotalMsg =tradeMsg.substring(tradeMsg.indexOf("總")); String tradeTotalInfo =tradeTotalMsg.substring(tradeTotalMsg.indexOf("`")); System.out.println("result----->"+result); System.out.println("tradeMsg----->"+tradeMsg); System.out.println("tradeInfo----->"+tradeInfo); System.out.println("tradeTotalMsg----->"+tradeTotalMsg); System.out.println("tradeTotalInfo----->"+tradeTotalInfo); //最後一欄是費率,裏面以%結尾,以此做爲切割目標,方便操做存數據庫 String[] tradeArray = tradeInfo.split("%"); List<Map<String, Object>> resultList = new ArrayList<>(); for(int i = 0;i < tradeArray.length;i++) { String[] tradeDetailArray = tradeArray[i].split(","); Map<String, Object> map = new HashMap<>(); /** * 這裏我取了幾個對我來講用處較大的幾個字段 * 詳細字段的話,你們能夠參考一下這裏,或本身看控制檯打印結果 * https://www.cnblogs.com/mgqy/articles/7657483.html */ map.put("readeTime", tradeDetailArray[0]);//交易時間 map.put("appid", tradeDetailArray[1]);//公衆號ID map.put("mchId", tradeDetailArray[2]);//商戶號 map.put("transactionId", tradeDetailArray[5]);//微信訂單號 map.put("outTradeNo", tradeDetailArray[6]);//商戶訂單號 map.put("openid", tradeDetailArray[7]);//用戶標識(openid) map.put("tradeState", tradeDetailArray[9]);// 交易狀態 map.put("tradeBank", tradeDetailArray[10]);// 付款銀行 map.put("totalFee", tradeDetailArray[12]);//總金額 map.put("refundFee", tradeDetailArray[16]);//退款金額 map.put("tradeName", tradeDetailArray[20]);// 商品名稱 map.put("poundage", tradeDetailArray[22]);//手續費 resultList.add(map); } System.out.println("resultList--->"+resultList); } }
下面是一些用到的工具類和方法:api
一、隨機字符串生成方法微信
/** * 隨機字符串 * @return */ public static String CreateNoncestr() { String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; String res = ""; for (int i = 0; i < 16; i++) { Random rd = new Random(); res += chars.charAt(rd.nextInt(chars.length() - 1)); } return res; }
二、編寫簽名方法app
/** * 編寫簽名 * @param charSet * @param parameters * @return * @throws Exception */ public static String createSign(String charSet,SortedMap<Object,Object> parameters) throws Exception{ MyConfig myconfig = new MyConfig(); StringBuffer sb = new StringBuffer(); Set es = parameters.entrySet(); Iterator it = es.iterator(); while(it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); String k = (String)entry.getKey(); Object v = entry.getValue(); if(null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) { sb.append(k + "=" + v + "&"); } } sb.append("key=" + myconfig.getKey()); // String sign = MD5Util.MD5Encode(sb.toString(), charSet).toUpperCase(); String sign = MD5Util.MD5Encode(sb.toString(), charSet).toUpperCase(); // String sign = MD5.MD5Encode(sb.toString(), charSet).toUpperCase(); return sign; }
三、轉xml格式方法dom
/** * 轉爲xml格式 * @param parameters * @return */ public static String getRequestXml(SortedMap<Object,Object> parameters){ StringBuffer sb = new StringBuffer(); sb.append("<xml>"); Set es = parameters.entrySet(); Iterator it = es.iterator(); while(it.hasNext()) { Map.Entry entry = (Map.Entry)it.next(); String k = (String)entry.getKey(); String v = (String)entry.getValue(); if ("attach".equalsIgnoreCase(k)||"body".equalsIgnoreCase(k)||"sign".equalsIgnoreCase(k)) { sb.append("<"+k+">"+"<![CDATA["+v+"]]></"+k+">"); }else { sb.append("<"+k+">"+v+"</"+k+">"); } } sb.append("</xml>"); return sb.toString(); }
四、https通用工具類
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ConnectException; import java.net.URL; import javax.net.ssl.HttpsURLConnection; import org.apache.log4j.Logger; import net.sf.json.JSONObject; /** * https通用工具類 */ public class CommonUtil { private static Logger log = Logger.getLogger(CommonUtil.class); public static JSONObject httpsRequestToJsonObject(String requestUrl, String requestMethod, String outputStr) { JSONObject jsonObject = null; try { String buffer = httpsRequest(requestUrl, requestMethod, outputStr); jsonObject = JSONObject.fromObject(buffer.toString()); } catch (Exception e) { log.error("https請求異常:"+e.getMessage()); } return jsonObject; } public static String httpsRequest(String requestUrl, String requestMethod, String outputStr){ try { URL url = new URL(requestUrl); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); // 設置請求方式(GET/POST) conn.setRequestMethod(requestMethod); conn.setRequestProperty("content-type", "application/x-www-form-urlencoded"); // 當outputStr不爲null時向輸出流寫數據 if (null != outputStr) { OutputStream outputStream = conn.getOutputStream(); // 注意編碼格式 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 從輸入流讀取返回內容 InputStream inputStream = conn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; StringBuffer buffer = new StringBuffer(); while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } // 釋放資源 bufferedReader.close(); inputStreamReader.close(); inputStream.close(); inputStream = null; conn.disconnect(); return buffer.toString(); } catch (ConnectException ce) { System.out.println("鏈接超時:{}"); } catch (Exception e) { System.out.println("https請求異常:{}"); } return null; } }
到此,微信下載對帳單功能就實現了
代碼寫的很差之處,請你們多多包涵並提出寶貴意見 937017870@qq.com