Android支付——支付寶支付總結

1、獲取支付寶必須的參數

申請支付寶商戶帳號,並且創建應用通過審覈。獲取商戶PID。使用openssl生成支付寶公鑰、私鑰和pkcs8格式私鑰(安卓必須是pkcs8格式的私鑰,openssl工具在支付寶官方的SDK裏面都有,也有使用介紹)。

    /** 商戶PID*/
    public static final String PARTNER = "";
    /** 商戶收款賬號*/
    public static final String SELLER = "";
    /** 商戶私鑰,pkcs8格式*/
    public static final String RSA_PRIVATE = "";
    /** 支付寶公鑰*/
    public static final String RSA_PUBLIC = "";

2、導入jar包

將alipaySdk-20151215.jar包放入應用工程的libs目錄下。

3、修改AndroidManifest.xml文件

在AndroidManifest.xml文件中添加如下代碼:

 <!-- ===== alipay sdk begin 支付寶配置開始 = -->
    <activity
        android:name="com.alipay.sdk.app.H5PayActivity"
        android:configChanges="orientation|keyboardHidden|navigation|screenSize"
        android:exported="false"
        android:screenOrientation="behind"
        android:launchMode="singleTop"
       android:windowSoftInputMode="adjustResize|stateHidden" >
    </activity>
 <!-- ====== alipay sdk end 支付寶配置結束 ======= -->

* 注意:添加啓動模式 android:launchMode=”singleTop”。

添加權限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

4、創建支付寶支付類

在支付寶的官方demo中找到Base64.java,PayResult.java和SignUtils.java文件放在自己的項目中。

創建支付類:
爲了保證後臺可以正確的接收數據可以設置異步接收支付結果,商戶提供一個http協議的接口,包含在參數裏傳遞給快捷支付,即notify_url。支付寶服務器在支付完成後,會以POST方式調用notify_url,以xml數據格式傳輸支付結果。

//服務器異步通知頁面路徑 Url.PAYORDER 訂單支付-支付寶支付完成異步回調接口
orderInfo += “&notify_url=” + “\”” + Url.PAYORDER + “\”“;

public class AlipayPay {

    private static final int SDK_PAY_FLAG = 1;
    private static final int SDK_CHECK_FLAG = 2;
    private Context context;
    /** 在後臺獲取的商戶訂單號 */
    private String tradeNo;

    public AlipayPay(Context context, String tradeNo) {
        this.context = context;
        this.tradeNo = tradeNo;
    }

    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case SDK_PAY_FLAG: {
                PayResult payResult = new PayResult((String) msg.obj);
                // 支付寶返回此次支付結果及加簽,建議對支付寶簽名信息拿簽約時支付寶提供的公鑰做驗籤
                String resultInfo = payResult.getResult();
                String resultStatus = payResult.getResultStatus();
                String memo = payResult.getMemo();
                LogUtils.e("resultStatus==" + resultStatus + "==memo==" + memo);
                // 判斷resultStatus 爲“9000”則代表支付成功,具體狀態碼代表含義可參考接口文檔
                if (TextUtils.equals(resultStatus, "9000")) {
                    Toast.makeText(context, "支付成功", Toast.LENGTH_SHORT).show();
                } else {
                    // 判斷resultStatus 爲非“9000”則代表可能支付失敗
                    // “8000”代表支付結果因爲支付渠道原因或者系統原因還在等待支付結果確認,最終交易是否成功以服務端異步通知爲準(小概率狀態)
                    if (TextUtils.equals(resultStatus, "8000")) {
                        Toast.makeText(context, "支付結果確認中", Toast.LENGTH_SHORT)
                                .show();
                    } else {
                        // 其他值就可以判斷爲支付失敗,包括用戶主動取消支付,或者系統返回的錯誤
                        Toast.makeText(context, "支付失敗", Toast.LENGTH_SHORT)
                                .show();
                    }
                }
                break;
            }
            case SDK_CHECK_FLAG: {
                Toast.makeText(context, "檢查結果爲:" + msg.obj, Toast.LENGTH_SHORT)
                        .show();
                break;
            }
            default:
                break;
            }
        };
    };

    /**
     * call alipay sdk pay. 調用SDK支付 subject 商品名稱 body 商品詳情 price 該筆訂單的資金總額
     */
    public void pay(String subject, String body, String price) {
        if (TextUtils.isEmpty(PayConfig.PARTNER)
                || TextUtils.isEmpty(PayConfig.RSA_PRIVATE)
                || TextUtils.isEmpty(PayConfig.SELLER)) {
            new AlertDialog.Builder(context)
                    .setTitle("警告")
                    .setMessage("需要配置PARTNER | RSA_PRIVATE| SELLER")
                    .setPositiveButton("確定",
                            new DialogInterface.OnClickListener() {
                                public void onClick(
                                        DialogInterface dialoginterface, int i) {
                                    // ((Activity) context).finish();
                                }
                            }).show();
            return;
        }
        // 訂單
        String orderInfo = getOrderInfo(subject, body, price);

        // 對訂單做RSA 簽名
        String sign = sign(orderInfo);
        try {
            // 僅需對sign 做URL編碼
            sign = URLEncoder.encode(sign, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        // 完整的符合支付寶參數規範的訂單信息
        final String payInfo = orderInfo + "&sign=\"" + sign + "\"&"
                + getSignType();

        Runnable payRunnable = new Runnable() {
            @Override
            public void run() {
                // 構造PayTask 對象
                PayTask alipay = new PayTask((Activity) context);
                // 調用支付接口,獲取支付結果
                String result = alipay.pay(payInfo);

                Message msg = new Message();
                msg.what = SDK_PAY_FLAG;
                msg.obj = result;
                mHandler.sendMessage(msg);
            }
        };

        // 必須異步調用
        Thread payThread = new Thread(payRunnable);
        payThread.start();
    }

    /**
     * check whether the device has authentication alipay account.
     * 查詢終端設備是否存在支付寶認證賬戶
     */
    public void check(View v) {
        Runnable checkRunnable = new Runnable() {

            @Override
            public void run() {
                // 構造PayTask 對象
                PayTask payTask = new PayTask((Activity) context);
                // 調用查詢接口,獲取查詢結果
                boolean isExist = payTask.checkAccountIfExist();

                Message msg = new Message();
                msg.what = SDK_CHECK_FLAG;
                msg.obj = isExist;
                mHandler.sendMessage(msg);
            }
        };

        Thread checkThread = new Thread(checkRunnable);
        checkThread.start();

    }

    /**
     * get the sdk version. 獲取SDK版本號
     */
    public void getSDKVersion() {
        PayTask payTask = new PayTask((Activity) context);
        String version = payTask.getVersion();
        Toast.makeText(context, version, Toast.LENGTH_SHORT).show();
    }

    /**
     * create the order info. 創建訂單信息
     */
    public String getOrderInfo(String subject, String body, String price) {
        // 簽約合作者身份ID
        String orderInfo = "partner=" + "\"" + PayConfig.PARTNER + "\"";
        // 簽約賣家支付寶賬號
        orderInfo += "&seller_id=" + "\"" + PayConfig.SELLER + "\"";
        // 商戶網站唯一訂單號 getOutTradeNo()
        orderInfo += "&out_trade_no=" + "\"" + tradeNo + "\"";
        // 商品名稱
        orderInfo += "&subject=" + "\"" + subject + "\"";
        // 商品詳情
        orderInfo += "&body=" + "\"" + body + "\"";
        // 商品金額
        orderInfo += "&total_fee=" + "\"" + price + "\"";
        // 服務器異步通知頁面路徑  Url.PAYORDER 訂單支付-支付寶支付完成異步回調接口
        orderInfo += "&notify_url=" + "\"" + Url.PAYORDER + "\"";
        // 服務接口名稱, 固定值
        orderInfo += "&service=\"mobile.securitypay.pay\"";
        // 支付類型, 固定值
        orderInfo += "&payment_type=\"1\"";
        // 參數編碼, 固定值
        orderInfo += "&_input_charset=\"utf-8\"";
        // 設置未付款交易的超時時間
        // 默認30分鐘,一旦超時,該筆交易就會自動被關閉。
        // 取值範圍:1m~15d。
        // m-分鐘,h-小時,d-天,1c-當天(無論交易何時創建,都在0點關閉)。
        // 該參數數值不接受小數點,如1.5h,可轉換爲90m。
        orderInfo += "&it_b_pay=\"30m\"";
        // extern_token爲經過快登授權獲取到的alipay_open_id,帶上此參數用戶將使用授權的賬戶進行支付
        // orderInfo += "&extern_token=" + "\"" + extern_token + "\"";
        // 支付寶處理完請求後,當前頁面跳轉到商戶指定頁面的路徑,可空
        orderInfo += "&return_url=\"m.alipay.com\"";
        // 調用銀行卡支付,需配置此參數,參與簽名, 固定值 (需要簽約《無線銀行卡快捷支付》才能使用)
        // orderInfo += "&paymethod=\"expressGateway\"";
        return orderInfo;
    }

    /**
     * get the out_trade_no for an order. 生成商戶訂單號,該值在商戶端應保持唯一(可自定義格式規範)
     * 
     */
    public String getOutTradeNo() {
        SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss",
                Locale.getDefault());
        Date date = new Date();
        String key = format.format(date);
        Random r = new Random();
        key = key + r.nextInt();
        key = key.substring(0, 15);
        return key;
    }

    /**
     * sign the order info. 對訂單信息進行簽名
     * 
     * @param content
     *            待簽名訂單信息
     */
    public String sign(String content) {
        return SignUtils.sign(content, PayConfig.RSA_PRIVATE);
    }

    /**
     * get the sign type we use. 獲取簽名方式
     * 
     */
    public String getSignType() {
        return "sign_type=\"RSA\"";
    }

}

5、調起支付

AlipayPay alipayPay=new AlipayPay(context,moneySn);
alipayPay.pay("錢包充值", "支付寶充值","100");//第一個參數爲商品詳情,第二個參數爲商品描述,第三個參數爲商品價格

具體問題還是需要查看支付寶的官方文檔,如果文檔查詢不到建議找支付寶客服解決問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章