Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 支付開發(支付寶)

Android 支付開發(支付寶)

編輯:關於Android編程

支付寶更新了開發文檔,針對最近的支付開發,做一下詳細的開發流程總結。

一、接入流程

1.1、第一步:創建應用並獲取APPID

創建應用,獲取APPID,並且可以申請開通開放產品使用權限,通過APPID您的應用才能正常使用有權限調用的開放產品的接口能力。

具體參考:https://doc.open.alipay.com/doc2/detail.htm?treeId=200&articleId=105308&docType=1

1.2、第二步:配置密鑰

這一步可以找後台人員配置,也可以自己配置,具體不作詳敘,需要用到的是支付寶私鑰。

具體參考:https://doc.open.alipay.com/doc2/detail.htm?treeId=200&articleId=105310&docType=1

1.3 第三部:集成並配置SDK

下載SDK,添加到項目中。
在商戶應用工程的AndroidManifest.xml文件裡面添加聲明:




 

權限聲明:





添加混淆:

-libraryjars libs/alipaySDK-20150602.jar

-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}

1.4、第四步:調用接口

這裡寫圖片描述

這裡看的很清晰,我們需要考慮的是2345678這幾步即可。主要說一下獲取的訂單是簽名後的訂單信息,並沒有將配置信息放在客戶端來進行操作,這是為了安全性來考慮的。

構造交易數據並簽名必須在商戶服務端完成,商戶的應用私鑰絕對不能保存在商戶APP客戶端中,也不能從服務端下發。
同步返回的數據,只是一個簡單的結果通知,商戶確定該筆交易付款是否成功需要依賴服務端收到支付寶異步通知的結果進行判斷。
商戶系統接收到通知以後,必須通過驗簽(驗證通知中的sign參數)來確保支付通知是由支付寶發送的。建議使用支付寶提供的SDK來完成

1.5、如何調用以及訂單參數詳解

這一步可以參考修改一下demo。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;"> public void payV2(View v) { if (TextUtils.isEmpty(APPID) || TextUtils.isEmpty(RSA_PRIVATE)) { new AlertDialog.Builder(this).setTitle("警告").setMessage("需要配置APPID | RSA_PRIVATE") .setPositiveButton("確定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialoginterface, int i) { // finish(); } }).show(); return; } Map params = OrderInfoUtil2_0.buildOrderParamMap(APPID); String orderParam = OrderInfoUtil2_0.buildOrderParam(params); String sign = OrderInfoUtil2_0.getSign(params, RSA_PRIVATE); final String orderInfo = orderParam + "&" + sign; Runnable payRunnable = new Runnable() { @Override public void run() { PayTask alipay = new PayTask(PayDemoActivity.this); Map 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(); }

支付行為需要在獨立的非ui線程中執行。

支付結果獲取和處理:

同步結果

private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            @SuppressWarnings("unchecked")
                PayResult payResult = new PayResult((Map) msg.obj);
                /**
                 * 同步返回的結果必須放置到服務端進行驗證(驗證的規則請看https://doc.open.alipay.com/doc2/
                 * detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&
                 * docType=1) 建議商戶依賴異步通知
                 */
                String resultInfo = payResult.getResult();// 同步返回需要驗證的信息

                String resultStatus = payResult.getResultStatus();
                // 判斷resultStatus 為“9000”則代表支付成功,具體狀態碼代表含義可參考接口文檔
                if (TextUtils.equals(resultStatus, "9000")) {
                    Toast.makeText(PayDemoActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
                } else {
                    // 判斷resultStatus 為非"9000"則代表可能支付失敗
                    // "8000"代表支付結果因為支付渠道原因或者系統原因還在等待支付結果確認,最終交易是否成功以服務端異步通知為准(小概率狀態)
                    if (TextUtils.equals(resultStatus, "8000")) {
                        Toast.makeText(PayDemoActivity.this, "支付結果確認中", Toast.LENGTH_SHORT).show();

                    } else {
                        // 其他值就可以判斷為支付失敗,包括用戶主動取消支付,或者系統返回的錯誤
                        Toast.makeText(PayDemoActivity.this, "支付失敗", Toast.LENGTH_SHORT).show();

                    }
                }
        };
    };

異步結果:

在訂單中返回一個key為notify_url的鏈接,支付寶會以POST方式調用notify_url傳輸數據。

支付參數:

Map result = alipay.payV2(orderInfo, true);

orderInfo:加簽後的訂單信息,app支付請求參數字符串,主要包含商戶的訂單信息,key=value形式,以&連接。

true:boolean isShowPayLoading,加載過渡。

訂單參數:

    public static Map buildOrderParamMap(String app_id) {
        Map keyValues = new HashMap();

        keyValues.put("app_id", app_id);

        keyValues.put("biz_content", "{\"timeout_express\":\"30m\",\"product_code\":\"QUICK_MSECURITY_PAY\",\"total_amount\":\"0.01\",\"subject\":\"1\",\"body\":\"我是測試數據\",\"out_trade_no\":\"" + getOutTradeNo() +  "\"}");

        keyValues.put("charset", "utf-8");

        keyValues.put("method", "alipay.trade.app.pay");

        keyValues.put("sign_type", "RSA");

        keyValues.put("timestamp", "2016-07-29 16:55:53");

        keyValues.put("version", "1.0");

        return keyValues;
    }

包含公共參數和業務參數。biz_content是業務參數,其他均是公共參數。

這裡寫圖片描述

這裡雖然不是必須參數,但是還要具體配置,還是寫上為好。畢竟別支付到別人賬戶去了哈哈!

訂單加簽流程:

請求參數按照key=value&key=value方式拼接的未簽名原始字符串:
    /**
     * 構造支付訂單參數信息
     * 
     * @param map
     * 支付訂單參數
     * @return
     */
    public static String buildOrderParam(Map map) {
        List keys = new ArrayList(map.keySet());

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < keys.size() - 1; i++) {
            String key = keys.get(i);
            String value = map.get(key);
            sb.append(buildKeyValue(key, value, true));
            sb.append("&");
        }

        String tailKey = keys.get(keys.size() - 1);
        String tailValue = map.get(tailKey);
        sb.append(buildKeyValue(tailKey, tailValue, true));

        return sb.toString();
    }
再對原始字符串進行簽名
/**
     * 對支付參數信息進行簽名
     * 
     * @param map
     *            待簽名授權信息
     * 
     * @return
     */
    public static String getSign(Map map, String rsaKey) {
        List keys = new ArrayList(map.keySet());
        // key排序
        Collections.sort(keys);

        StringBuilder authInfo = new StringBuilder();
        for (int i = 0; i < keys.size() - 1; i++) {
            String key = keys.get(i);
            String value = map.get(key);
            authInfo.append(buildKeyValue(key, value, false));
            authInfo.append("&");
        }

        String tailKey = keys.get(keys.size() - 1);
        String tailValue = map.get(tailKey);
        authInfo.append(buildKeyValue(tailKey, tailValue, false));

        String oriSign = SignUtils.sign(authInfo.toString(), rsaKey);
        String encodedSign = "";

        try {
            encodedSign = URLEncoder.encode(oriSign, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "sign=" + encodedSign;
    }

具體參考:https://doc.open.alipay.com/doc2/detail.htm?treeId=200&articleId=105351&docType=1

最後對請求字符串value進行encode,編碼格式按請求串中的charset為准,沒傳charset按UTF-8處理,獲得最終的請求字符串:
// 僅需對sign 做URL編碼
sign = URLEncoder.encode(sign, "UTF-8");

demo已經將2,3合並成一步。

支付結果驗證:

當然,前面所述,基本支付功能不成問題,但是為了程序的嚴謹性和支付的安全性考慮,還是需要對支付結果進行驗證。

同步通知驗證:

示例:

{
    "memo" : "xxxxx",
    "result" : "{
                    \"alipay_trade_wap_pay_response\":{
                        \"code\":\"10000\",
                        \"msg\":\"Success\",
                        \"app_id\":\"2014072300007148\",
                        \"out_trade_no\":\"081622560194853\",
                        \"trade_no\":\"2016081621001004400236957647\",
                        \"total_amount\":\"0.01\",
                        \"seller_id\":\"2088702849871851\",
                        \"charset\":\"utf-8\"
                    },
                    \"sign\":\"NGfStJf3i3ooWBuCDIQSumOpaGBcQz+aoAqyGh3W6EqA/gmyPYwLJ2REFijY9XPTApI9YglZyMw+ZMhd3kb0mh4RAXMrb6mekX4Zu8Nf6geOwIa9kLOnw0IMCjxi4abDIfXhxrXyj********\",
                    \"sign_type\":\"RSA\"
                }",
    "resultStatus" : "9000"
}

code結果碼:

這裡寫圖片描述

具體意思即驗證返回結果信息跟訂單信息是否一致,當然驗證的參數也比較多
具體參考:
https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.1N7QWY&treeId=193&articleId=105302&docType=1

異步驗證:
這裡是服務端做的驗證,支付成功後支付寶會吊起notify_url上的鏈接,返回支付參數,服務端對支付參數進行解析驗證。

具體參考:
https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.q9gQhV&treeId=193&articleId=105301&docType=1

舊版支付當前還在兼容使用,當然需要使用舊版的SDK,具體需要注意的是

這裡寫圖片描述

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