之前講了一篇部落格關與支付寶整合擷取支付寶公開金鑰與商戶私密金鑰的部落格。這一片講的是如何在項目中整合支付寶。首先要運行我們的Demo.就是配置好公開金鑰與私密金鑰的Demo。只要Demo 運行起來了,那麼接下來,就是如何移植代碼的問題了。
第一步:
將Demo中libs 檔案夾下面的支付寶jar 包拷貝到 所需要引入的項目中的libs 檔案下,如果沒有此檔案,可以自己在項目中建立libs 檔案,並將sdk的jar包引入其中。
第二步:
配置AndroidManifest.xml檔案。此檔案大都是配置資訊的。整合支付寶,當然也不例外。下面的代碼也是從Demo中拷貝過來的,資訊如下:
<!-- alipay sdk begin -->
<activity
android:name="com.alipay.sdk.app.H5PayActivity"
android:configChanges="orientation|keyboardHidden|navigation"
android:exported="false"
android:screenOrientation="behind"
android:windowSoftInputMode="adjustResize|stateHidden" >
</activity>
<!-- alipay sdk end -->
可以看到的是這是一個Activity.設定檔。就如平常的註冊Activity 一樣,放在application節點之中即可。下面是許可權的配置:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
這是必要的許可權,如果添加過的,就不需要重新添加了。沒有的,則需要添加到裡面。
第三步:
拷貝java檔案,同樣是Demo 檔案中,在你需要引入支付寶的項目中建立一個包,來存放必須要的java 檔案。分別是下面幾個檔案: Base64.java,PayResult.java與SignUtils.java 檔案,我下載的是alipaySDK-20150610.jar 的jar 包。只需要引入這些檔案即可。
第四步:
下面就是主要Activity的代碼的引入了。主要代碼如下:
public static final String PARTNER = "註冊賬戶的PID";
// 商戶收款帳號
public static final String SELLER = "支付寶收款賬戶";
// 商戶私密金鑰,pkcs8格式
public static final String RSA_PRIVATE = "商戶私密金鑰";
// 支付寶公開金鑰
public static final String RSA_PUBLIC = "支付寶公開金鑰";
private static final int SDK_PAY_FLAG = 1;
private static final int SDK_CHECK_FLAG = 2;
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();
// 判斷resultStatus 為“9000”則代表支付成功,具體狀態代碼代表含義可參考介面文檔
if (TextUtils.equals(resultStatus, "9000")) {
Toast.makeText(PayDemoActivity.this, "支付成功",
Toast.LENGTH_SHORT).show();
} else {
// 判斷resultStatus 為非“9000”則代表可能支付失敗
// “8000”代表支付結果因為支付渠道原因或者系統原因還在等待支付結果確認,最終交易是否成功以服務端非同步通知為準(小機率狀態)
if (TextUtils.equals(resultStatus, "8000")) {
Toast.makeText(PayDemoActivity.this, "支付結果確認中",
Toast.LENGTH_SHORT).show();
} else {
// 其他值就可以判斷為支付失敗,包括使用者主動取消支付,或者系統返回的錯誤
Toast.makeText(PayDemoActivity.this, "支付失敗",
Toast.LENGTH_SHORT).show();
}
}
break;
}
case SDK_CHECK_FLAG: {
Toast.makeText(PayDemoActivity.this, "檢查結果為:" + msg.obj,
Toast.LENGTH_SHORT).show();
break;
}
default:
break;
}
};
};
這段代碼,是一個Handler,放在Java 檔案的頂部。
* call alipay sdk pay. 調用SDK支付
*
*/
public void pay() {
// 訂單
String orderInfo = getOrderInfo("測試的商品", "該測試商品的詳細描述", "0.01");
// 對訂單做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(PayDemoActivity.this);
// 調用支付介面,擷取支付結果
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(PayDemoActivity.this);
// 調用查詢介面,擷取查詢結果
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(this);
String version = payTask.getVersion();
Toast.makeText(this, version, Toast.LENGTH_SHORT).show();
}
/**
* create the order info. 建立訂單資訊
*
*/
public 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 += "¬ify_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;
}
/**
* 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, RSA_PRIVATE);
}
/**
* get the sign type we use. 擷取簽名方式
*
*/
public String getSignType() {
return "sign_type=\"RSA\"";
}
}
這一段代碼要和上一段代碼放在一個Java 檔案中,需要注意的一個方法是。 pay() 方法和getOrderInfo(); 需要注意的是,在我們選擇支付寶支付的按鈕中調用的 是 pay() 方法。而放在pay()方法中則需要調用getOrderInfo(),仔細發現,getOrderInfo()方法裡面的三個參數。其中price 參數就是我們要消費的金額,當我們調用pay()方法的時候,就需要傳入一個price 的參數,就是我們需要支付的金額。具體的金額怎麼傳入,計算,要根據項目需要來自己擷取了,這樣項目整合支付寶就圓滿結束了。