最近在作中國電信的翼支付網關接口的接入,正好拿Java練練手。到目前爲止,惟一不太適應的就是本身的Java積累幾乎爲0,什麼都要重頭寫起,不像C#有這麼多年的沉澱,能夠隨手拿來用。html
廢話先很少說。這個支付接口就和支付寶差很少,無非就是把一些必要的數據參數,POST到指定的接口地址,而後接收它返回的支付結果。接口沒有什麼複雜的邏輯處理,因此能夠直接採用JSP+Servlet+JDBC來作簡單處理。對於WEB支付請求的發起,能夠從JSP把用戶輸入或選擇的相關數據傳到Servlet,而後在Servlet裏把商戶的基本信息以及用戶數據封裝下,再統一POST到網關接口地址:web
1 StringBuffer stb = new StringBuffer(); 2 stb.append("<html>"); 3 stb.append("<head><title>你的Title</title></head>"); 4 stb.append("<body onload=\"document.form1.submit()\">"); 5 stb.append("<form name=\"form1\" method=\"post\" action=\"https://webpaywg.bestpay.com.cn/payWeb.do\" >"); 6 stb.append(String.format("<input name=\"MERCHANTID\" type=\"hidden\" value=\"%s\">", merchantId)); //商戶號 7 stb.append(String.format("<input name=\"ORDERSEQ\" type=\"hidden\" value=\"%s\">", orderSeq)); //訂單號 8 stb.append(String.format("<input name=\"ORDERREQTRANSEQ\" type=\"hidden\" value=\"%s\">", orderSeq)); //訂單請求交易流水號 9 stb.append(String.format("<input name=\"ORDERDATE\" type=\"hidden\" value=\"%s\">", orderDate)); //訂單日期 10 stb.append(String.format("<input name=\"ORDERAMOUNT\" type=\"hidden\" value=\"%s\">", orderAmount)); //訂單總金額 11 stb.append(String.format("<input name=\"PRODUCTAMOUNT\" type=\"hidden\" value=\"%s\">", orderAmount)); //產品金額 12 stb.append("<input name=\"ATTACHAMOUNT\" type=\"hidden\" value=\"0\">"); //附加金額 13 stb.append("<input name=\"CURTYPE\" type=\"hidden\" value=\"RMB\">"); //幣種 14 stb.append("<input name=\"ENCODETYPE\" type=\"hidden\" value=\"1\">"); //加密方式 MD5 15 stb.append(String.format("<input name=\"MERCHANTURL\" type=\"hidden\" value=\"%s\">", merchantUrl)); //前臺返回地址 16 stb.append(String.format("<input name=\"BACKMERCHANTURL\" type=\"hidden\" value=\"%s\">", backMerchantUrl)); //後臺返回地址 17 stb.append(String.format("<input name=\"ATTACH\" type=\"hidden\" value=\"%s\">", attach)); //商戶附加信息 18 stb.append("<input name=\"BUSICODE\" type=\"hidden\" value=\"0001\">"); //業務類型 19 stb.append("<input name=\"PRODUCTID\" type=\"hidden\" value=\"08\">"); // 業務標識 20 stb.append(String.format("<input name=\"TMNUM\" type=\"hidden\" value=\"%s\">", tmNum)); //終端號碼 21 stb.append(String.format("<input name=\"CUSTOMERID\" type=\"hidden\" value=\"%s\">", customerId)); //客戶標識 22 stb.append(String.format("<input name=\"PRODUCTDESC\" type=\"hidden\" value=\"%s\">", productDes)); //產品描述 23 stb.append(String.format("<input name=\"MAC\" type=\"hidden\" value=\"%s\">", mac)); //MAC校驗域 24 stb.append(String.format("<input name=\"CLIENTIP\" type=\"hidden\" value=\"%s\">", clientIp)); //客戶端IP 25 stb.append("</form></body>"); 26 stb.append("</html>"); 27 //入庫、記錄日誌等 28 response.setContentType("text/html"); 29 response.setCharacterEncoding("UTF-8"); 30 PrintWriter out = response.getWriter(); 31 out.write(stb.toString());
這裏須要注意的是MAC這個值,翼支付網關會對這個值作校驗;接口文檔中提供了這個值的加密和MD5摘要算法樣例,因此只要按照文檔描述的規則來,通常不會有沒有什麼問題。上面的參數中,有一個前臺返回地址和後臺返回地址,當用戶經過網銀完成支付後,翼支付網關會把用戶這次的支付結果POST到這2個地址,因此前臺地址能夠把支付結果展現給用戶,後臺地址的話就用來處理商戶的業務邏輯吧。畢竟前臺地址可能不會達到用戶側,或者用戶在支付完成後就直接關了當前窗口。另外後臺地址在接收到支付結果數據後,必定要原路響應網關,否則網關那邊會不定時的持續發送重複的支付結果過來:算法
1 request.setCharacterEncoding("UTF-8"); 2 String uptranSeq = request.getParameter("UPTRANSEQ"); //翼支付網關平臺交易流水號 3 String tranDate = request.getParameter("TRANDATE"); //翼支付網關平臺交易日期 4 String returnCode = request.getParameter("RETNCODE"); //處理結果碼 「0000」 表示支付成功,其餘值則表示支付失敗 5 String retuInfo = request.getParameter("RETNINFO"); //處理結果解釋碼 6 if(retuInfo != null && !retuInfo.isEmpty()) { 7 retuInfo = URLDecoder.decode(retuInfo, "UTF-8"); 8 } 9 String orderReqTranseq = request.getParameter("ORDERREQTRANSEQ"); //訂單請求交易流水號 10 String orderReq = request.getParameter("ORDERSEQ"); //訂單號 11 String orderAmount = request.getParameter("ORDERAMOUNT"); //訂單總金額 12 String productAmount = request.getParameter("PRODUCTAMOUNT"); //產品金額 13 String attachMount = request.getParameter("ATTACHAMOUNT"); //附加金額 14 String curType = request.getParameter("CURTYPE"); //幣種 15 String encodeType = request.getParameter("ENCODETYPE"); //加密方式 16 String bankId = request.getParameter("BANKID"); //銀行編碼 17 String attach = request.getParameter("ATTACH"); //商戶附加信息 18 String upreqTranseq = request.getParameter("UPREQTRANSEQ"); //網關平臺請求銀行流水號 19 String upbankTranseq = request.getParameter("UPBANKTRANSEQ"); //銀行流水號 20 String productNo = request.getParameter("PRODUCTNO"); //產品號碼 21 String sign = request.getParameter("SIGN"); //數字簽名 22 //對sign作數字簽名校驗(信息沒有被篡改) 23 //商戶業務邏輯處理、入庫、日誌等 24 String returnContent = "UPTRANSEQ_" + uptranSeq; 25 PrintWriter out = response.getWriter(); 26 out.write(returnContent); //回寫響應數據
WEB支付的處理主要就是這塊,很好理解吧!
至於退款接口,則是須要調用網關提供的WebService接口,以下所示,refundResult就是返回的退款結果了:app
1 //Axis 2 refundV2.webservice.ideal.com.RefundServiceFenImplProxy teStub = new RefundServiceFenImplProxy(); 3 String refundResult = teStub.refund(commCode, "", commPwd, oldOrderId, oldOrderPayId, orderRefundId, transamt, reqTime, mac);
最後再記錄下,在寫一個簡單的日誌記錄類時,本機開發環境的路徑中又有空格又有中文。。。這樣的話,採用 .getResource("").toURI().getPath() 方法來獲取路徑,就不怕任何奇特格式的路徑了~~~ide