前言
App開發(fā)中用到的支付有支付寶异剥、微信瑟由、銀聯(lián)卡、pos等冤寿,但最常見的方式就是支付寶和微信支付歹苦,尤其電商項(xiàng)目。閑來沒事總結(jié)一下督怜,以下是集成支付寶支付的個(gè)人心得殴瘦。
首先App添加支付寶支付功能,需要滿足兩點(diǎn)條件号杠。
1:簽約成為支付寶商戶
簽約地址:https://b.alipay.com/痴施, 只有成為簽約商戶的開發(fā)者才能具備集成支付寶app支付的資格。 簽約資料:1)營業(yè)執(zhí)照 2)APP說明文檔 3)商戶經(jīng)營信息、商戶聯(lián)系人等信息
2:集成APP代碼
2.1:導(dǎo)入jar包資源
Eclipse將lib包復(fù)制到lib文件夾下辣吃,Android studio在gradle中可以添加依賴
compile files('libs/alipaySdk-20160223.jar')
2.2:修改AndroidManifest.xml清單
聲明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>
添加權(quán)限
<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" />
2.3:根據(jù)情況添加支付寶混淆規(guī)則
2.4:添加主要代碼(重要)
支付寶數(shù)據(jù)交互流程圖
主要流程分為:
1:app通過下單調(diào)用后臺(tái)接口动遭,然后后臺(tái)服務(wù)器返回簽名后訂單信息
2:app調(diào)起支付寶支付,傳簽名的訂單信息神得,用戶輸入支付寶密碼進(jìn)行支付
3:支付寶返回支付結(jié)果厘惦,app進(jìn)行支付結(jié)果展示,支付寶服務(wù)端異步回調(diào)商戶服務(wù)端即我們自己后臺(tái)服務(wù)端哩簿,后臺(tái)更改訂單狀態(tài)
生成簽名后的訂單信息官方建議安全起見宵蕉,在后臺(tái)服務(wù)端生成,在此我在app端生成方面講解整個(gè)流程节榜。
//生成訂單所需信息
public String getOrderInfo(String order_id,String order_sn, String price) {
// 簽約合作者身份ID
String orderInfo = "partner=" + "\"" + Keys.DEFAULT_PARTNER + "\"";
// 簽約賣家支付寶賬號(hào)
orderInfo += "&seller_id=" + "\"" + Keys.DEFAULT_SELLER + "\"";
// 商戶網(wǎng)站唯一訂單號(hào)
orderInfo += "&out_trade_no=" + "\"" + order_id+"-"+getTimeByCalendar()+ "\"";
// 商品名稱
orderInfo += "&subject=" + "\"" + order_sn + "\"";
// 商品詳情
orderInfo += "&body=" + "\"" + order_id + "\"";
// 商品金額
orderInfo += "&total_fee=" + "\"" + price + "\"";
// 服務(wù)器異步通知頁面路徑
orderInfo += "¬ify_url=" + "\"" + payUrlBean.getAlipay_order_pay_notify()
+ "\"";
// 服務(wù)接口名稱羡玛, 固定值
orderInfo += "&service=\"mobile.securitypay.pay\"";
// 支付類型, 固定值
orderInfo += "&payment_type=\"1\"";
// 參數(shù)編碼宗苍, 固定值
orderInfo += "&_input_charset=\"utf-8\"";
// 設(shè)置未付款交易的超時(shí)時(shí)間
// 默認(rèn)30分鐘稼稿,一旦超時(shí),該筆交易就會(huì)自動(dòng)被關(guān)閉讳窟。
// 取值范圍:1m~15d让歼。
// m-分鐘,h-小時(shí)丽啡,d-天谋右,1c-當(dāng)天(無論交易何時(shí)創(chuàng)建,都在0點(diǎn)關(guān)閉)补箍。
// 該參數(shù)數(shù)值不接受小數(shù)點(diǎn)改执,如1.5h,可轉(zhuǎn)換為90m坑雅。
orderInfo += "&it_b_pay=\"30m\"";
// extern_token為經(jīng)過快登授權(quán)獲取到的alipay_open_id,帶上此參數(shù)用戶將使用授權(quán)的賬戶進(jìn)行支付
// orderInfo += "&extern_token=" + "\"" + extern_token + "\"";
// 支付寶處理完請(qǐng)求后天梧,當(dāng)前頁面跳轉(zhuǎn)到商戶指定頁面的路徑,可空
orderInfo += "&return_url=\"m.alipay.com\"";
// 調(diào)用銀行卡支付霞丧,需配置此參數(shù)呢岗,參與簽名, 固定值 (需要簽約《無線銀行卡快捷支付》才能使用)
// orderInfo += "&paymethod=\"expressGateway\"";
return orderInfo;
}
// 對(duì)訂單信息做RSA 簽名
String sign = sign(orderInfo);
try {
// 僅需對(duì)sign 做URL編碼
sign = URLEncoder.encode(sign, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// 完整的符合支付寶參數(shù)規(guī)范的訂單信息
final String payInfo = orderInfo + "&sign=\"" + sign + "\"&"+ getSignType();
然后app需要調(diào)起支付寶上傳訂單信息
Runnable payRunnable = new Runnable() {
@Override
public void run() {
// 構(gòu)造PayTask 對(duì)象
PayTask alipay = new PayTask(OrderConfirmActivity.this);
boolean exist = alipay.checkAccountIfExist();
// 調(diào)用支付接口蛹尝,獲取支付結(jié)果
String result = alipay.pay(payInfo);
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
// 必須異步調(diào)用
Thread payThread = new Thread(payRunnable);
payThread.start();
根據(jù)支付寶返回的支付結(jié)果展示信息
private Handler mHandler = new Handler() {
@Override
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case RQF_PAY:
//支付成功
break;
case RQF_LOGIN:
//支付失敗
break;
case SDK_PAY_FLAG:
PayResult payResult = new PayResult((String) msg.obj);
// 支付寶返回此次支付結(jié)果及加簽后豫,建議對(duì)支付寶簽名信息拿簽約時(shí)支付寶提供的公鑰做驗(yàn)簽
String resultInfo = payResult.getResult();
String resultStatus = payResult.getResultStatus();
// 判斷resultStatus 為“9000”則代表支付成功,具體狀態(tài)碼代表含義可參考接口文檔
if (TextUtils.equals(resultStatus, "9000")) {
Toast.makeText(OrderConfirmActivity.this, "支付成功",
Toast.LENGTH_SHORT).show();
//支付成功
} else {
// 判斷resultStatus 為非“9000”則代表可能支付失敗
// “8000”代表支付結(jié)果因?yàn)橹Ц肚涝蚧蛘呦到y(tǒng)原因還在等待支付結(jié)果確認(rèn)突那,最終交易是否成功以服務(wù)端異步通知為準(zhǔn)(小概率狀態(tài))
if (TextUtils.equals(resultStatus, "8000")) {
Toast.makeText(OrderConfirmActivity.this, "支付結(jié)果確認(rèn)中",
Toast.LENGTH_SHORT).show();
} else {
// 其他值就可以判斷為支付失敗挫酿,包括用戶主動(dòng)取消支付,或者系統(tǒng)返回的錯(cuò)誤
Toast.makeText(OrderConfirmActivity.this, "支付失敗",
Toast.LENGTH_SHORT).show();
}
}
break;
default:
break;
}
};
};