微信對賬單介面返回值解析

樑樸生發表於2018-08-08

最近在做微信支付相關的業務,在呼叫微信的對賬單介面時,遇到一個當時感覺很頭大的問題,為什麼說當時很頭大呢?因為現在這個問題已經被我解決了!嘿嘿...

好吧,言歸正傳。我遇到的問題就是在呼叫微信的對賬單介面時,微信會返回一個字串給我,而這個字串就包含了賬單名稱以及賬單資料。喏,就是下面這個樣子。

微信對賬單介面返回值解析

當時看了一臉懵逼,因為看不出任何可以進行解析的特徵,因此不得不又認認真真的看了一遍介面的文件說明,結合著介面文件的說明和自己大膽的假設,最終將該字串解析成自己想要的樣子。接下來就來說說自己的解法吧。

按照文件說明剖析整體結構

微信對賬單介面返回值解析

從上面的文件說明中,我找出了最關鍵的三句話(用紅框標記),從這個三句話中可以看出字串的結構其實就是:

  • 表頭
  • 資料記錄
  • 彙總表頭
  • 彙總資料

所以我就按照這種結構來解析整個字串。 不過在解析之前需要說明,微信給的示例和呼叫介面返回的資料非常的具有迷惑性,它給的資料看不出任何的特別有用特徵,但是當把介面返回字串複製貼上到你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]);// 彙總資料
	}
}
複製程式碼

總結

至此,我們的微信對賬單返回值的解析就完成了。回頭看其實這個解析一點都不難,只是我們沒有認真閱讀文件去了解它的結構,並且沒有細心的發現它的一些特徵,從而導致開始的茫然。所以在以後的開發中一定要認真閱讀文件,最好能清晰的解讀出文件中的關鍵內容,再加上一點點細心,那麼肯定很多問題都能夠迎刃而解的。

相關文章