java如何集成支付寶移動快捷支付功能

項目須要,須要在客戶端集成支付寶接口。第一次集成,過程仍是挺簡單的,不過因爲支付寶官方文檔寫的不夠清晰,也是走了一些彎路,下面把過程寫出來分享給你們。就研究了一下:由於使用支付寶接口,就須要到支付寶官網:註冊賬號,並申請。下面講的是申請好以後的操做。登陸成功以後,   店家個人商家服務—在頁面的下方找到——>簽約管理—>找打 移動支付—–>點擊下載集成文檔—>跳到新的頁面,在頁面下方—>找到下載開發包,下載移動支付便可。而後解壓出來以後通常會獲得三個文件夾。java


1、申請移動支付權限

首先登陸【支付寶開放平臺】http://open.alipay.com/platform/home.htm,添加應用,申請移動支付權限。申請開通支付,是須要公司文件的,我的是不容許開始支付的。
具體細節就再也不詳聊了,下面就講講如何將阿里給出的demo運行起來。
android

2、阿里支付DEMO

一、概述

(1)支付調用頁面及測試

支付寶在調用時,會首先看本地是否是存在支付寶客戶端,若是有的話,就直接調用客戶端進行支付,若是沒有,則調用jar包中的H5頁面支付。
因此在測試時,須要有測試兩種情境:有支付寶客戶端和沒有支付寶客戶端的狀況。
算法

 

(2)、客戶端與服務器

在demo中你們能夠看到,有客戶端的demo也有服務端的demo,你們可能以爲須要服務端寫好以後,客戶端才能集成,其實並非。整個流程是這樣的:
1,APP客戶端經過SDK發送支付請求 (客戶端處理)
2,SDK支付成功並同步返回支付結果(客戶端處理)
3,支付寶服務器向咱們的服務器發送支付結果字符串(服務端處理)
客戶端:從上面的流程能夠看出,服務端只是用來接出異步返回的支付結果的。而支付與同步結果返回都是在客戶端能夠直接看獲得的。因此在集成支付寶支付接口時,主要功能是在客戶端,即使服務端沒有作集成,也是可能付款成功的。
服務端:服務端只須要添加一個功能:接口支付結果返回

下面幾張圖顯示了整個demo的運行過程,因爲沒辦法在真機上錄製gif,因此只能用圖片來代替了。
初始化界面:

 

點擊支付後,跳出確認付款界面:
express


點擊確認付款後,跳出輸入密碼界面:
windows

最後是支付成功界面:
服務器


在看DEMO的代碼以前,咱們須要先配置幾個變量:
app

二、配置幾個變量

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

(1)PID

 

合做者身份ID(PID)是商戶與支付寶簽約後,商戶得到的支付寶商戶惟一識別碼。當商戶把支付寶功能接入商戶網站時會用到PID,以便讓支付寶認證商戶。
查看PID步驟以下:
一、登陸支付寶官方網站b.alipay.com
二、點擊導航欄中「商家服務」
dom


三、點擊「查詢PID、Key」
異步


 

(2)、APPID、APP SECRET和支付寶公鑰

https://openhome.alipay.com/platform/createApp.htm頁面,建立一個應用

 


完成以後:在個人應用中是能夠看獲得的:
ide


而後轉到賬戶基本信息頁面:https://openhome.alipay.com/platform/keyManage.htm


在開放平臺密鑰欄,能夠找到APPID,APP SECRET,和支付寶密鑰
這三個數據,都是在應用建立後,支付寶爲咱們生成好的,沒法更改!

 

(3)、生成商戶私鑰【windows生成方法】

(有關mac的生成方法,下面會再補充)
一、下載DEMO及SDK
到文檔中心,查看移動支付對應的文檔,文檔地址:http://doc.open.alipay.com/doc2/detail?treeId=59&articleId=103563&docType=1
而後,點擊(SDK&DEMO下載)下載代碼

 


二、獲得原始私鑰
在代碼中的DEMO/openssl/bin目錄下,有openssl.exe文件


打開openssl.exe
輸入

 

copy
 
 
 
genrsa -out rsa_private_key.pem   

獲得生成成功的結果,以下圖:

 

此時,咱們能夠在bin文件夾中看到一個文件名爲rsa_private_key.pem的文件


用記事本方式打開它,能夠看到-----BEGIN RSA PRIVATE KEY-----開頭,-----END RSA PRIVATE KEY-----結尾的沒有換行的字符串,這個就是原始的私鑰。


但這段原始私鑰代碼中是用不到的,咱們須要將它轉化爲PKCS8格式
三、轉換爲PKCS8格式
在openssl.exe中輸入:並回車

 

copy
 
 
 

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的文件夾下:
好比,切到下載目錄下


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

 

copy
 
 
 

openssl genrsa -out rsa_private_key.pem    而後運行下面的命令來生成轉換的PCKS8格式的命令。

copy
 
 
 

openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt   而後將生成的私鑰複製保存起來。
從上面的命令能夠看出,與windows相比,mac上須要在前面添加openssl指定運行的是openssl命令。其它命令是徹底一致的。

(5)、生成用戶公鑰及網頁填充

一、生成公鑰
一樣對於windows用戶而言,直接在openssl.exe中輸入下面的命令:

copy
 
 
 

rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem   一樣,若是是Mac的同窗,輸入的命令應該是以下:

copy
 
 
 

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-----給複製進去了。中間的這部分就是公鑰。
二、網頁填充

上傳RSA公鑰,在「合做夥伴密鑰管理」下,點擊「RSA加密」後的「添加密鑰」,把本身的公鑰複製進去。注意不能有空格,換行之類的。

  

點擊確認上傳,如果提示上傳成功。則就是成功。

這個時候就可查看支付寶公鑰了。如圖:


至此,將對應的私鑰與公鑰填到相應位置咱們的Demo  就可一運行了。到這裏,全部的準備工做都已經結束了。下面就是配置DEMO的過程了

三、配置DEMO

在剛纔下載的sdk&demo的源碼中,打開DEMO/客戶端demo/支付寶Android 15.0.1/alipay_demo工程

第一步:

 

將Demo中libs 文件夾下面的支付寶jar 包拷貝到 所須要引入的項目中的libs 文件下,若是沒有此文件,能夠本身在項目中新建libs 文件,並將sdk的jar包引入其中。

第二步:

配置AndroidManifest.xml文件。此文件大都是配置信息的。集成支付寶,固然也不例外。下面的代碼也是從Demo中拷貝過來的,信息以下:

<span class="comment" style="color: rgb(153, 153, 136); font-style: italic;"><!-- alipay sdk begin --></span>
<span class="tag" style="color: rgb(0, 0, 128);"><<span class="title">activity
<span class="indent">  </span>android:name="com.alipay.sdk.app.H5PayActivity"
<span class="indent">  </span>android:configChanges="orientation|keyboardHidden|navigation"
<span class="indent">  </span>android:exported="false"
<span class="indent">  </span>android:screenOrientation="behind"
<span class="indent">  </span>android:windowSoftInputMode="adjustResize|stateHidden"</span> ></span>
<span class="tag" style="color: rgb(0, 0, 128);"></<span class="title">activity</span>></span>
<span class="comment" style="color: rgb(153, 153, 136); font-style: italic;"><!-- alipay sdk end --></span>

<span class="tag" style="color: rgb(0, 0, 128);"><<span class="title">uses-permission</span> <span class="attribute" style="color: rgb(0, 128, 128);">android:name</span>=<span class="value" style="color: rgb(221, 17, 68);">"android.permission.INTERNET"</span> /></span> <span class="tag" style="color: rgb(0, 0, 128);"><<span class="title">uses-permission</span> <span class="attribute" style="color: rgb(0, 128, 128);">android:name</span>=<span class="value" style="color: rgb(221, 17, 68);">"android.permission.WRITE_EXTERNAL_STORAGE"</span> /></span> <span class="tag" style="color: rgb(0, 0, 128);"><<span class="title">uses-permission</span> <span class="attribute" style="color: rgb(0, 128, 128);">android:name</span>=<span class="value" style="color: rgb(221, 17, 68);">"android.permission.ACCESS_NETWORK_STATE"</span> /></span> <span class="tag" style="color: rgb(0, 0, 128);"><<span class="title">uses-permission</span> <span class="attribute" style="color: rgb(0, 128, 128);">android:name</span>=<span class="value" style="color: rgb(221, 17, 68);">"android.permission.READ_PHONE_STATE"</span> /></span> <span class="tag" style="color: rgb(0, 0, 128);"><<span class="title">uses-permission</span> <span class="attribute" style="color: rgb(0, 128, 128);">android:name</span>=<span class="value" style="color: rgb(221, 17, 68);">"android.permission.ACCESS_WIFI_STATE"</span> /></span>

這是必要的權限,若是添加過的,就不須要從新添加了。沒有的,則須要添加到裏面。

 

第三步:

拷貝Java文件,一樣是Demo 文件中,在你須要引入支付寶的項目中新建一個包,來存放必需要的Java 文件。分別是下面幾個文件: Base64.Java,PayResult.java與SignUtils.java 文件,我下載的是alipaySDK.jar 的jar 包。只須要引入這些文件便可。

第四步:

下面就是主要Activity的代碼的引入了。主要代碼以下:

<span class="keyword" style="font-weight: bold;">public</span> <span class="keyword" style="font-weight: bold;">static</span> <span class="keyword" style="font-weight: bold;">final</span> String PARTNER = <span class="string" style="color: rgb(221, 17, 68);">"註冊帳戶的PID"</span>;
<span class="indent">  </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 商戶收款帳號</span>
<span class="indent">  </span><span class="keyword" style="font-weight: bold;">public</span> <span class="keyword" style="font-weight: bold;">static</span> <span class="keyword" style="font-weight: bold;">final</span> String SELLER = <span class="string" style="color: rgb(221, 17, 68);">"支付寶收款帳戶"</span>;
<span class="indent">  </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 商戶私鑰,pkcs8格式</span>
<span class="indent">  </span><span class="keyword" style="font-weight: bold;">public</span> <span class="keyword" style="font-weight: bold;">static</span> <span class="keyword" style="font-weight: bold;">final</span> String RSA_PRIVATE = <span class="string" style="color: rgb(221, 17, 68);">"商戶私鑰"</span>;
<span class="indent">  </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 支付寶公鑰</span>
<span class="indent">  </span><span class="keyword" style="font-weight: bold;">public</span> <span class="keyword" style="font-weight: bold;">static</span> <span class="keyword" style="font-weight: bold;">final</span> String RSA_PUBLIC = <span class="string" style="color: rgb(221, 17, 68);">"支付寶公鑰"</span>;

<span class="indent">  </span><span class="keyword" style="font-weight: bold;">private</span> <span class="keyword" style="font-weight: bold;">static</span> <span class="keyword" style="font-weight: bold;">final</span> <span class="keyword" style="font-weight: bold;">int</span> SDK_PAY_FLAG = <span class="number" style="color: rgb(0, 153, 153);">1</span>;

<span class="indent">  </span><span class="keyword" style="font-weight: bold;">private</span> <span class="keyword" style="font-weight: bold;">static</span> <span class="keyword" style="font-weight: bold;">final</span> <span class="keyword" style="font-weight: bold;">int</span> SDK_CHECK_FLAG = <span class="number" style="color: rgb(0, 153, 153);">2</span>;

<span class="indent">  </span><span class="keyword" style="font-weight: bold;">private</span> Handler mHandler = <span class="keyword" style="font-weight: bold;">new</span> Handler() {
<span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">public</span> <span class="keyword" style="font-weight: bold;">void</span> handleMessage(Message msg) {
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">switch</span> (msg.what) {
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">case</span> SDK_PAY_FLAG: {
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>PayResult payResult = <span class="keyword" style="font-weight: bold;">new</span> PayResult((String) msg.obj);

<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 支付寶返回這次支付結果及加簽,建議對支付寶簽名信息拿簽約時支付寶提供的公鑰作驗籤</span>
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>String resultInfo = payResult.getResult();

<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>String resultStatus = payResult.getResultStatus();

<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 判斷resultStatus 爲「9000」則表明支付成功,具體狀態碼錶明含義可參考接口文檔</span>
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">if</span> (TextUtils.equals(resultStatus, <span class="string" style="color: rgb(221, 17, 68);">"9000"</span>)) {
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>Toast.makeText(PayDemoActivity.<span class="keyword" style="font-weight: bold;">this</span>, <span class="string" style="color: rgb(221, 17, 68);">"支付成功"</span>,
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>Toast.LENGTH_SHORT).show();
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>} <span class="keyword" style="font-weight: bold;">else</span> {
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 判斷resultStatus 爲非「9000」則表明可能支付失敗</span>
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 「8000」表明支付結果由於支付渠道緣由或者系統緣由還在等待支付結果確認,最終交易是否成功以服務端異步通知爲準(小几率狀態)</span>
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">if</span> (TextUtils.equals(resultStatus, <span class="string" style="color: rgb(221, 17, 68);">"8000"</span>)) {
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>Toast.makeText(PayDemoActivity.<span class="keyword" style="font-weight: bold;">this</span>, <span class="string" style="color: rgb(221, 17, 68);">"支付結果確認中"</span>,
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>Toast.LENGTH_SHORT).show();

<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>} <span class="keyword" style="font-weight: bold;">else</span> {
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 其餘值就能夠判斷爲支付失敗,包括用戶主動取消支付,或者系統返回的錯誤</span>
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>Toast.makeText(PayDemoActivity.<span class="keyword" style="font-weight: bold;">this</span>, <span class="string" style="color: rgb(221, 17, 68);">"支付失敗"</span>,
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>Toast.LENGTH_SHORT).show();

<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>}
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>}
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">break</span>;
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>}
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">case</span> SDK_CHECK_FLAG: {
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>Toast.makeText(PayDemoActivity.<span class="keyword" style="font-weight: bold;">this</span>, <span class="string" style="color: rgb(221, 17, 68);">"檢查結果爲:"</span> + msg.obj,
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>Toast.LENGTH_SHORT).show();
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">break</span>;
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>}
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">default</span>:
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="indent">  </span><span class="keyword" style="font-weight: bold;">break</span>;
<span class="indent">  </span><span class="indent">  </span><span class="indent">  </span>}
<span class="indent">  </span><span class="indent">  </span>};
<span class="indent">  </span>};

<span class="javadoc" style="color: rgb(153, 153, 136); font-style: italic;">/** <span class="indent"> </span> * call alipay sdk pay. 調用SDK支付 <span class="indent"> </span> * <span class="indent"> </span> */</span> <span class="indent"> </span><span class="keyword" style="font-weight: bold;">public</span> <span class="keyword" style="font-weight: bold;">void</span> pay() { <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 訂單</span> <span class="indent"> </span><span class="indent"> </span>String orderInfo = getOrderInfo(<span class="string" style="color: rgb(221, 17, 68);">"測試的商品"</span>, <span class="string" style="color: rgb(221, 17, 68);">"該測試商品的詳細描述"</span>, <span class="string" style="color: rgb(221, 17, 68);">"0.01"</span>); <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 對訂單作RSA 簽名</span> <span class="indent"> </span><span class="indent"> </span>String sign = sign(orderInfo); <span class="indent"> </span><span class="indent"> </span><span class="keyword" style="font-weight: bold;">try</span> { <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 僅需對sign 作URL編碼</span> <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>sign = URLEncoder.encode(sign, <span class="string" style="color: rgb(221, 17, 68);">"UTF-8"</span>); <span class="indent"> </span><span class="indent"> </span>} <span class="keyword" style="font-weight: bold;">catch</span> (UnsupportedEncodingException e) { <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>e.printStackTrace(); <span class="indent"> </span><span class="indent"> </span>} <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 完整的符合支付寶參數規範的訂單信息</span> <span class="indent"> </span><span class="indent"> </span><span class="keyword" style="font-weight: bold;">final</span> String payInfo = orderInfo + <span class="string" style="color: rgb(221, 17, 68);">"&sign=\""</span> + sign + <span class="string" style="color: rgb(221, 17, 68);">"\"&"</span> <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>+ getSignType(); <span class="indent"> </span><span class="indent"> </span>Runnable payRunnable = <span class="keyword" style="font-weight: bold;">new</span> Runnable() { <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="annotation">@Override</span> <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="keyword" style="font-weight: bold;">public</span> <span class="keyword" style="font-weight: bold;">void</span> run() { <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 構造PayTask 對象</span> <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>PayTask alipay = <span class="keyword" style="font-weight: bold;">new</span> PayTask(PayDemoActivity.<span class="keyword" style="font-weight: bold;">this</span>); <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 調用支付接口,獲取支付結果</span> <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>String result = alipay.pay(payInfo); <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>Message msg = <span class="keyword" style="font-weight: bold;">new</span> Message(); <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>msg.what = SDK_PAY_FLAG; <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>msg.obj = result; <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>mHandler.sendMessage(msg); <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>} <span class="indent"> </span><span class="indent"> </span>}; <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 必須異步調用</span> <span class="indent"> </span><span class="indent"> </span>Thread payThread = <span class="keyword" style="font-weight: bold;">new</span> Thread(payRunnable); <span class="indent"> </span><span class="indent"> </span>payThread.start(); <span class="indent"> </span>} <span class="indent"> </span><span class="javadoc" style="color: rgb(153, 153, 136); font-style: italic;">/** <span class="indent"> </span> * check whether the device has authentication alipay account. <span class="indent"> </span> * 查詢終端設備是否存在支付寶認證帳戶 <span class="indent"> </span> * <span class="indent"> </span> */</span> <span class="indent"> </span><span class="keyword" style="font-weight: bold;">public</span> <span class="keyword" style="font-weight: bold;">void</span> check(View v) { <span class="indent"> </span><span class="indent"> </span>Runnable checkRunnable = <span class="keyword" style="font-weight: bold;">new</span> Runnable() { <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="annotation">@Override</span> <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="keyword" style="font-weight: bold;">public</span> <span class="keyword" style="font-weight: bold;">void</span> run() { <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 構造PayTask 對象</span> <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>PayTask payTask = <span class="keyword" style="font-weight: bold;">new</span> PayTask(PayDemoActivity.<span class="keyword" style="font-weight: bold;">this</span>); <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 調用查詢接口,獲取查詢結果</span> <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="keyword" style="font-weight: bold;">boolean</span> isExist = payTask.checkAccountIfExist(); <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>Message msg = <span class="keyword" style="font-weight: bold;">new</span> Message(); <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>msg.what = SDK_CHECK_FLAG; <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>msg.obj = isExist; <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>mHandler.sendMessage(msg); <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>} <span class="indent"> </span><span class="indent"> </span>}; <span class="indent"> </span><span class="indent"> </span>Thread checkThread = <span class="keyword" style="font-weight: bold;">new</span> Thread(checkRunnable); <span class="indent"> </span><span class="indent"> </span>checkThread.start(); <span class="indent"> </span>} <span class="indent"> </span><span class="javadoc" style="color: rgb(153, 153, 136); font-style: italic;">/** <span class="indent"> </span> * get the sdk version. 獲取SDK版本號 <span class="indent"> </span> * <span class="indent"> </span> */</span> <span class="indent"> </span><span class="keyword" style="font-weight: bold;">public</span> <span class="keyword" style="font-weight: bold;">void</span> getSDKVersion() { <span class="indent"> </span><span class="indent"> </span>PayTask payTask = <span class="keyword" style="font-weight: bold;">new</span> PayTask(<span class="keyword" style="font-weight: bold;">this</span>); <span class="indent"> </span><span class="indent"> </span>String version = payTask.getVersion(); <span class="indent"> </span><span class="indent"> </span>Toast.makeText(<span class="keyword" style="font-weight: bold;">this</span>, version, Toast.LENGTH_SHORT).show(); <span class="indent"> </span>} <span class="indent"> </span><span class="javadoc" style="color: rgb(153, 153, 136); font-style: italic;">/** <span class="indent"> </span> * create the order info. 建立訂單信息 <span class="indent"> </span> * <span class="indent"> </span> */</span> <span class="indent"> </span><span class="keyword" style="font-weight: bold;">public</span> String getOrderInfo(String subject, String body, String price) { <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 簽約合做者身份ID</span> <span class="indent"> </span><span class="indent"> </span>String orderInfo = <span class="string" style="color: rgb(221, 17, 68);">"partner="</span> + <span class="string" style="color: rgb(221, 17, 68);">"\""</span> + PARTNER + <span class="string" style="color: rgb(221, 17, 68);">"\""</span>; <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 簽約賣家支付寶帳號</span> <span class="indent"> </span><span class="indent"> </span>orderInfo += <span class="string" style="color: rgb(221, 17, 68);">"&seller_id="</span> + <span class="string" style="color: rgb(221, 17, 68);">"\""</span> + SELLER + <span class="string" style="color: rgb(221, 17, 68);">"\""</span>; <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 商戶網站惟一訂單號</span> <span class="indent"> </span><span class="indent"> </span>orderInfo += <span class="string" style="color: rgb(221, 17, 68);">"&out_trade_no="</span> + <span class="string" style="color: rgb(221, 17, 68);">"\""</span> + getOutTradeNo() + <span class="string" style="color: rgb(221, 17, 68);">"\""</span>; <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 商品名稱</span> <span class="indent"> </span><span class="indent"> </span>orderInfo += <span class="string" style="color: rgb(221, 17, 68);">"&subject="</span> + <span class="string" style="color: rgb(221, 17, 68);">"\""</span> + subject + <span class="string" style="color: rgb(221, 17, 68);">"\""</span>; <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 商品詳情</span> <span class="indent"> </span><span class="indent"> </span>orderInfo += <span class="string" style="color: rgb(221, 17, 68);">"&body="</span> + <span class="string" style="color: rgb(221, 17, 68);">"\""</span> + body + <span class="string" style="color: rgb(221, 17, 68);">"\""</span>; <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 商品金額</span> <span class="indent"> </span><span class="indent"> </span>orderInfo += <span class="string" style="color: rgb(221, 17, 68);">"&total_fee="</span> + <span class="string" style="color: rgb(221, 17, 68);">"\""</span> + price + <span class="string" style="color: rgb(221, 17, 68);">"\""</span>; <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 服務器異步通知頁面路徑</span> <span class="indent"> </span><span class="indent"> </span>orderInfo += <span class="string" style="color: rgb(221, 17, 68);">"¬ify_url="</span> + <span class="string" style="color: rgb(221, 17, 68);">"\""</span> + <span class="string" style="color: rgb(221, 17, 68);">"http://notify.msp.hk/notify.htm"</span> <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>+ <span class="string" style="color: rgb(221, 17, 68);">"\""</span>; <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 服務接口名稱, 固定值</span> <span class="indent"> </span><span class="indent"> </span>orderInfo += <span class="string" style="color: rgb(221, 17, 68);">"&service=\"mobile.securitypay.pay\""</span>; <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 支付類型, 固定值</span> <span class="indent"> </span><span class="indent"> </span>orderInfo += <span class="string" style="color: rgb(221, 17, 68);">"&payment_type=\"1\""</span>; <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 參數編碼, 固定值</span> <span class="indent"> </span><span class="indent"> </span>orderInfo += <span class="string" style="color: rgb(221, 17, 68);">"&_input_charset=\"utf-8\""</span>; <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 設置未付款交易的超時時間</span> <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 默認30分鐘,一旦超時,該筆交易就會自動被關閉。</span> <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 取值範圍:1m~15d。</span> <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// m-分鐘,h-小時,d-天,1c-當天(不管交易什麼時候建立,都在0點關閉)。</span> <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 該參數數值不接受小數點,如1.5h,可轉換爲90m。</span> <span class="indent"> </span><span class="indent"> </span>orderInfo += <span class="string" style="color: rgb(221, 17, 68);">"&it_b_pay=\"30m\""</span>; <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// extern_token爲通過快登受權獲取到的alipay_open_id,帶上此參數用戶將使用受權的帳戶進行支付</span> <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// orderInfo += "&extern_token=" + "\"" + extern_token + "\"";</span> <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 支付寶處理完請求後,當前頁面跳轉到商戶指定頁面的路徑,可空</span> <span class="indent"> </span><span class="indent"> </span>orderInfo += <span class="string" style="color: rgb(221, 17, 68);">"&return_url=\"m.alipay.com\""</span>; <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// 調用銀行卡支付,需配置此參數,參與簽名, 固定值 (須要簽約《無線銀行卡快捷支付》才能使用)</span> <span class="indent"> </span><span class="indent"> </span><span class="comment" style="color: rgb(153, 153, 136); font-style: italic;">// orderInfo += "&paymethod=\"expressGateway\"";</span> <span class="indent"> </span><span class="indent"> </span><span class="keyword" style="font-weight: bold;">return</span> orderInfo; <span class="indent"> </span>} <span class="indent"> </span><span class="javadoc" style="color: rgb(153, 153, 136); font-style: italic;">/** <span class="indent"> </span> * get the out_trade_no for an order. 生成商戶訂單號,該值在商戶端應保持惟一(可自定義格式規範) <span class="indent"> </span> * <span class="indent"> </span> */</span> <span class="indent"> </span><span class="keyword" style="font-weight: bold;">public</span> String getOutTradeNo() { <span class="indent"> </span><span class="indent"> </span>SimpleDateFormat format = <span class="keyword" style="font-weight: bold;">new</span> SimpleDateFormat(<span class="string" style="color: rgb(221, 17, 68);">"MMddHHmmss"</span>, <span class="indent"> </span><span class="indent"> </span><span class="indent"> </span><span class="indent"> </span>Locale.getDefault()); <span class="indent"> </span><span class="indent"> </span>Date date = <span class="keyword" style="font-weight: bold;">new</span> Date(); <span class="indent"> </span><span class="indent"> </span>String key = format.format(date); <span class="indent"> </span><span class="indent"> </span>Random r = <span class="keyword" style="font-weight: bold;">new</span> Random(); <span class="indent"> </span><span class="indent"> </span>key = key + r.nextInt(); <span class="indent"> </span><span class="indent"> </span>key = key.substring(<span class="number" style="color: rgb(0, 153, 153);">0</span>, <span class="number" style="color: rgb(0, 153, 153);">15</span>); <span class="indent"> </span><span class="indent"> </span><span class="keyword" style="font-weight: bold;">return</span> key; <span class="indent"> </span>} <span class="indent"> </span><span class="javadoc" style="color: rgb(153, 153, 136); font-style: italic;">/** <span class="indent"> </span> * sign the order info. 對訂單信息進行簽名 <span class="indent"> </span> * <span class="indent"> </span> * <span class="javadoctag">@param</span> content <span class="indent"> </span> * 待簽名訂單信息 <span class="indent"> </span> */</span> <span class="indent"> </span><span class="keyword" style="font-weight: bold;">public</span> String sign(String content) { <span class="indent"> </span><span class="indent"> </span><span class="keyword" style="font-weight: bold;">return</span> SignUtils.sign(content, RSA_PRIVATE); <span class="indent"> </span>} <span class="indent"> </span><span class="javadoc" style="color: rgb(153, 153, 136); font-style: italic;">/** <span class="indent"> </span> * get the sign type we use. 獲取簽名方式 <span class="indent"> </span> * <span class="indent"> </span> */</span> <span class="indent"> </span><span class="keyword" style="font-weight: bold;">public</span> String getSignType() { <span class="indent"> </span><span class="indent"> </span><span class="keyword" style="font-weight: bold;">return</span> <span class="string" style="color: rgb(221, 17, 68);">"sign_type=\"RSA\""</span>; <span class="indent"> </span>} }這一段代碼要和上一段代碼放在一個Java 文件中,須要注意的一個方法是。 pay() 方法和getOrderInfo(); 須要注意的是,在咱們選擇支付寶支付的按鈕中調用的 是 pay() 方法。而放在pay()方法中則須要調用getOrderInfo(),仔細發現,getOrderInfo()方法裏面的三個參數。其中price 參數就是咱們要消費的金額,當咱們調用pay()方法的時候,就須要傳入一個price 的參數,就是咱們須要支付的金額。具體的金額怎麼傳入,計算,要根據項目須要來本身獲取了,這樣項目集成支付寶就圓滿結束了。

 

配置的具體操做:

在PayDemoActivity中配置幾個變量:

copy
 
 
 

//PID public  String PARTNER = ;   在這裏填上咱們上面找到的PID;

copy
 
 
 

// 商戶收款帳號 public  String SELLER = ;   而後在SELLER上寫上咱們支付寶的登陸賬戶,即那個你申請移動支付的支付寶帳號

copy
 
 
 

// 支付寶公鑰 public  String RSA_PUBLIC =;   而後在RSA_PUBLIC這裏填上支付寶公鑰

copy
 
 
 

// 商戶私鑰,pkcs8格式 public  String RSA_PRIVATE = ;   最後是填上RSA_PRIVATE對應的商戶私鑰,注意是PKCS8格式的。
私鑰這部分,注意是----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----之間的部分,即那段純代碼,不要把----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----給複製進去了。中間的這部分就是公鑰。

 

如今運行demo就直接能夠支付了。

 

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

四、代碼講解

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

 

copy
 
 
 

public pay(View v) {  

  •     …………  
  •   
  •     String orderInfo = getOrderInfo();  
  •   
  •  {  
  •   
  •         sign = URLEncoder.encode(sign, );  
  •  (UnsupportedEncodingException e) {  
  •         e.printStackTrace();  
  •   
  •      String payInfo = orderInfo +   Runnable() {  
  •   
  •   
  •           run() {  
  •   
  •             PayTask alipay =  PayTask(PayDemoActivity.);  
  •   
  •             String result = alipay.pay(payInfo);  
  •  Message();  
  •   
  •     Thread payThread =  Thread(payRunnable);  
  • }  


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

 

第一步:構造定單信息:

 

copy
 
 
 

String orderInfo = getOrderInfo();   主要是這句,即在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

copy
 
 
 

public   

  •     String orderInfo =  +  + PARTNER + ;  
  •   
  •  + SELLER + ;  
  •   
  •   
  •     orderInfo +=  + getOutTradeNo() + ;  
  •   
  •  + subject + ;  
  •   
  •   
  •     orderInfo +=  + body + ;  
  •   
  •  + price + ;  
  •   
  •   
  •     orderInfo +=  +   
  • ;  
  •   
  •  orderInfo;  
  • }  

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

copy
 
 
 

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

  • ;  

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

 

 

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

爲何要簽名呢?固然是防止傳輸出錯了,這但是跟錢相關的,若是orderInfo傳輸過程當中出錯了,那怎麼樣來校驗它是否是出錯了呢,只有經過簽名算法來了。因此這裏就須要對訂單字符串作簽名。
具體簽名算法就不講了,直接應用到項目中就行,不須要理解,若是想看看怎麼實現的,裏面有對應的源碼,能夠去研究一下。

 

 

copy
 
 
 

// 對訂單作RSA 簽名 try   

  • );  
  •  (UnsupportedEncodingException e) {  
  • }  

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

在訂單字符串和簽名作完之後,就能夠用他們來構造完整的請求字符串了:

copy
 
 
 

// 完整的符合支付寶參數規範的訂單信息 final         + getSignType();  

第四步:請求與結果返回

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

 

 

copy
 
 
 

Runnable payRunnable =  Runnable() {  

  •   
  •   
  •       run() {  
  •   
  •         PayTask alipay =  PayTask(PayDemoActivity.);  
  •   
  •         String result = alipay.pay(payInfo);  
  •  Message();  
  • // 必須異步調用  Thread(payRunnable);  
  • payThread.start();  

最關鍵的部分在這裏:

copy
 
 
 

PayTask alipay =  PayTask(PayDemoActivity.);  

  •   
  •  Message();  
  • msg.what = SDK_PAY_FLAG;  
  • mHandler.sendMessage(msg);  

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

相關文章
相關標籤/搜索