android 支付寶第三方支付

支付寶集成文檔

一、申請移動支付權限

首先登錄【支付寶開放平臺】http://open.alipay.com/platform/home.htm,添加應用,申請移動支付權限。申請開通支付,是需要公司文件的,個人是不允許開始支付的。

二、阿里支付DEMO

自己去下載

2、配置幾個變量

這部分會對代碼中用到的幾個變量的找到方法或生成方法進行講述,部分資料引自支付寶開放平臺。

(1)PID

合作者身份IDPID)是商戶與支付寶簽約後,商戶獲得的支付寶商戶唯一識別碼。當商戶把支付寶功能接入商戶網站時會用到PID,以便讓支付寶認證商戶。
查看PID步驟如下:
1、登錄支付寶官方網站b.alipay.com
2、點擊導航欄中商家服務

 

3、點擊查詢PIDKey”

 

(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 KEYEND 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中配置幾個變量:

//PID

public static final String PARTNER = "";

在這裏填上我們上面找到的PID;

// 商戶收款賬號

public static final String SELLER = "[email protected]";

然後在SELLER上寫上我們支付寶的登錄帳戶,即那個你申請移動支付的支付寶賬號

// 支付寶公鑰

public static final String RSA_PUBLIC ="";

然後在RSA_PUBLIC這裏填上支付寶公鑰

// 商戶私鑰,pkcs8格式

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()這個函數,這裏完成了支付所需要的所有功能。代碼如下:

public void 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

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();

}


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

第一步:構造定單信息:

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

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;

}

這裏就是通過我們的提供的商家ID,產品信息,價格等信息來構造定單及回調頁面,這裏需要非常注意的一個地方:

// 服務器異步通知頁面路徑

orderInfo += "&noify_url=" + "\"" + "http://notify.msp.hk/notify.htm"

+ "\"";

服務器異步通知頁面路徑,首先我們用支付寶支付之後,支付寶會返回給我們兩個通知,一個是同步的,就是我們點擊支付後支付寶直接反饋給我們客戶端的信息,我們可以直接拿到,根據反饋的結果可以初步判定該次交易是否成功,第二個就是服務器異步的通知,這個異步的通知是支付寶的服務器端發給我們服務器端的信息,我們在客戶端是直接獲取不了的,那支付寶的服務器怎麼知道我們服務器的路徑呢,那就是這參數的作用了,我們給支付寶服務器一個路徑,它就會在訂單狀態改變的時候給我們服務器端一個反饋,告訴服務器這次交易的狀態,如果服務器結果判定該次交易成功了,就必須返給支付寶服務器一個success,要不服務器會一直給我們異步通知,因爲它不知道該次交易是否完成了(一般情況下25小時內8次通知,頻率一般是2m 10m 10m 1h 2h 6h 15h),我們一般會在收到異步通知時,對訂單的狀態進行更新。
其它的就不講了,通過看源碼都能看得懂,比如構造訂單號啥的。

第二步:對訂單字符串做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

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();

最關鍵的部分在這裏:

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);

String result = alipay.pay(payInfo);中,就直接獲得了支付結果;
然後通過handler將結果發送出去。
這就是同步的方式獲取支付結果的方式。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章