1. 程式人生 > >Android接入支付寶支付實現

Android接入支付寶支付實現

price show inf mms subject 商品詳情 轉換 || In

接上篇android接入微信支付文章,這篇我們帶你來接入支付寶支付服務

簡介

首先要說明的是個人感覺接入支付寶比微信簡單多了,很輕松的,所以同學們不要緊張~

當然還是老規矩啦,上來肯定的貼上官網地址,因為我這些服務天天在更新,而我的文章是教大家方法,而讓你不是照葫蘆畫瓢

技術分享圖片

進入app支付文檔有兩種方式,一種是直接在下面的開放業務裏

技術分享圖片

還有一種是通過上面的導航欄文檔中心,然後滾動到業務接入那一欄,可以看到移動支付

技術分享圖片

當然也可以直接打開這個地址,文檔還是挺多,可以關註我勾選的這幾項

技術分享圖片

首先這裏我也要說明的是個人是不能申請的,只能是企業,所以我demo裏面的用的一些資料也是demo裏面的

這裏是交互流程的官方文檔,需要詳細的可以點進去看看

運行Demo

我們來到官方demo的下載地址

技術分享圖片

可以看到有兩個,選擇你需要的就行了,下載解壓完直接導入eclipse並配置一些參數運行就可以查看效果了

導入jar

將demo裏面的alipaySdk-20160223.jar拷貝到我們工程的libs下,並添加到依賴中

配置

權限

ses-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" />

activity

<activity
    android:name="com.alipay.sdk.app.H5PayActivity
" android:configChanges="orientation|keyboardHidden|navigation" android:exported="false" android:screenOrientation="behind"> </activity> <activity android:name="com.alipay.sdk.auth.AuthActivity" android:configChanges="orientation|keyboardHidden|navigation" android:exported="false" android:screenOrientation="behind"> </activity>

訂單數據生成

這一步,可以在服務端完成,也可以在本地完成

String orderInfo = getOrderInfo("測試的商品", "該測試商品的詳細描述", "0.01");
 
/**
 * 特別註意,這裏的簽名邏輯需要放在服務端,切勿將私鑰泄露在代碼中!
 */
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(MainActivity.this);
        // 調用支付接口,獲取支付結果
        String result = alipay.pay(payInfo, true);
 
        Message msg = new Message();
        msg.what = SDK_PAY_FLAG;
        msg.obj = result;
        mHandler.sendMessage(msg);
    }
};
 
// 必須異步調用
Thread payThread = new Thread(payRunnable);
payThread.start();

處理支付結果

@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
    @SuppressWarnings("unused")
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case SDK_PAY_FLAG: {
                PayResult payResult = new PayResult((String) 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(MainActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
                } else {
                    // 判斷resultStatus 為非"9000"則代表可能支付失敗
                    // "8000"代表支付結果因為支付渠道原因或者系統原因還在等待支付結果確認,最終交易是否成功以服務端異步通知為準(小概率狀態)
                    if (TextUtils.equals(resultStatus, "8000")) {
                        Toast.makeText(MainActivity.this, "支付結果確認中", Toast.LENGTH_SHORT).show();
 
                    } else {
                        // 其他值就可以判斷為支付失敗,包括用戶主動取消支付,或者系統返回的錯誤
                        Toast.makeText(MainActivity.this, "支付失敗", Toast.LENGTH_SHORT).show();
 
                    }
                }
                break;
            }
            default:
                break;
        }
    }
 
};

這裏支付成功了,只是提示用戶,還得從服務器確認是否正在支付了,我這裏只寫了本地,其他如果在服務端實現是一樣的,你把這代碼直接發給後端就行了(如果後端是Java開發),可以看到我們已經成功調起支付寶服務了

技術分享圖片

完整代碼:

package cn.woblog.testalipay;
 
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;
 
import com.alipay.sdk.app.PayTask;
 
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Random;
 
import cn.woblog.testalipay.domain.PayResult;
import cn.woblog.testalipay.util.SignUtils;
 
public class MainActivity extends AppCompatActivity {
    public static final String PARTNER = "";
 
    // 商戶收款賬號
    public static final String SELLER = "";
 
    // 商戶私鑰,pkcs8格式
    public static final String RSA_PRIVATE = "";
 
    private static final int SDK_PAY_FLAG = 1;
 
    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @SuppressWarnings("unused")
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SDK_PAY_FLAG: {
                    PayResult payResult = new PayResult((String) 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(MainActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
                    } else {
                        // 判斷resultStatus 為非"9000"則代表可能支付失敗
                        // "8000"代表支付結果因為支付渠道原因或者系統原因還在等待支付結果確認,最終交易是否成功以服務端異步通知為準(小概率狀態)
                        if (TextUtils.equals(resultStatus, "8000")) {
                            Toast.makeText(MainActivity.this, "支付結果確認中", Toast.LENGTH_SHORT).show();
 
                        } else {
                            // 其他值就可以判斷為支付失敗,包括用戶主動取消支付,或者系統返回的錯誤
                            Toast.makeText(MainActivity.this, "支付失敗", Toast.LENGTH_SHORT).show();
 
                        }
                    }
                    break;
                }
                default:
                    break;
            }
        }
 
    };
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
 
    public void testAlipay(View view) {
        if (TextUtils.isEmpty(PARTNER) || TextUtils.isEmpty(RSA_PRIVATE) || TextUtils.isEmpty(SELLER)) {
            new AlertDialog.Builder(this).setTitle("警告").setMessage("需要配置PARTNER | RSA_PRIVATE| SELLER")
                    .setPositiveButton("確定", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialoginterface, int i) {
                            //
                            finish();
                        }
                    }).show();
            return;
        }
 
        String orderInfo = getOrderInfo("測試的商品", "該測試商品的詳細描述", "0.01");
 
/**
 * 特別註意,這裏的簽名邏輯需要放在服務端,切勿將私鑰泄露在代碼中!
 */
        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(MainActivity.this);
                // 調用支付接口,獲取支付結果
                String result = alipay.pay(payInfo, true);
 
                Message msg = new Message();
                msg.what = SDK_PAY_FLAG;
                msg.obj = result;
                mHandler.sendMessage(msg);
            }
        };
 
// 必須異步調用
        Thread payThread = new Thread(payRunnable);
        payThread.start();
    }
 
 
    /**
     * create the order info. 創建訂單信息
     */
    private String getOrderInfo(String subject, String body, String price) {
 
        // 簽約合作者身份ID
        String orderInfo = "partner=" + "\"" + PARTNER + "\"";
 
        // 簽約賣家支付寶賬號
        orderInfo += "&seller_id=" + "\"" + SELLER + "\"";
 
        // 商戶網站唯一訂單號
        orderInfo += "&out_trade_no=" + "\"" + getOutTradeNo() + "\"";
 
        // 商品名稱
        orderInfo += "&subject=" + "\"" + subject + "\"";
 
        // 商品詳情
        orderInfo += "&body=" + "\"" + body + "\"";
 
        // 商品金額
        orderInfo += "&total_fee=" + "\"" + price + "\"";
 
        // 服務器異步通知頁面路徑
        orderInfo += "&notify_url=" + "\"" + "http://notify.msp.hk/notify.htm" + "\"";
 
        // 服務接口名稱, 固定值
        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;
    }
 
    /**
     * sign the order info. 對訂單信息進行簽名
     *
     * @param content 待簽名訂單信息
     */
    private String sign(String content) {
        return SignUtils.sign(content, RSA_PRIVATE);
    }
 
    /**
     * get the sign type we use. 獲取簽名方式
     */
    private String getSignType() {
        return "sign_type=\"RSA\"";
    }
 
    /**
     * get the out_trade_no for an order. 生成商戶訂單號,該值在商戶端應保持唯一(可自定義格式規範)
     */
    private 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;
    }
 
}

如果要測試demo,請替換

MainActivity中PARTNER,SELLER,RSA_PRIVATE為你申請到的值

Android接入支付寶支付實現