Android 支付寶整合Demo
一、申請移動支付許可權
首先登入【支付寶開放平臺】http://open.alipay.com/platform/home.htm,新增應用,申請移動支付許可權。申請開通支付,是需要公司檔案的,個人是不允許開始支付的。
具體細節就不再詳聊了,下面就講講如何將阿里給出的demo執行起來。
二、阿里支付DEMO
1、概述
(1)支付呼叫頁面及測試
支付寶在呼叫時,會首先看本地是不是存在支付寶客戶端,如果有的話,就直接呼叫客戶端進行支付,如果沒有,則呼叫jar包中的H5頁面支付。
所以在測試時,需要有測試兩種情境:有支付寶客戶端和沒有支付寶客戶端的情況。
(2)、客戶端與伺服器
在demo中大家可以看到,有客戶端的demo也有服務端的demo,大家可能覺得需要服務端寫好之後,客戶端才能整合,其實並不是。整個流程是這樣的:1,APP客戶端通過SDK傳送支付請求 (客戶端處理)
2,SDK支付成功並同步返回支付結果(客戶端處理)
3,支付寶伺服器向我們的伺服器傳送支付結果字串(服務端處理)
客戶端:從上面的流程可以看出,服務端只是用來接出非同步返回的支付結果的。而支付與同步結果返回都是在客戶端可以直接看得到的。所以在整合支付寶支付介面時,主要功能是在客戶端,即便服務端沒有做整合,也是可能付款成功的。
服務端:服務端只需要新增一個功能:介面支付結果返回
下面幾張圖顯示了整個demo的執行過程,由於沒辦法在真機上錄製gif,所以只能用圖片來代替了。
初始化介面:
點選支付後,跳出確認付款介面:
點選確認付款後,跳出輸入密碼介面:
最後是支付成功介面:
在看DEMO的程式碼之前,我們需要先配置幾個變數:
2、配置幾個變數
這部分會對程式碼中用到的幾個變數的找到方法或生成方法進行講述,部分資料引自支付寶開放平臺。(1)PID
合作者身份ID(PID)是商戶與支付寶簽約後,商戶獲得的支付寶商戶唯一識別碼。當商戶把支付寶功能接入商戶網站時會用到PID,以便讓支付寶認證商戶。
檢視PID步驟如下:
1、登入支付寶官方網站b.alipay.com
2、點選導航欄中“商家服務”
3、點選“查詢PID、Key”
(2)、APPID、APP SECRET和支付寶公鑰
在https://openhome.alipay.com/platform/createApp.htm頁面,建立一個應用完成之後:在我的應用中是可以看得到的:
在開放平臺金鑰欄,可以找到APPID,APP SECRET,和支付寶金鑰
這三個資料,都是在應用建立後,支付寶為我們生成好的,無法更改!
(3)、生成商戶私鑰【windows生成方法】
(有關mac的生成方法,下面會再補充)1、下載DEMO及SDK
到文件中心,檢視移動支付對應的文件,文件地址:http://doc.open.alipay.com/doc2/detail?treeId=59&articleId=103563&docType=1
然後,點選(SDK&DEMO下載)下載程式碼
2、得到原始私鑰
在程式碼中的DEMO/openssl/bin目錄下,有openssl.exe檔案
開啟openssl.exe
輸入
- genrsa -out rsa_private_key.pem 1024
此時,我們可以在bin資料夾中看到一個檔名為rsa_private_key.pem的檔案
用記事本方式開啟它,可以看到-----BEGIN RSA PRIVATE KEY-----開頭,-----END RSA PRIVATE KEY-----結尾的沒有換行的字串,這個就是原始的私鑰。
但這段原始私鑰程式碼中是用不到的,我們需要將它轉化為PKCS8格式
3、轉換為PKCS8格式
在openssl.exe中輸入:並回車
- pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
注意,私鑰是紅框包括的那部分,是不包含BEGIN PRIVATE KEY和END PRIVATE KEY這兩行的。
右鍵點選openssl視窗上邊邊緣,選擇編輯→標記,選中要複製的文字(如上圖),
此時繼續右鍵點選openssl視窗上邊邊緣,選擇編輯→複製,
把複製的內容粘土進一個新的記事本中,可隨便命名,只要知道這個是PKCS8格式的私鑰即可。
(4)、生成商戶私鑰【MAC生成方法】
這裡來講一下mac端如何生成使用者私鑰的,由於mac系統是自帶openssl的,所以只需要開啟終端,利用cd 命令切到任意一個想存放生成Key的資料夾下:
比如,切到下載目錄下
然後執行下面的命令來生成私鑰原始金鑰
- openssl genrsa -out rsa_private_key.pem 1024
- openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
從上面的命令可以看出,與windows相比,mac上需要在前面新增openssl指定執行的是openssl命令。其它命令是完全一致的。
(5)、生成使用者公鑰及網頁填充
1、生成公鑰同樣對於windows使用者而言,直接在openssl.exe中輸入下面的命令:
- rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
- openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
此時,我們可以在bin資料夾中看到一個檔名為rsa_public_key.pem的檔案,用記事本方式開啟它,可以看到-----BEGIN PUBLIC KEY-----開頭,
-----END PUBLIC KEY-----結尾的沒有換行的字串,這個就是公鑰。
在生成網頁以後,複製----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----之間的部分,即那段純程式碼,不要把----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----給複製進去了。中間的這部分就是公鑰。
2、網頁填充
然後到https://openhome.alipay.com/platform/keyManage.htm?keyType=partner(需要登入)中,左側找到合作伙伴金鑰欄,再到右側的RSA加密中,將公鑰貼上進去。由於,我們已經貼上進去了,所以這裡顯示檢視開發者公鑰,在沒填之前寫的是“新增開發者公鑰”
到這裡,所有的準備工作都已經結束了。下面就是配置DEMO的過程了
3、配置DEMO
在剛才下載的sdk&demo的原始碼中,開啟DEMO/客戶端demo/支付寶Android 15.0.1/alipay_demo工程路徑如下:
在PayDemoActivity中配置幾個變數:
- //PID
- publicstaticfinal String PARTNER = "";
- // 商戶收款賬號
- publicstaticfinal String SELLER = "[email protected]";
- // 支付寶公鑰
- publicstaticfinal String RSA_PUBLIC ="";
- // 商戶私鑰,pkcs8格式
- publicstaticfinal String RSA_PRIVATE = "";
私鑰這部分,注意是----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----之間的部分,即那段純程式碼,不要把----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----給複製進去了。中間的這部分就是公鑰。
現在執行demo就直接可以支付了。
本文中對應的DEMO在文章底部給出。4、程式碼講解
通過上面的配置,demo應該就直接可以運行了,但這裡所涉及的程式碼,我們再仔細看看主要的支付與結果返回就是pay()這個函式,這裡完成了支付所需要的所有功能。程式碼如下:
- publicvoid pay(View v) {
- …………
- // 訂單資訊
- 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
- publicvoid 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();
- }
這裡總是分了四步來完成支付與結果接收。
第一步:構造定單資訊:
- String orderInfo = getOrderInfo("測試的商品", "該測試商品的詳細描述", "0.01");
- 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"
- + "\"";
- …………
- return orderInfo;
- }
- // 伺服器非同步通知頁面路徑
- orderInfo += "&noify_url=" + "\"" + "http://notify.msp.hk/notify.htm"
- + "\"";
其它的就不講了,通過看原始碼都能看得懂,比如構造訂單號啥的。
第二步:對訂單字串做RSA簽名
為什麼要簽名呢?當然是防止傳輸出錯了,這可是跟錢相關的,如果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();
第四步:請求與結果返回
最後是傳送請求,程式碼如下:- Runnable payRunnable = new Runnable() {
- @Override
- publicvoid 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();
- 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);
然後通過handler將結果傳送出去。
這就是同步的方式獲取支付結果的方式。
好了,有關支付寶對接的方法全部都在這了。至於getOrderInfo函式裡,使用的呼叫銀行卡支付,我覺得也沒啥用,在我們程式裡也沒接上。