第三方支付至支付寶對接
阿新 • • 發佈:2019-01-09
前言
App開發中用到的支付有支付寶、微信、銀聯卡、pos等,但最常見的方式就是支付寶和微信支付,尤其電商專案。閒來沒事總結一下,以下是整合支付寶支付的個人心得。
首先App新增支付寶支付功能,需要滿足兩點條件。
1:簽約成為支付寶商戶
簽約地址:https://b.alipay.com/, 只有成為簽約商戶的開發者才能具備整合支付寶app支付的資格。 簽約資料:1)營業執照 2)APP說明文件 3)商戶經營資訊、商戶聯絡人等資訊
2:整合APP程式碼
2.1:匯入jar包資源
Eclipse將lib包複製到lib資料夾下,Android studio在gradle中可以新增依賴
compile files('libs/alipaySdk-20160223.jar')
- 1
- 2
2.2:修改AndroidManifest.xml清單
宣告activity
<activity
android:name="com.alipay.sdk.app.H5PayActivity"
android:configChanges="orientation|keyboardHidden|navigation"
android:exported="false"
android:screenOrientation="behind" >
- 1
- 2
- 3
- 4
- 5
- 6
<activity android:name="com.alipay.sdk.auth.AuthActivity" android:configChanges="orientation|keyboardHidden|navigation" android:exported="false" android:screenOrientation="behind" >
- 1
- 2
- 3
- 4
- 5
- 6
新增許可權
<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" />
- 1
- 2
- 3
- 4
- 5
- 6
2.3:根據情況新增支付寶混淆規則
2.4:新增主要程式碼(重要)
主要流程分為:
1:app通過下單呼叫後臺介面,然後後臺伺服器返回簽名後訂單資訊
2:app調起支付寶支付,傳簽名的訂單資訊,使用者輸入支付寶密碼進行支付
3:支付寶返回支付結果,app進行支付結果展示,支付寶服務端非同步回撥商戶服務端即我們自己後臺服務端,後臺更改訂單狀態
生成簽名後的訂單資訊官方建議安全起見,在後臺服務端生成,在此我在app端生成方面講解整個流程。
//生成訂單所需資訊
public String getOrderInfo(String order_id,String order_sn, String price) {
// 簽約合作者身份ID
String orderInfo = "partner=" + "\"" + Keys.DEFAULT_PARTNER + "\"";
// 簽約賣家支付寶賬號
orderInfo += "&seller_id=" + "\"" + Keys.DEFAULT_SELLER + "\"";
// 商戶網站唯一訂單號
orderInfo += "&out_trade_no=" + "\"" + order_id+"-"+getTimeByCalendar()+ "\"";
// 商品名稱
orderInfo += "&subject=" + "\"" + order_sn + "\"";
// 商品詳情
orderInfo += "&body=" + "\"" + order_id + "\"";
// 商品金額
orderInfo += "&total_fee=" + "\"" + price + "\"";
// 伺服器非同步通知頁面路徑
orderInfo += "¬ify_url=" + "\"" + payUrlBean.getAlipay_order_pay_notify()
+ "\"";
// 服務介面名稱, 固定值
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;
}
// 對訂單資訊做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();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
然後app需要調起支付寶上傳訂單資訊
Runnable payRunnable = new Runnable() {
@Override
public void run() {
// 構造PayTask 物件
PayTask alipay = new PayTask(OrderConfirmActivity.this);
boolean exist = alipay.checkAccountIfExist();
// 呼叫支付介面,獲取支付結果
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();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
根據支付寶返回的支付結果展示資訊
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);
// 支付寶返回此次支付結果及加簽,建議對支付寶簽名信息拿簽約時支付寶提供的公鑰做驗籤
String resultInfo = payResult.getResult();
String resultStatus = payResult.getResultStatus();
// 判斷resultStatus 為“9000”則代表支付成功,具體狀態碼代表含義可參考介面文件
if (TextUtils.equals(resultStatus, "9000")) {
Toast.makeText(OrderConfirmActivity.this, "支付成功",
Toast.LENGTH_SHORT).show();
//支付成功
} else {
// 判斷resultStatus 為非“9000”則代表可能支付失敗
// “8000”代表支付結果因為支付渠道原因或者系統原因還在等待支付結果確認,最終交易是否成功以服務端非同步通知為準(小概率狀態)
if (TextUtils.equals(resultStatus, "8000")) {
Toast.makeText(OrderConfirmActivity.this, "支付結果確認中",
Toast.LENGTH_SHORT).show();
} else {
// 其他值就可以判斷為支付失敗,包括使用者主動取消支付,或者系統返回的錯誤
Toast.makeText(OrderConfirmActivity.this, "支付失敗",
Toast.LENGTH_SHORT).show();
}
}
break;
default:
break;
}
};
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39