最近在做微信支付相關的業務,在呼叫微信的對賬單介面時,遇到一個當時感覺很頭大的問題,為什麼說當時很頭大呢?因為現在這個問題已經被我解決了!嘿嘿...
好吧,言歸正傳。我遇到的問題就是在呼叫微信的對賬單介面時,微信會返回一個字串給我,而這個字串就包含了賬單名稱以及賬單資料。喏,就是下面這個樣子。
當時看了一臉懵逼,因為看不出任何可以進行解析的特徵,因此不得不又認認真真的看了一遍介面的文件說明,結合著介面文件的說明和自己大膽的假設,最終將該字串解析成自己想要的樣子。接下來就來說說自己的解法吧。
按照文件說明剖析整體結構
從上面的文件說明中,我找出了最關鍵的三句話(用紅框標記),從這個三句話中可以看出字串的結構其實就是:
- 表頭
- 資料記錄
- 彙總表頭
- 彙總資料
所以我就按照這種結構來解析整個字串。 不過在解析之前需要說明,微信給的示例和呼叫介面返回的資料非常的具有迷惑性,它給的資料看不出任何的特別有用特徵,但是當把介面返回字串複製貼上到你IDE編輯區後,你會發現每行資料後面都有一個換行符,但是在文件示例和IDE的Console區中的返回資料中是看不出這一點的。所以當這一點被發現後,其實問題就已經迎刃而解了。
解析對賬單字串
解析對賬單的字串,可以分為以下幾個步驟:
- 解析表頭
- 解析表頭剩下的內容
- 解析交易記錄
- 解析彙總表頭和資料
解析表頭
首先從表頭的解析開始。由文件可知,從第二行開始,每行引數前都有這個符號:*** ***,因此在第一個 ***
*** 符號之前都是表頭的內容。所以到這裡就可以把表頭的內容解析出來了。程式碼如下:
String bill = "\uFEFFTransaction time,Official account ID(appid),Vendor ID(mch_id),Sub vendor ID (sub_mch_id),Device ID(Device_info),Wechat order number(transaction_id),Vendor order number (out_transaction_id),User tag(openid),Transaction type(trade_type),Transaction status(trade_state),Payment bank(bank_type),Currency type(fee_type),Total amount(total_fee),Coupon amount,Wechat refund number (refund_id),Vendor refund number(out_refund_no),Refund amount(refund_fee),Coupon refund amount,Refund type,Refund status(refund_status_$n),Product name,Vendor's data package(attach),Fee,Rate,Payment Currency type(Cash_fee_type),Cash payment amount(Cash_fee),Settlement currency type,Settlement currency amount,Exchange rate,Refund exchange rate,Payer's Refund amount,Payer's Refund currency type,Refund currency type,Refund settlement currency type,Refund settlement amount\n" +
"`2018-08-06 11:57:04,`wxa7ca41f5ddb1d958,`1234567890,`224195623,`,`420000018620180806525649,`UW002807000000052018080600000014,`oRRUM1NqZxiBHzPtpk1iOd-oug0U,`NATIVE,`SUCCESS,`CMB_DEBIT,`NZD,`0.01,`0.00,`0,`0,`0.00,`0.00,`,`,`睡貓 支付-收款,`,`0.00000,`0.50%,`CNY,`0.04,`NZD,`0.01,`461620123,`0,`0,`,`,`,`0.00\n" +
"`2018-08-06 13:13:58,`wxa7ca41f5ddb1d958,`1234567890,`224195623,`,`420000016420180806864932,`UW002808030000022018080600000016,`oRRUM1JH3GFSPDDimcSO9T0pyKMI,`MICROPAY,`SUCCESS,`CFT,`NZD,`0.01,`0.00,`0,`0,`0.00,`0.00,`,`,`productDescribe,`,`0.00000,`0.50%,`CNY,`0.04,`NZD,`0.01,`460927123,`0,`0,`,`,`,`0.00\n" +
"Total transaction count,Total transaction amount,Total refund amount,Total coupon refund amount,Total commission amount\n" +
"`7,`0.07,`0.00,`0.00,`0.00000\n"
String tableHead = bill.substring(0, bill.indexOf("`"));
複製程式碼
解析剩餘的內容
我們可以從Total
這個字串入手,根據它來將剩餘的內容一一解析成我們想要的內容,程式碼如下:
// 獲取表頭以外的其他內容:交易記錄、彙總表頭、彙總資料
String otherContent = bill.substring(bill.indexOf("`"));
System.out.println("otherContent" + otherContent);
//獲取交易記錄
String records = otherContent.substring(0, otherContent.indexOf("Total"));
String tradeRecords = records.replace("`", "");
System.out.println("records:" + tradeRecords);// 把 ` 全部去掉
// 獲取彙總表頭和彙總資料
String totalContent = otherContent.substring(otherContent.indexOf("Total"), otherContent.length());
String[] total = totalContent.split("\n");// 根據換行符分割
System.out.println("totalTableHead:" + total[0]);// 彙總表頭
System.out.println("totalData:" + total[1]);// 彙總資料
複製程式碼
完整程式碼
public class AnalyseDownloadBill {
public static void main(String[] args) {
String bill = "Transaction time,Official account ID(appid),Vendor ID(mch_id),Sub vendor ID (sub_mch_id),Device ID(Device_info),Wechat order number(transaction_id),Vendor order number (out_transaction_id),User tag(openid),Transaction type(trade_type),Transaction status (trade_state),Payment bank(bank_type),Currency type(fee_type),Total amount(total_fee),Coupon amount,Wechat refund number(refund_id),Vendor refund number(out_refund_no),Refund amount (refund_fee),Coupon refund amount,Refund type,Refund status(refund_status_$n),Product name,Vendor'bill data package(attach),Fee,Rate,Payment Currency type(Cash_fee_type),Cash payment amount(Cash_fee),Settlement currency type,Settlement currency amount,Exchange rate,Refund exchange rate,Payer'bill Refund amount,Payer'bill Refund currency type,Refund currency type,Refund settlement currency type,Refund settlement amount\n`2018-07-13 13:58:59,`wxa7ca41f5ddb1d958,`1499826932,`224150459,`,`4200000111201807132458910571,`A20180713157 27,` oRRUM1OMLP5E071pqb0y48ugIDoY,`NATIVE,`SUCCESS,`CFT,`CNY,`0.05,`0.00,`0,`0,`0.00,`0.00,`,`,`測試掃 碼支付 流程,`,`0.00000,`0.50%,`CNY,`0.05,`NZD,`0.01,`452930000,`0,`0,`,`,`,`0.00\n`2018-07-13 15:44:53,`wxa7ca41f5ddb1d958,`1499826932,`224150459,`,`4200000138201807136839391208,`A20180713344 47,` oRRUM1OMLP5E071pqb0y48ugIDoY,`MICROPAY,`SUCCESS,`CMB_DEBIT,`CNY,`0.05,`0.00,`0,`0,`0.00,`0.00,`,` ,`測 試刷卡介面,`,`0.00000,`0.50%,`CNY,`0.05,`NZD,`0.01,`452930000,`0,`0,`,`,`,`0.00\n`2018-07-13 16:06:52,`wxa7ca41f5ddb1d958,`1499826932,`224150459,`,`4200000138201807136839391208,`A20180713344 47,` oRRUM1OMLP5E071pqb0y48ugIDoY,`MICROPAY,`REFUND,`CMB_DEBIT,`CNY,`0.00,`0.00,`500000075220180713054 2334 1768,`A201807134645,`0.05,`0.00,`ORIGINAL,`SUCCESS,`測試刷卡接 口,`,`0.00000,`0.50%,`CNY,`0.00,`NZD,`0.00,`0,`452930000,`0.05,`CNY,`CNY,`NZD,`0.01\n`2018-07-13 16:05:34,`wxa7ca41f5ddb1d958,`1499826932,`224150459,`,`4200000111201807132458910571,`A20180713157 27,` oRRUM1OMLP5E071pqb0y48ugIDoY,`NATIVE,`REFUND,`CFT,`CNY,`0.00,`0.00,`50000307532018071305354138153 ,`A2 01807134527,`0.05,`0.00,`ORIGINAL,`SUCCESS,`測試掃碼支付流 程,`,`0.00000,`0.50%,`CNY,`0.00,`NZD,`0.00,`0,`452930000,`0.05,`CNY,`CNY,`NZD,`0.01\nTotal transaction count,Total transaction amount,Total refund amount,Total coupon refund amount,Total commission amount\n`4,`0.10,`0.10,`0.00,`0.00000";
// 獲取表頭
String tableHead = bill.substring(0, bill.indexOf("`"));
System.out.println("tableHead:" + tableHead);
// 獲取表頭以外的其他內容:交易記錄、彙總表頭、彙總資料
String otherContent = bill.substring(bill.indexOf("`"));
System.out.println("otherContent" + otherContent);
//獲取交易記錄
String records = otherContent.substring(0, otherContent.indexOf("Total"));
String tradeRecords = records.replace("`", "");
System.out.println("records:" + tradeRecords);// 把 ` 全部去掉
// 獲取彙總表頭和彙總資料
String totalContent = otherContent.substring(otherContent.indexOf("Total"), otherContent.length());
String[] total = totalContent.split("\n");
System.out.println("totalTableHead:" + total[0]);// 彙總表頭
System.out.println("totalData:" + total[1]);// 彙總資料
}
}
複製程式碼
總結
至此,我們的微信對賬單返回值的解析就完成了。回頭看其實這個解析一點都不難,只是我們沒有認真閱讀文件去了解它的結構,並且沒有細心的發現它的一些特徵,從而導致開始的茫然。所以在以後的開發中一定要認真閱讀文件,最好能清晰的解讀出文件中的關鍵內容,再加上一點點細心,那麼肯定很多問題都能夠迎刃而解的。