一、準備工作
〉1、下載開發(fā)包
壓縮包下的“支付寶錢包支付接口開發(fā)包”中即有Andoid使用支付寶的JAR和Demo
〉2、創(chuàng)建支付寶應(yīng)用
在支付寶開放平臺申請創(chuàng)建應(yīng)用
https://open.alipay.com/index.htm
支付寶平臺的應(yīng)用創(chuàng)建僅限于公司實名認證用戶,個人帳號是不能創(chuàng)建應(yīng)用的,應(yīng)用申請我沒試過,暫且不做說明
〉3、AndroidManifest.xml 修改 (權(quán)限、界面、服務(wù)等申明)


>4、獲取開發(fā)所需要的參數(shù)數(shù)據(jù)

商戶私鑰和支付寶公鑰都是需要通過支付寶開發(fā)包中的openssl文件夾下的bin目錄下的OpenSSL程序生成
命令如下:
RSA密鑰生成命令生成RSA私鑰openssl>genrsa-outrsa_private_key.pem1024
生成RSA公鑰openssl>rsa-inrsa_private_key.pem-pubout-outrsa_public_key.pem
將RSA私鑰轉(zhuǎn)換成PKCS8格式openssl>pkcs8-topk8-nocrypt-inform PEM-inrsa_private_key.pem-outform PEM outform

開發(fā)者的私鑰
1、必須保證只有一行文字,即,沒有回車、換行、空格等
2、去掉“—–BEGIN RSA PRIVATE KEY—–”、“—–END RSA PRIVATE KEY—–”,只保存這兩條文字之中的部分
◆開發(fā)者的公鑰
1、必須保證只有一行文字,即,沒有回車、換行、空格等
2、去掉“—–BEGIN PUBLIC KEY—–”、“—–END PUBLIC KEY—–”,只保存這兩條文字之中的部分
3、保存到一個臨時的記事本中。
參數(shù)設(shè)置完成
〉5、加載Jar文件
將開發(fā)包中的alipay-sdk-common文件夾下面的jar文件復(fù)制到項目的libs目錄下并加載
〉6、添加混淆規(guī)則
在gradle.properties文件中添加如下代碼
-libraryjars libs/alipaysdk.jar
-libraryjars libs/alipaysecsdk.jar
-libraryjars libs/alipayutdid.jar
-keepclasscom.alipay.android.app.IAlixPay{*;}
-keepclasscom.alipay.android.app.IAlixPay$Stub{*;}
-keepclasscom.alipay.android.app.IRemoteServiceCallback{*;}
-keepclasscom.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keepclasscom.alipay.sdk.app.PayTask{public*;}
-keepclasscom.alipay.sdk.app.AuthTask{public*;}
-keepclasscom.alipay.mobilesecuritysdk.*
-keepclasscom.ut.*
二、開發(fā)

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

/**
* 特別注意,這里的簽名邏輯需要放在服務(wù)端,切勿將私鑰泄露在代碼中!
*/
String sign = sign(orderInfo);
try {
/**
* 僅需對sign 做URL編碼
*/
sign = URLEncoder.encode(sign, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
/**
* 完整的符合支付寶參數(shù)規(guī)范的訂單信息
*/
final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();
Runnable payRunnable = new Runnable() {
@Override
public void run() {
// 構(gòu)造PayTask 對象
PayTask alipay = new PayTask(MainActivity.this);
// 調(diào)用支付接口,獲取支付結(jié)果
String result = alipay.pay(payInfo, true);
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
// 必須異步調(diào)用
Thread payThread = new Thread(payRunnable);
payThread.start();
3、支付結(jié)果獲取和處理

@SuppressLint("HandlerLeak")
privateHandlermHandler=newHandler() {
@SuppressWarnings("unused")
public voidhandleMessage(Message msg) {
switch(msg.what) {
caseSDK_PAY_FLAG: {
PayResult payResult =newPayResult((String) msg.obj);
//? ? ? ? ? ? ? ? ? ? Log.d("MainActivity", "msg.obj:" + msg.obj);
/**
* 同步返回的結(jié)果必須放置到服務(wù)端進行驗證(驗證的規(guī)則請看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”則代表支付成功,具體狀態(tài)碼代表含義可參考接口文檔
if(TextUtils.equals(resultStatus,"9000")) {
Toast.makeText(MainActivity.this,"支付成功", Toast.LENGTH_SHORT).show();
}else{
// 判斷resultStatus 為非"9000"則代表可能支付失敗
// "8000"代表支付結(jié)果因為支付渠道原因或者系統(tǒng)原因還在等待支付結(jié)果確認,最終交易是否成功以服務(wù)端異步通知為準(小概率狀態(tài))
if(TextUtils.equals(resultStatus,"8000")) {
Toast.makeText(MainActivity.this,"支付結(jié)果確認中", Toast.LENGTH_SHORT).show();
}else{
// 其他值就可以判斷為支付失敗,包括用戶主動取消支付,或者系統(tǒng)返回的錯誤
Toast.makeText(MainActivity.this,"支付失敗", Toast.LENGTH_SHORT).show();
}
}
break;
}
default:
break;
}
}
};
源碼地址:https://github.com/LostDeer