關於Android線上支付Alipay(支付寶)開發的經驗分享
阿新 • • 發佈:2019-01-28
在近期,公司需要開發一個關於線上支付的模組,所以需要用到第三方支付平臺
經過一週多的時間對這兩種支付平臺的研究,完成功能後將經驗分享給大家,希望能幫助到有需求的朋友。
申請流程
註冊支付寶賬號——進行實名認證——提交稽核資料——稽核通過
備註:申請通過後會獲得:合作者身份ID(PID),該ID在專案配置中需要用到
開發流程:
第一步:
下載API開發文件後,即可獲取官方Demo,該Demo中需要將稽核通過後獲取的PID替換,並且輸入支付寶收款賬戶即可。這裡非常簡單,就不過多敘述。
第二步:
官方Api開發文件中,存在一個openssl的資料夾,該資料夾主要是用於生成支付寶所需要用到的公鑰以及私鑰。開啟該資料夾可以看到詳細的生成方式,根據提示生成公鑰及私鑰,請注意,金鑰需要經過pkcs8二次加密。
第三步:
將生成的公鑰和私鑰配置到Demo中。
第四步(可省略):
為了方便後期維護,建議將支付寶相關的方法及配置項抽取出來做為單獨的一個類,後期需要使用直接呼叫即可。程式碼如下:
package com.alipay.pay;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Random;
import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.Toast;
import com.alipay.sdk.app.PayTask;
public class Alipay {
// 商戶PID
public static final String PARTNER = "******";
// 商戶收款賬號
public static final String SELLER = "***@alipay.com" ;
// 商戶私鑰,pkcs8格式
public static final String RSA_PRIVATE = "*****";
// 支付寶公鑰
public static final String RSA_PUBLIC = "******";
public static final int SDK_PAY_FLAG = 1;
public static final int SDK_CHECK_FLAG = 2;
private Handler mHandler;
private Activity activity;
private String orderNo;
public Alipay(Handler handler, Activity activity) {
mHandler = handler;
this.activity = activity;
}
/**
* call alipay sdk pay. 呼叫SDK支付
*
*/
public void pay(PayInfo payinfo) {
// 訂單
DecimalFormat df = new DecimalFormat("0.00");
String orderInfo = getOrderInfo(payinfo.getName(), payinfo.getDesc()
+ " ", df.format(payinfo.getPrice() * payinfo.getRate()));
// 對訂單做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(activity);
// 呼叫支付介面,獲取支付結果
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(activity);
// 呼叫查詢介面,獲取查詢結果
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(activity);
String version = payTask.getVersion();
Toast.makeText(activity, 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);
String md5 = Constants.MD5(key);
this.orderNo = md5;
return md5;
}
/**
* 獲取已經生產的訂單編號
*
* @return
*/
public String getOrderNo() {
return this.orderNo;
}
/**
* 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\"";
}
}
從上面程式碼可以看出,程式的主要執行流程是:通過開啟一個子執行緒去呼叫支付寶的支付功能,獲取到支付結果後,通過Handler通知UI執行緒,根據支付結果去顯示不同的。
到這裡基本上整個開發流程已經大致完成了,具體細節根據需求去修改即可。官方建議支付完成後,將獲取到的支付結果上傳到自己的伺服器,通過官方提供的API進行驗證,建議新增該流程。
如果有疑問,可以通過QQ381959281聯絡作者進行交流