1. 程式人生 > >關於Android線上支付Alipay(支付寶)開發的經驗分享

關於Android線上支付Alipay(支付寶)開發的經驗分享

在近期,公司需要開發一個關於線上支付的模組,所以需要用到第三方支付平臺

經過一週多的時間對這兩種支付平臺的研究,完成功能後將經驗分享給大家,希望能幫助到有需求的朋友。

申請流程
註冊支付寶賬號——進行實名認證——提交稽核資料——稽核通過

備註:申請通過後會獲得:合作者身份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 += "&notify_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聯絡作者進行交流