支付寶集成過程詳解——運行DEMO

前言,夢想是需要堅持的,在路上,一路前行。加油。


這兩天軟件需要集成支付寶了,第一次集成,過程還是挺簡單的,不過由於[支付寶官方文檔](https://docs.open.alipay.com/204/105297/)寫的不夠清晰,也是走了一些彎路,下面把過程寫出來分享給大家


一、申請移動支付權限

首先登錄【支付寶開放平臺】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頁面,創建一個應用


完成之後:在我的應用中是可以看得到的:


然後轉到帳戶基本信息頁面:https://openhome.alipay.com/platform/keyManage.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
得到生成功的結果,這個結果就是PKCS8格式的私鑰,如下圖:


注意,私鑰是紅框包括的那部分,是不包含BEGIN PRIVATE KEY和END PRIVATE KEY這兩行的。

右鍵點擊openssl窗口上邊邊緣,選擇編輯→標記,選中要複製的文字(如上圖),
此時繼續右鍵點擊openssl窗口上邊邊緣,選擇編輯→複製,
把複製的內容粘土進一個新的記事本中,可隨便命名,只要知道這個是PKCS8格式的私鑰即可。

(4)、生成商戶私鑰【MAC生成方法】

這裏來講一下mac端如何生成用戶私鑰的,由於mac系統是自帶openssl的,所以只需要打開終端,利用cd 命令切到任意一個想存放生成Key的文件夾下:
比如,切到下載目錄下


然後運行下面的命令來生成私鑰原始密鑰

openssl genrsa -out rsa_private_key.pem 1024
然後運行下面的命令來生成轉換的PCKS8格式的命令。
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
同樣,如果是Mac的同學,輸入的命令應該是如下:
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中配置幾個變量:

  1. //PID
  2. public static final String PARTNER = "";
在這裏填上我們上面找到的PID;
  1. // 商戶收款賬號
  2. public static final String SELLER = "[email protected]";
然後在SELLER上寫上我們支付寶的登錄帳戶,即那個你申請移動支付的支付寶賬號
  1. // 支付寶公鑰
  2. public static final String RSA_PUBLIC ="";
然後在RSA_PUBLIC這裏填上支付寶公鑰
  1. // 商戶私鑰,pkcs8格式
  2. public static final String RSA_PRIVATE = "";
最後是填上RSA_PRIVATE對應的商戶私鑰,注意是PKCS8格式的。
私鑰這部分,注意是----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----之間的部分,即那段純代碼,不要把----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----給複製進去了。中間的這部分就是公鑰。

現在運行demo就直接可以支付了。

本文中對應的DEMO在文章底部給出。

4、代碼講解

通過上面的配置,demo應該就直接可以運行了,但這裏所涉及的代碼,我們再仔細看看
主要的支付與結果返回就是pay()這個函數,這裏完成了支付所需要的所有功能。代碼如下:

  1. public void pay(View v) {
  2. …………
  3. // 訂單信息
  4. String orderInfo = getOrderInfo("測試的商品", "該測試商品的詳細描述", "0.01");
  5. // 對訂單做RSA 簽名
  6. String sign = sign(orderInfo);
  7. try {
  8. // 僅需對sign 做URL編碼
  9. sign = URLEncoder.encode(sign, "UTF-8");
  10. } catch (UnsupportedEncodingException e) {
  11. e.printStackTrace();
  12. }
  13. // 完整的符合支付寶參數規範的訂單信息
  14. final String payInfo = orderInfo + "&sign=\"" + sign + "\"&"
  15. + getSignType();
  16. Runnable payRunnable = new Runnable() {
  17. @Override
  18. public void run() {
  19. // 構造PayTask 對象
  20. PayTask alipay = new PayTask(PayDemoActivity.this);
  21. // 調用支付接口,獲取支付結果
  22. String result = alipay.pay(payInfo);
  23. Message msg = new Message();
  24. msg.what = SDK_PAY_FLAG;
  25. msg.obj = result;
  26. mHandler.sendMessage(msg);
  27. }
  28. };
  29. // 必須異步調用
  30. Thread payThread = new Thread(payRunnable);
  31. payThread.start();
  32. }

這裏總是分了四步來完成支付與結果接收。

第一步:構造定單信息:

String orderInfo = getOrderInfo("測試的商品", "該測試商品的詳細描述", "0.01");
主要是這句,即在getOrderInfo()函數中完成定單信息的構造:(這裏對getOrderInfo函數做的精減,更多字段及意義參考源碼)

有關paymethod的方法使用,參考:https://cshall.alipay.com/support/help_detail.htm?help_id=476935
各個字段的意義及取值參考:http://doc.open.alipay.com/doc2/detail?treeId=59&articleId=103663&docType=1

  1. public String getOrderInfo(String subject, String body, String price) {
  2. // 簽約合作者身份ID
  3. String orderInfo = "partner=" + "\"" + PARTNER + "\"";
  4. // 簽約賣家支付寶賬號
  5. orderInfo += "&seller_id=" + "\"" + SELLER + "\"";
  6. // 商戶網站唯一訂單號
  7. orderInfo += "&out_trade_no=" + "\"" + getOutTradeNo() + "\"";
  8. // 商品名稱
  9. orderInfo += "&subject=" + "\"" + subject + "\"";
  10. // 商品詳情
  11. orderInfo += "&body=" + "\"" + body + "\"";
  12. // 商品金額
  13. orderInfo += "&total_fee=" + "\"" + price + "\"";
  14. // 服務器異步通知頁面路徑
  15. orderInfo += "&notify_url=" + "\"" + "http://notify.msp.hk/notify.htm"
  16. + "\"";
  17. …………
  18. return orderInfo;
  19. }
這裏就是通過我們的提供的商家ID,產品信息,價格等信息來構造定單及回調頁面,這裏需要非常注意的一個地方:
  1. // 服務器異步通知頁面路徑
  2. orderInfo += "&noify_url=" + "\"" + "http://notify.msp.hk/notify.htm"
  3. + "\"";
服務器異步通知頁面路徑,首先我們用支付寶支付之後,支付寶會返回給我們兩個通知,一個是同步的,就是我們點擊支付後支付寶直接反饋給我們客戶端的信息,我們可以直接拿到,根據反饋的結果可以初步判定該次交易是否成功,第二個就是服務器異步的通知,這個異步的通知是支付寶的服務器端發給我們服務器端的信息,我們在客戶端是直接獲取不了的,那支付寶的服務器怎麼知道我們服務器的路徑呢,那就是這參數的作用了,我們給支付寶服務器一個路徑,它就會在訂單狀態改變的時候給我們服務器端一個反饋,告訴服務器這次交易的狀態,如果服務器結果判定該次交易成功了,就必須返給支付寶服務器一個success,要不服務器會一直給我們異步通知,因爲它不知道該次交易是否完成了(一般情況下25小時內8次通知,頻率一般是2m 10m 10m 1h 2h 6h 15h),我們一般會在收到異步通知時,對訂單的狀態進行更新。
其它的就不講了,通過看源碼都能看得懂,比如構造訂單號啥的。

第二步:對訂單字符串做RSA簽名

爲什麼要簽名呢?當然是防止傳輸出錯了,這可是跟錢相關的,如果orderInfo傳輸過程中出錯了,那怎麼樣來校驗它是不是出錯了呢,只有通過簽名算法來了。所以這裏就需要對訂單字符串做簽名。
具體簽名算法就不講了,直接應用到項目中就行,不需要理解,如果想看看怎麼實現的,裏面有對應的源碼,可以去研究一下。

  1. // 對訂單做RSA 簽名
  2. String sign = sign(orderInfo);
  3. try {
  4. // 僅需對sign 做URL編碼
  5. sign = URLEncoder.encode(sign, "UTF-8");
  6. } catch (UnsupportedEncodingException e) {
  7. e.printStackTrace();
  8. }

第三步:構造完成的請求字符串

在訂單字符串和簽名做完以後,就可以用他們來構造完整的請求字符串了:
  1. // 完整的符合支付寶參數規範的訂單信息
  2. final String payInfo = orderInfo + "&sign=\"" + sign + "\"&"
  3. + getSignType();

第四步:請求與結果返回

最後是發送請求,代碼如下:

  1. Runnable payRunnable = new Runnable() {
  2. @Override
  3. public void run() {
  4. // 構造PayTask 對象
  5. PayTask alipay = new PayTask(PayDemoActivity.this);
  6. // 調用支付接口,獲取支付結果
  7. String result = alipay.pay(payInfo);
  8. Message msg = new Message();
  9. msg.what = SDK_PAY_FLAG;
  10. msg.obj = result;
  11. mHandler.sendMessage(msg);
  12. }
  13. };
  14. // 必須異步調用
  15. Thread payThread = new Thread(payRunnable);
  16. payThread.start();
最關鍵的部分在這裏:
  1. PayTask alipay = new PayTask(PayDemoActivity.this);
  2. // 調用支付接口,獲取支付結果
  3. String result = alipay.pay(payInfo);
  4. Message msg = new Message();
  5. msg.what = SDK_PAY_FLAG;
  6. msg.obj = result;
  7. mHandler.sendMessage(msg);
在String result = alipay.pay(payInfo);中,就直接獲得了支付結果;
然後通過handler將結果發送出去。
這就是同步的方式獲取支付結果的方式。
好了,有關支付寶對接的方法全部都在這了。至於getOrderInfo函數裏,使用的調用銀行卡支付,我覺得也沒啥用,在我們程序裏也沒接上。


本文所使用的DEMO源碼下載地址:http://download.csdn.net/detail/harvic880925/9261363



原文地址: http://blog.csdn.net/harvic880925/article/details/49779061
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章