android 集成支付寶app支付(原生態)-包括android前端與java后台


本文講解了 android開發的原生態app集成了支付寶支付, 還提供了java后台服務器處理支付寶支付的加密代碼, app前端與java后台服務器使用json數據格式交互信息,java后台服務主要用來對支付數據進行加密和接受支付寶服務器的回調

注意: 本文即涉及到 android前端, 也涉及到 Java后台

准備條件:

  1. 到支付寶官網上注冊用戶, 打開開放平台,支付寶默認生成沙箱環境,用來測試支付流程

  2. 安裝Android Studio【下載】, 安裝 Eclipse mars  【下載】,  JDK1.7    tomcat7

 

1. 支付流程概述

    使用過app支付的用戶都知道,在支付環節,如果選擇【支付寶支付】,我們的app會拉起支付寶app,並且將支付信息傳入到

支付寶app中顯示出來, 用戶確認付款完成付款操作, 有朋友就會問,那我們的應用邏輯應該放在哪個步驟呢?

 

步驟1: 應用程序拉起支付寶app前,會按照支付寶的規則傳遞相應的數據給支付寶,所以啟動支付寶前,我們需要構建數據, 基本數據包括商品描述,商品價錢等,但為了讓支付寶區別是哪個應用程序傳過來的數據,還需要AppId(應用程序在支付寶平台上對應的序號); 另外為了保障數據不被篡改,我們傳遞的數據需要進行RSA加密

 

步驟2: 對數據的加密工作是放在后台進行的,那為什么不放在前台呢,熟悉RSA加密的朋友都知道,RSA是非對稱加密,加密方與解密方 需要一對密鑰(公鑰和私鑰), 這些公鑰與私鑰是敏感信息,放在android端容易被盜取,所以將公鑰與私鑰放在后台,后台對數據加密完成后再傳給前台

 

步驟3: 前台將加密完成后的數據傳送給支付寶,由支付寶完成支付

 

步驟4: 支付完成后app端會得到相應的事件通知,前台根據相應的事件來判斷前台的業務走向

 

步驟5: 支付寶官方要求,使用支付寶完成支付后,支付寶后台 會調用 應用服務的后台用來告之交易支付是否真正成功

由於本地服務無法向外界提供服務, 所以支付寶回調本地測試的服務器接口無法連通,至於連通的方法,可以看一下

ngrok的配置,  這個工具可以穿透內網

 

2. Android端

項目運行后如下圖

2.1 下載導入項目到android studio中,將build.gradle中的storeFile的路徑設置正確

2.2 android端的通信使用 retrofit rxjava技術,所以訪問后台的請求url需要配置正確, 如果使用本文提供的后台,則可以不必修改,如果使用別人的后台服務,需要進行更改

3.3 android端訪問后台獲取加密數據,然后將加密數據傳遞給支付寶

注意:由於使用的支付寶的沙箱配置信息  ,必須加上 代碼 EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);

如果使用正式環境的支付寶配置信息, 不能加上上面沙箱代碼

 

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
42
43
private  void  aliPay(){
     BizContent bizContent =  new  BizContent();
     bizContent.setOut_trade_no(outTradeNum);
     bizContent.setTotal_amount(totalPrice);
     bizContent.setSubject( "某個項目"  "-支付訂單" );
     String strBizContent =  new  Gson().toJson(bizContent);
  
  
     //generateOrderInfo去后台獲取加密的信息
      payService
         .generateOrderInfo(strBizContent)
             .subscribe( new  Action1<String>() {
                 @Override
                 public  void  call(String s) {
                     //orderInfo為加密的信息
                     final  String orderInfo = s;
                     Runnable payRunnable =  new  Runnable() {
                         @Override
                         public  void  run() {
                             //沙箱環境開啟沙箱功能
                             //正式環境不需要下面這行代碼
                             EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX);
                             PayTask alipay =  new  PayTask(MainActivity. this );
                             Map<String, String> result = alipay.payV2(orderInfo,  true );
                             Log.i( "msp" , result.toString());
  
                             Message msg =  new  Message();
                             msg.what = SDK_PAY_FLAG;
                             msg.obj = result;
                             mHandler.sendMessage(msg);
                         }
                     };
  
                     Thread payThread =  new  Thread(payRunnable);
                     payThread.start();
                 }
             },  new  Action1<Throwable>() {
                 @Override
                 public  void  call(Throwable throwable) {
                     showToast(throwable.getMessage());
                 }
             });
}

  

3.4 支付寶支付完成后執行 handleMessage

    在handleMessage判斷支付情況, 如果 payResult.getResultStatus() == "9000" 則支付成功, 否則失敗

    具體的失敗信息可以查看支付寶的官方文檔

 

復制代碼
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
    @SuppressWarnings("unused")
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case SDK_PAY_FLAG: {
                @SuppressWarnings("unchecked")
                PayResult payResult = new PayResult((Map<String, String>) msg.obj);
                /**
                 對於支付結果,請商戶依賴服務端的異步通知結果。同步通知結果,僅作為支付結束的通知。
                 */
                String resultInfo = payResult.getResult();// 同步返回需要驗證的信息
                String resultStatus = payResult.getResultStatus();
                // 判斷resultStatus 為9000則代表支付成功
                if (TextUtils.equals(resultStatus, "9000")) {
                    outTradeNum = "";
                    showToast("支付成功");
                } else {
                    outTradeNum = "";
                    // 該筆訂單真實的支付結果,需要依賴服務端的異步通知。
                    Toast.makeText(MainActivity.this, "支付失敗", Toast.LENGTH_SHORT).show();
                }
                break;
            }
            case SDK_AUTH_FLAG: {
                @SuppressWarnings("unchecked")
                AuthResult authResult = new AuthResult((Map<String, String>) msg.obj, true);
                String resultStatus = authResult.getResultStatus();
 
                // 判斷resultStatus 為“9000”且result_code
                // 為“200”則代表授權成功,具體狀態碼代表含義可參考授權接口文檔
                if (TextUtils.equals(resultStatus, "9000") && TextUtils.equals(authResult.getResultCode(), "200")) {
                    // 獲取alipay_open_id,調支付時作為參數extern_token 的value
                    // 傳入,則支付賬戶為該授權賬戶
                    Toast.makeText(MainActivity.this,
                            "授權成功\n" + String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT)
                            .show();
                } else {
                    // 其他狀態值則為授權失敗
                    Toast.makeText(MainActivity.this,
                            "授權失敗" + String.format("authCode:%s", authResult.getAuthCode()), Toast.LENGTH_SHORT).show();
 
                }
                break;
            }
            default:
                break;
        }
    };
};
復制代碼

3. Java后台

3.1 修改支付寶配置信息, 實例中使用的是本人支付寶中申請的沙箱配置信息

    請將Config.properties中的信息改成自己的

3.2 generateOrderInfo對android傳遞的支付信息進行加密, 加密信息回傳給android端

復制代碼
@RequestMapping("/generateOrderInfo.htm")
    @ResponseBody
    public Result generateOrderInfo(String bizContent) 
    {
        Result result = new Result();
        AlipaySignature sing=  new AlipaySignature();
        if(StringUtils.isEmpty(bizContent)){
            result.setData("");
            result.setStateCode(Constant.RESULT_FAILURE);
            result.setDesc("待加簽字符串不能為空");
        }else
        {
            String appId = ConfigManager.getInstance().getConfigItem("APPID");
            Map<String, String> params = OrderInfoUtil2_0.buildOrderParamMap(appId, bizContent, true);
            String orderParam = OrderInfoUtil2_0.buildOrderParam(params);
 
            String privateKey = ConfigManager.getInstance().getConfigItem("ProjectPrivateKey");
            String sign = OrderInfoUtil2_0.getSign(params, privateKey, true);
            final String orderInfo = orderParam + "&" + sign;
            result.setDesc("加簽成功");
            result.setStateCode(Constant.RESULT_SUCCESS);
            result.setData(orderInfo);
        }
        return  result;
    }
復制代碼

3.3 支付成功后,支付寶服務端回調后台應用程序接口,用來告之支付是否成功

復制代碼
/**
     * 支付寶的回調接口
     * @param request
     */
    @RequestMapping("/notifyOrderInfo.htm")
    public void notifyOrderInfo(HttpServletRequest request){
         
        if ("TRADE_SUCCESS".equals(request.getParameter("trade_status"))) {
            Enumeration<?> pNames = request.getParameterNames();
            Map<String, String> param = new HashMap<String, String>();
            try {
                while (pNames.hasMoreElements()) {
                    String pName = (String) pNames.nextElement();
                    param.put(pName, request.getParameter(pName));
                }
 
                boolean signVerified = AlipaySignature.rsaCheckV1(param, ConfigManager.getInstance().getConfigItem("AlipayPublicKey"),
                        AlipayConstants.CHARSET_UTF8); // 校驗簽名是否正確
                if (signVerified) {
                    // TODO 驗簽成功后
                    // 按照支付結果異步通知中的描述,對支付結果中的業務內容進行1\2\3\4二次校驗,校驗成功后在response中返回success,校驗失敗返回failure
                    System.out.println("訂單支付成功:" + JSON.toJSONString(param)); 
                } else {
                    // TODO 驗簽失敗則記錄異常日志,並在response中返回failure.
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return;
    }
復制代碼

 

關於支付寶的其它接口的更加詳細信息,請參照 【服務端詳解】

 

DEMO下載:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=844


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM