聊一聊Java如何接入招行一網通支付功能

来源:https://www.cnblogs.com/zhixiang-org-cn/archive/2018/08/20/9503367.html
-Advertisement-
Play Games

1.前提條件 相比較於支付寶和微信的支付功能接入這一塊,銀行相對來說更加嚴格,比如說支付寶,在你簽約之前可以進行一些測試。但是銀行來說就不是這樣了,如果您現在要進行招行的支付功能開發的話,請務必先讓相關人員去進行簽約 2. 測試開發必須條件 進行測試開發之前有幾個比較重要的東西是不可避免的,我們來看 ...


1.前提條件

相比較於支付寶和微信的支付功能接入這一塊,銀行相對來說更加嚴格,比如說支付寶,在你簽約之前可以進行一些測試。但是銀行來說就不是這樣了,如果您現在要進行招行的支付功能開發的話,請務必先讓相關人員去進行簽約

2. 測試開發必須條件

進行測試開發之前有幾個比較重要的東西是不可避免的,我們來看一下都是有什麼:

  1. 商戶號、商戶分行號以及商戶秘鑰(具體明細請參考:http://link.cmbchina.com/open2/DOC/ToTest6.aspx

  2. 驗證碼查詢地址(測試環境招行所發的驗證碼都可以在此網站查詢到http://121.15.180.69/GetMsgVerifyCode/Default.aspx

  3. API文檔(進行簽約時招行一般會給我們一份文檔,但是此文檔也是很有參考價值的http://link.cmbchina.com/open2/API/APIdefault.aspx

3.測試開發

咱們這次一個完整的支付流程為例

進入正式的開發之前咱們先來看一下一個圖,這個圖呢,簡單介紹了一下這個支付的流程,並沒有考慮失敗的因素。僅供大家參考!

圖片

接下來呢,我們就按照上圖所示的流程進行開發。

  1. 第一個相信不用費心,APP請求時攜帶一個訂單號就行。

  2. 我們根據訂單號查詢出此訂單關聯的訂單金額及用戶等信息,然後呢參考此鏈接(http://link.cmbchina.com/open2/API/PWDPayAPI4.aspx)的請求報文要求的必填欄位一一組合起來。

    這裡組合的時候有幾個小小的問題,因為招行對我們發送的請求報文是有要求的:測試環境回調地址不支持功能變數名稱,只能是純IP地址,且埠只能為80、443、8081其中的一個。另外請求報文中的reqData欄位里的內容要進行排序。最後,排序完的報文要進行簽名。詳細要求請看此鏈接:http://link.cmbchina.com/open2/API/SigAndCheck2.aspx


    這裡進行排序的話我可以提供一種全新的思路,我們可以把待排序的欄位使用一個dto封裝起來類似於下麵這種:

1
2
3
4
5
6
7
8
9
10
11
12
13


//客戶協議號。
private String agrNo;

//金額
private String amount;

//銀行訂單流水號
private String bankSerialNo;

// 商戶分行號
private String branchNo;

這樣的dto轉換成json串的時候是已經有序了的。

對參數進行簽名的話怎可以參考招行為我們提供的代碼示例。http://link.cmbchina.com/open2/API/Appendix16.aspx#jvch2
需要註意的就是上方我們dto轉成的是一個json串,但是簽名要求的待簽名的字元串格式是這樣的。agrNo=xxx&amount=88.88&bankSerialNo=1234567&branchNo=xxx

排序以及簽名完畢以後就可以把這個發送給APP了,我們發送給APP的就是下方這個形式的json:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"version":"1.0",
"charset":"UTF-8",
"sign":"見簽名處理章節",
"signType":"SHA-256",
"reqData":{
"dateTime":"20161209112230",
"branchNo":"0755",
"merchantNo":"000054",
"date":"20161209",
"orderNo":"9999000001",
"amount":"0.01",
"expireTimeSpan":"30",
"payNoticeUrl":"http://www.merchant.com/path/payNotice.do",
"payNoticePara":"12345678|ABCDEFG|HIJKLM",
"returnUrl":"http://www.merchant.com/path/return.do",
"clientIP":"99.12.38.165",
"cardType":"A",
"agrNo":"12345678901234567890",
"merchantSerialNo":"2016062014308888",
"userID":"2016062388888"
}
}
  1. APP收到伺服器返回的請求報文,就可以組成如下表單向招行發送請求:
1
2
3
4
<form action="http://121.15.180.66:801/NetPayment/BaseHttp.dll?MB_EUserPay" method="post" >
<input type="hidden" name="jsonRequestData" value='服務端返回的請求報文' />
<input type="submit" >
</form>

這一塊呢,也有一個需要註意的地方,因為有的時候我們服務端開發的時候可能APP還沒有時間,如果我們每次都讓人家幫忙也挺浪費時間的。這裡也有一個快速測試的好辦法。我們可以把上方的代碼拿著自己建一個HTML文件,發送到自己手機上,然後使用手機瀏覽器打開其實也是可以的。

  1. 此時招行就會返回一個統一的支付頁面

  2. 在這我們填入簽約時招行給我們的測試賬號等信息,賬號支付使用的驗證碼請參考文章剛開始我們所說的網址

  3. 假設支付成功,那麼招行就會回調我們請求參數所填的回調地址,這裡其實是有兩個回調地址的,一個是簽約成功的回調,一個是支付成功的回調。


    關於這些回調的問題一般我們會有兩種方式解決,1呢是內網穿透,2呢就是遠程Debug,因為招行的測試回調地址只能是ip所以這裡我們就是要第二種方式,不熟悉遠程Debug的同學可以參考我的另一篇博文IDEA遠程Debug


    我們就拿支付成功的回調來說。
    招行會把參數放到一個jsonRequestData的屬性里。我們可以通過以下方式來取得:
    JSONObject jsonRequestData=JSONObject.parseObject(request.getParameter("jsonRequestData"));
    這個json裡面的東西我們可以參考一下這個鏈接http://link.cmbchina.com/open2/API/PayRltAPI6.aspx
    有了這些東西我們就可以準確的知道此次支付的一些相關信息。

    不過呢,這樣有個問題呀,這東西要是別人偽造的怎麼辦呀。所以呢,這裡還一個驗簽的過程,驗證此次回調到底是不是招行發來的。

    這個驗簽還牽扯到一個問題,那就是驗簽需要招行的公鑰,而招行的公鑰是會定期更新的,所以我們可以做一個定時任務定期去請求招行的公鑰(關於定時任務的相關可以參考我的這篇博客:Java定時任務解決方案

    至於怎麼去查詢請參考此鏈接http://link.cmbchina.com/open2/API/QueryAPI3.aspx,使用我們上方所說的如何排序請求參數,如何進行簽名。不過這個只需要在服務端請求就可以了,至於在服務端如何發送請求大家可以使用一下方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public static String doPost(String jsonParam, String url, String charset) {
OutputStreamWriter out = null;
BufferedReader in = null;
StringBuffer result = new StringBuffer();
try {
URL httpUrl = new URL(url);
HttpURLConnection urlCon = (HttpURLConnection) httpUrl.openConnection();
urlCon.setRequestMethod("POST");
urlCon.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
urlCon.setDoOutput(true);
urlCon.setDoInput(true);
urlCon.setReadTimeout(5 * 1000);
out = new OutputStreamWriter(urlCon.getOutputStream(), charset);
out.write("jsonRequestData=" + jsonParam);
log.info("the request to cmb jsonRequestData is :{}",jsonParam);
out.flush();

in = new BufferedReader(new InputStreamReader(urlCon.getInputStream(), charset));
String str = null;
while ((str = in.readLine()) != null) {
result.append(str);
}

} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result.toString();
}


既然公鑰有了,我們就可以進行驗簽了。
具體驗簽細節可參看此鏈接:http://link.cmbchina.com/open2/API/Appendix16.aspx

如果驗簽通過的情況下我們就可以happy進行各種操作了。

不過呢,還有一點。記得給招行返回一個收到的信息
`
response.setStatus(HttpStatus.SC_OK);

`
你要是不告訴人家你收到了,他是會在間隔一段時間後再次發送通知,直到10個以後。

  1. 這個大流程終於走到這了,這個時候你是使用APP輪訓,或者向APP推送告知支付完成的信息就是看你需求了。

結語

關於招行的支付功能是我上周剛剛親手擼出來的代碼,我想能踩的坑我基本上已經踩過了,如果大家在開發過程中遇到什麼問題的話都可以來我的網站,我們一起交流討論:石玉軍的個人博客

本文出自http://zhixiang.org.cn,轉載請保留。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 樹形結構是軟體行業很常見的一種結構,幾乎隨處可見, 比如: HTML 頁面中的DOM,產品的分類,通常一些應用或網站的菜單,Windows Form 中的控制項繼承關係,Android中的View繼承關係,部門的組織架構,Windows 資源管理器 等等都是樹形結構。 Windows 資源管理 樹形結 ...
  • 概要 帶著問題去看教程: 不是用logstash來監聽我們的日誌,我們可以使用logback配置來使用TCP appender通過TCP協議將日誌發送到遠程Logstash實例。 我們可以使用Logstash指向多個日誌文件。 我們可以在logstash配置文件中使用更複雜的過濾器,以根據需要執行更 ...
  • 緩存ABC Intro 緩存是一種比較常見的用來將提高系統性能的方式。從線程緩存、進程緩存、到記憶體緩存再到分散式緩存再到CDN,都是屬於緩存的範疇。 緩存的本質是 以提高讀的效率,犧牲一些記憶體空間來換取之後的快速讀取與訪問。 緩存3問 為什麼需要緩存? 一般在項目中,最消耗性能的地方就是後端服務了, ...
  • 說起線程,無法免俗首先要弄清楚的三個概念就是:進程、線程、協程。OK,那什麼是進程,什麼是線程,哪協程又是啥東西。進程:進程可以簡單的理解為運行在操作系統中的程式,程式時靜態代碼,進程是動態運行著的代碼,程式的運行需要向操作系統申請資源比如記憶體,文件句柄等,特別強調的是進程申請的資源都是獨立的,也就 ...
  • 本文主要講解靜態代理,動態代理的原理,以及如何使用JDK動態代理,cglib動態代理,最後帶大家手寫jdk動態代理源碼!真正理解動態代理的原理與技術!含Git完整項目地址! ...
  • 詳情戳擊下方鏈接 Python之進程、線程、協程 python之IO多路復用 ...
  • 數據類型 由於學習過其他編程語言(C/C++/java),所以記錄的話除了一些差異點和遇到的問題,儘可能的簡潔,以達到最佳的記錄作用,方便以後的複習和形成體系。 1.數字類型 包括integer,long,float,complex(複雜整數)等,統稱number,而且不用特殊聲明。 特殊類型:布爾 ...
  • 方式一:修改server.xml文件 優點: 配置速度快,只需要在server.xml文件中添加<Context>標簽,在其中分別配置path虛擬路徑和docBase真實路徑然後啟動Tomcat伺服器即可 缺點: 需要配置兩個路徑,如果path為空字元串,則為預設配置 每次修改server.xml文 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...