Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發:app工程集成銀聯支付功能(服務器端)

Android開發:app工程集成銀聯支付功能(服務器端)

編輯:關於Android編程

一.功能描述

因為是自己開發了一個app應用,沒資格去申請微信支付和支付寶支付,於是就采用了銀聯支付功能,銀聯支付分為了兩種環境:測試環境和生產環境,一般前期開發的時候都是使用測試環境,數據都是測試數據,不會發生真實交易。第一次做Android項目+IDE為Android Studio+第一次集成支付功能,所以個人覺得整個集成過程可能有點復雜,而且銀聯支付產品眾多:網關支付產品、手機控件支付、手機網頁支付等等,第一次看的時候真是雲裡霧裡,不知道選哪個,不知道他們的區別,最後自己選擇了手機控件支付,先試試,光看沒有用。自己做了多少寫多少,好記性不如爛筆頭,就怕後面想記錄的時候忘記了前面的過程。

二.實現過程

2.1下載銀聯支付SDK和Demo

(1)銀聯商家服務地址:https://open.unionpay.com/ajweb/index

第一步:注冊;

第二步:然後在幫助中心界面的產品分類下載裡選擇手機控件支付;
產品分類下載
第三步:下載安卓版的開發包。<喎?/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPjxiciAvPg0KPGltZyBhbHQ9"這裡寫圖片描述" src="/uploadfile/Collfiles/20160506/2016050609072426.png" title="\" />

(2)下載的文件如下

這裡寫圖片描述

2.2集成過程

個人建議可以先把服務器端的工程跑一下,這樣結合代碼的時候就很容易明白怎麼集成到自己的工程裡了。所以這一小部分內容是官方Demo的運行情況,需要修改的配置很少,但是還是有小地方需要調整一下。

(1)先試官方Demo

將工程導入

這裡寫圖片描述

修改acp_sdk_properties的配置

將這三個路徑修改為測試環境證書的路徑(證書在assets文件夾下),可以使用相對路徑或者絕對路徑都行,下面圖中是絕對路徑,我把assets/測試環境證書下的三個文件移動到了C盤。
這裡寫圖片描述
我的測試環境證書地址:
這裡寫圖片描述

Run一個試試

啟動tomcat過程中比較關鍵的一處就是
這裡寫圖片描述

首頁

這裡寫圖片描述

獲取tn

這裡寫圖片描述
最後打印的報文

這裡寫圖片描述

(2)集成到自己的工程裡

先講服務器端,因為自己也才完成了這部分工作。運行了官方Demo以及相關說明文檔後,整體思路其實就有了。
首先試試配置!!!

jar包

將Demo工程lib中的jar包復制到自己工程的lib裡(如果已經有jar包了,就不需要復制了)
這裡寫圖片描述

修改acp_sdk_propertise和log4j.properties
(主要是一些路徑的修改,因為我的服務器上只有C盤,所以我必須得改,acp_sdk_properties的修改見(1)運行Demo部分)

這裡寫圖片描述

導入相關java文件

之所以寫用import的方式是為了少出現亂碼的問題,見下圖
這裡寫圖片描述

第一部分 controller對應於Demo中的ACPSample_AppServer\src\com\unionpay\acp\demo,其中PayController是我自己寫的Controller。
第二部分model對應於Demo中的ACPSample_AppServer\src\com\unionpay\acp\sdk
第三部分的兩個java文件對應於Demo中的\ACPSample_AppServer\src\web中的兩個java文件

web.xml配置
增加

    autoLoadServlet
    com.XXX.component.pay.AutoLoadServlet
    0
  
  
    autoLoadServlet
    /autoLoadServlet
  

ok,配置過程就算完事了,現在就該寫PayController來接受請求了。

PayController控制器
其實就是Form05_6_2_AppConsume.java中的代碼,因為使用是SSM架構,就改了改架構而已。
@Controller
public class PayController extends BasicController{
    @RequestMapping(value = "/pay/pay")
    @ResponseBody
    public void pay(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {

        request.setCharacterEncoding(DemoBase.encoding_UTF8);//
        response.setContentType("text/html; charset="+ DemoBase.encoding_UTF8);//這兩句是我臨時加的,因為出現了亂碼

        Map contentData = new HashMap();

        /***銀聯全渠道系統,產品參數,除了encoding自行選擇外其他不需修改***/
        contentData.put("version", DemoBase.version);            //版本號 全渠道默認值
        contentData.put("encoding", DemoBase.encoding_UTF8);     //字符集編碼 可以使用UTF-8,GBK兩種方式
        contentData.put("signMethod", "01");                    //簽名方法 目前只支持01:RSA方式證書加密
        contentData.put("txnType", "01");                       //交易類型 01:消費
        contentData.put("txnSubType", "01");                    //交易子類 01:消費
        contentData.put("bizType", "000201");                   //填寫000201
        contentData.put("channelType", "08");                   //渠道類型 08手機

        String merId = request.getParameter("merId");
        String txnAmt = request.getParameter("txnAmt");
        String orderId = request.getParameter("orderId");
        String txnTime = request.getParameter("txnTime");

        /***商戶接入參數***/
        contentData.put("merId", merId);                        //商戶號碼,請改成自己申請的商戶號或者open上注冊得來的777商戶號測試
        contentData.put("accessType", "0");                     //接入類型,商戶接入填0 ,不需修改(0:直連商戶, 1: 收單機構 2:平台商戶)
        contentData.put("orderId", orderId);                    //商戶訂單號,8-40位數字字母,不能含“-”或“_”,可以自行定制規則   
        contentData.put("txnTime", txnTime);                    //訂單發送時間,取系統時間,格式為YYYYMMDDhhmmss,必須取當前時間,否則會報txnTime無效
        contentData.put("accType", "01");                       //賬號類型 01:銀行卡02:存折03:IC卡帳號類型(卡介質)
        contentData.put("txnAmt", txnAmt);                      //交易金額 單位為分,不能帶小數點
        contentData.put("currencyCode", "156");                 //境內商戶固定 156 人民幣
        //contentData.put("reqReserved", "透傳字段");              //商戶自定義保留域,交易應答時會原樣返回
        //後台通知地址(需設置為外網能訪問 http https均可),支付成功後銀聯會自動將異步通知報文post到商戶上送的該地址,【支付失敗的交易銀聯不會發送後台通知】
                //後台通知參數詳見open.unionpay.com幫助中心 下載  產品接口規范  網關支付產品接口規范 消費交易 商戶通知
                //注意:1.需設置為外網能訪問,否則收不到通知    2.http https均可  3.收單後台通知後需要10秒內返回http200或302狀態碼 
                //    4.如果銀聯通知服務器發送通知後10秒內未收到返回狀態碼或者應答碼非http200或302,那麼銀聯會間隔一段時間再次發送。總共發送5次,銀聯後續間隔1、2、4、5 分鐘後會再次通知。
                //    5.後台通知地址如果上送了帶有?的參數,例如:http://abc/web?a=b&c=d 在後台通知處理程序驗證簽名之前需要編寫邏輯將這些字段去掉再驗簽,否則將會驗簽失敗
        contentData.put("backUrl", DemoBase.backUrl);//[其實還沒搞明白這個地址的作用]

        /**對請求參數進行簽名並發送http post請求,接收同步應答報文**/
        Map reqData = AcpService.sign(contentData,DemoBase.encoding_UTF8);           //報文中certId,signature的值是在signData方法中獲取並自動賦值的,只要證書配置正確即可。
        String requestAppUrl = SDKConfig.getConfig().getAppRequestUrl();                                 //交易請求url從配置文件讀取對應屬性文件acp_sdk.properties中的 acpsdk.backTransUrl
        Map rspData = AcpService.post(reqData,requestAppUrl,DemoBase.encoding_UTF8);  //發送請求報文並接受同步應答(默認連接超時時間30秒,讀取返回結果超時時間30秒);這裡調用signData之後,調用submitUrl之前不能對submitFromData中的鍵值對做任何修改,如果修改會導致驗簽不通過

        /**對應答碼的處理,請根據您的業務邏輯來編寫程序,以下應答碼處理邏輯僅供參考------------->**/
        //應答碼規范參考open.unionpay.com幫助中心 下載  產品接口規范  《平台接入接口規范-第5部分-附錄》
        if(!rspData.isEmpty()){
            if(AcpService.validate(rspData, DemoBase.encoding_UTF8)){
                LogUtil.writeLog("驗證簽名成功");
                String respCode = rspData.get("respCode") ;
                if(("00").equals(respCode)){
                    //成功,獲取tn號
                    //String tn = resmap.get("tn");//這裡應該是rspData.get("tn");
                    //TODO
                }else{
                    //其他應答碼為失敗請排查原因或做失敗處理
                    //TODO
                }
            }else{
                LogUtil.writeErrorLog("驗證簽名失敗");
                //TODO 檢查驗證簽名失敗的原因
            }
        }else{
            //未返回正確的http狀態
            LogUtil.writeErrorLog("未獲取到返回報文或返回http狀態碼非200");
        }
        String reqMessage = DemoBase.genHtmlResult(reqData);
        String rspMessage = DemoBase.genHtmlResult(rspData);
        try {
            response.getWriter().write("請求報文:
"+reqMessage+"
" + "應答報文:
"+rspMessage+"");
            //response.getOutputStream().write(("請求報文:
"+reqMessage+"
" + "應答報文:
"+rspMessage+"").getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
運行

然後浏覽器輸入(get方式,在Form05_6_2_AppConsume.java中get和post方式是一樣的,我的PayController因為沒有指定請求方式,所以兩種方式也是兼容的,而且只是為了測試采用的get,後面把客戶端搭好,就用post方式)
:http://123.XX.XXX.127:8080/intveh/pay/pay?merId=777290058110048&txnTime=20160505092851&orderId=20160505092851&txnAmt=5
效果和官方Demo一樣:
這裡寫圖片描述

目前就把服務器端的tn獲取搭好了,還有退款退貨等等以及客戶端的搭建,接著搞~~

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved