android移動支付——銀聯支付
前言
這裡開篇講解一系列的Android相關的移動支付。移動支付也稱為手機支付,使用者使用移動的裝置,完成對所購買商品或者服務的支付功能。包括遠端支付(網上支付、簡訊支付),近場支付(刷卡、滴卡、pos機)。
國內的移動支付方式:
支付寶,微信,銀聯,百度錢包,QQ錢包,財付通,京東支付
易寶支付,快錢支付,還有一些第三方的支付什麼連連支付之類的
境外的移動支付方式(這裡直說一個) :paypal
流程
我們這裡主要是來學習一下支付寶,微信支付,銀聯支付和paypal支付
現實生活中的支付就是:去商店瀏覽商品->把商品加入購物車->把購物車中的商品拿到收銀臺付款
上面的支付流程細化下來就是:
1.瀏覽商品
2.把要買的商品加入購物車
3.把商品拿到收銀臺,收銀人員處理商品資訊
4.告訴收銀員支付方式
5.選擇支付方式進行支付
6.處理支付結果(成功、失敗、取消)
程式中的支付流程中:
1.瀏覽商品
2.把要買的商品加入購物車
3.把購物車中的商品資訊和使用者資訊和支付方式等資訊傳送到自己伺服器,伺服器處理商品資訊生成訂單,並返回”支付串”給客戶端
4.客戶端拿著“支付串”,呼叫第三方服務(支付寶、微信、銀聯、paypal等)完成支付
5.處理支付結果(成功、失敗、取消)
l 同步返回:支付後通知我們的客戶端
l 非同步通知:支付後通知我們的服務端
以上就是一般的移動支付的基本流程了,下面看這幾個支付平臺的詳細介紹
銀聯支付
1.概述
銀聯支付有很多種型別,我們這裡主要說的是手機控制元件支付
銀聯手機支付控制元件主要應用於各類手機電子商務平臺的支付應用。銀聯控制元件合作商戶的手機客戶端(或網站)內整合(或呼叫)銀聯支付控制元件後,持卡人在合作商戶上即可使用銀聯手機支付安全控制元件進行安全的、便捷的即時支付,同時,保障使用者銀行卡資訊的安全。
2.支付流程
流程圖說明:
(1)使用者在客戶端中點選購買商品,客戶端發起訂單生成請求到商戶後臺;
(2)商戶後臺收到訂單生成請求後,按照《手機控制元件支付產品介面規範》組織並推送訂單資訊至銀聯後臺;
(3)銀聯後臺接收訂單資訊並檢查通過後,生成對應交易流水號(即TN),並回復交易流水號至商戶後臺(應答要素:交易流水號等);
(4)商戶後臺接收到交易流水號,將交易流水號返回給客戶端;
(5)客戶端通過交易流水號(TN)呼叫支付控制元件;
(6)使用者在支付控制元件中輸入相關支付資訊後,由支付控制元件向銀聯後臺發起支付請求;
(7)支付成功後,銀聯後臺將支付結果通知給商戶後臺;
(8)銀聯將支付結果通知支付控制元件;
(9)支付控制元件顯示支付結果並將支付結果返回給客戶端;
注: 本文件主要關注上述流程中(5)、(9)部分的實現
目前各個平臺支援的裝置情況如下:
Android平臺SDK主要適用於Android 2.3及以上版本的終端裝置;
3.測試賬號
提供測試使用卡號、手機號資訊(此類資訊僅供測試,不會發生正式交易)
招商銀行借記卡:6226090000000048 |
華夏銀行貸記卡:6226388000000095 |
4.接入SDK和一些文件的說明
手機控制元件支付SDK下載demo還有相關的接入文件之類的jar包
因為下載下來的銀聯手機控制元件支付開發包裡面的demo工程都還沒配好的,還有是用eclipse的,一些說明也在下載回來的控制元件使用指南的文件中有了,這裡也會列出來,現在我改用Androidstudio來完成這個demo,如下:
4.1 SDK包說明
商戶開發者在獲取到銀聯提供的開發包後請檢查SDK檔案所在目錄upmp_android/sdkProSDK,以下部分提及的檔案均在該目錄中:
apk目錄下包括了支付控制元件的apk:UPPayPluginExPro.apk
jar目錄下包括了商戶整合所需要的jar包、so檔案(支援arm,armv7,x86,x86_64和arm64-v8a平臺)和資原始檔。
UPPayAssistEx.jar定義了呼叫支付控制元件所需要的介面。
4.2介面說明
1、 支付介面
upmp_android/UPPayAssistEx.jar中定義了啟動支付控制元件的介面,介面定義如下:
public static int startPay(Activity activity, String spId, String sysProvider, String orderInfo, String mode) 引數說明: activity —— 用於啟動支付控制元件的活動物件 spId —— 保留使用,這裡輸入null sysProvider —— 保留使用,這裡輸入null orderInfo —— 訂單資訊為交易流水號,即TN,為商戶後臺從銀聯後臺獲取。 mode —— 銀聯後臺環境標識,“00”將在銀聯正式環境發起交易,“01”將在銀聯測試環境發起交易 返回值: UPPayAssistEx.PLUGIN_VALID —— 該終端已經安裝控制元件,並啟動控制元件 UPPayAssistEx.PLUGIN_NOT_FOUND — 手機終端尚未安裝支付控制元件,需要先安裝支付控制元件 |
2、檢查是否安裝銀聯Apk的介面
upmp_android/UPPayAssistEx.jar中定義了檢測銀聯apk是否安裝的介面,介面定義如下:
public static boolean checkInstalled (Context context) 引數說明: activity —— 用於啟動支付控制元件的context環境 返回值: true —— 該終端已經安裝控制元件apk false — 該終端未安裝控制元件apk |
4.3 新增SDK包
(1)可以自己新建一個工程來寫demo,也可以利用Androidstudio匯入eclipse的demo
生成Androidstudio的工程
(2)在appàsrcàmain新建一個assets資料夾,拷貝upmp_android/sdkPro/jar/data.bin到工程的assets/目錄下;
(3)在main目錄下新建一個jniLibs,然後再拷貝upmp_android/sdkPro/jar/xxx/libentryexpro.so和upmp_android/sdkPro/jar/xxx/libuptsmaddon.so到工程的libs/xxx/目錄下,其中xxx為 armeabi-v7a、armeabi、arm64-v8a、x86、x86_64之一。
arm64-v8a(x86_64)是針對arm64(x86 64)架構優化的庫檔案,引入工程後在arm64(x86 64)機型上效能會提升,但是最終生成的程式包將變大。注意: 如果工程中使用了其他的.so庫,那麼需要所有.so庫都有arm64-v8a(x86_64)的版本。
(4)app目錄下新建libs,拷貝upmp_android/sdkPro/UPPayAssistEx.jar到工程的libs/目錄下;
拷貝upmp_android/sdkPro/jar/UPPayPluginExPro.jar到工程的libs/目錄下,然後進行依賴jar包;
效果如下圖:
(5)在工程的AndroidManifest.xml檔案中註冊支付外掛使用的Activity。新增如下
<uses-libraryandroid:name="org.simalliance.openmobileapi" android:required="false"/>
<activity
android:name="com.unionpay.uppayplugin.demo.JARActivity"
android:label="@string/jar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name="com.unionpay.uppay.PayActivity"
android:configChanges="orientation|keyboardHidden|keyboard"
android:screenOrientation="portrait">
</activity>
<activity
android:name="com.unionpay.UPPayWapActivity"
android:configChanges="orientation|keyboardHidden|fontScale"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize" >
</activity>
同時新增許可權:
<uses-permissionandroid:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="org.simalliance.openmobileapi.SMARTCARD"/>
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc.hce"/>
注意:版本編譯時的target應選用OpenMobile API,建議level19以上
(6)呼叫支付控制元件
1、支付介面呼叫
a) 在呼叫支付控制元件的程式碼檔案中引入UPPayAssistEx類如:
import com.unionpay.UPPayAssistEx; |
b) 接著可以通過以下方式呼叫支付控制元件:
// “00” – 銀聯正式環境 // “01” – 銀聯測試環境,該環境中不發生真實交易 String serverMode = "01"; UPPayAssistEx.startPay (activity, null,null, tn, serverMode); |
支付完成後,獲取支付控制元件支付結果,並新增相應處理邏輯,只需實現呼叫Activity中的onActivityResult()方法即可,支付成功時會返回商戶客戶端支付結果的簽名信息。
對於新增的簽名信息需注意以下幾點:
1. 前臺返回的支付結果中包含銀聯簽名,要在商戶後臺對簽名進行校驗後才能展示結果。
2. 前臺簽名使用的金鑰和演算法與後臺結果中的簽名一致。
3. 如果商戶APP在客戶端內進行簽名驗證,要自行實現簽名金鑰更新的機制,否則更換金鑰後會導致驗籤失敗。(不推薦)
4. 商戶訂單是否成功支付應該以商戶後臺收到全渠道返回的支付結果為準,此處支付控制元件返回的結果僅作為參考。
示例程式碼如下:
protected void onActivityResult( int requestCode, int resultCode, Intent data) { if( data ==null ){ return; } String str = data.getExtras().getString("pay_result"); if( str.equalsIgnoreCase(R_SUCCESS) ){ // 支付成功後,extra中如果存在result_data,取出校驗 // result_data結構見c)result_data引數說明 if(data.hasExtra("result_data")) { String sign = data.getExtras().getString("result_data"); // 驗簽證書同後臺驗簽證書 // 此處的verify,商戶需送去商戶後臺做驗籤 if(verify(sign)) { //驗證通過後,顯示支付結果 showResultDialog(" 支付成功! "); } else { // 驗證不通過後的處理 // 建議通過商戶後臺查詢支付結果 } } else { // 未收到簽名信息 // 建議通過商戶後臺查詢支付結果 } }else if( str.equalsIgnoreCase(R_FAIL) ){ showResultDialog(" 支付失敗! "); }else if( str.equalsIgnoreCase(R_CANCEL) ){ showResultDialog(" 你已取消了本次訂單的支付! "); } } |
c) result_data引數說明:
引數說明: sign —— 簽名後做Base64的資料 data —— 用於簽名的原始資料 data中原始資料結構: pay_result —— 支付結果success,fail,cancel tn —— 訂單號 |
result_data示例如下:
"{"sign":"ZnZY4nqFGu/ugcXNIhniJh6UDVriWANlHtIDRzV9w120E6tUgpL9Z7jIFzWrSV73hmrkk8BZMXMc/9b8u3Ex1ugnZn0OZtWfMZk2I979dxp2MmOB+1N+Zxf8iHr7KNhf9xb+VZdEydn3Wc/xX/B4jncg0AwDJO/0pezhSZqdhSivTEoxq7KQTq2KaHJmNotPzBatWI5Ta7Ka2l/fKUv8zr6DGu3/5UaPqHhnUq1IwgxEWOYxGWQgtyTMo/tDIRx0OlXOm4iOEcnA9DWGT5hXTT3nONkRFuOSyqS5Rzc26gQE6boD+wkdUZTy55ns8cDCdaPajMrnuEByZCs70yvSgA==","data":"pay_result=success&tn=201512151321481233778"}"
2、檢測是否已安裝銀聯Apk介面呼叫
if(UPPayAssistEx.checkInstalled(context)) { //當判斷使用者手機上已安裝銀聯Apk,商戶客戶端可以做相應個性化處理 } |
對於原有sdk接入商戶,可在原有修改的基礎上更新對應檔案後,還需增加如下修改:
1. 增加upmp_android/sdkPro/jar/xxx/libuptsmaddon.so
2. 在工程的AndroidManifest.xml檔案增加UPPayWapActivity。新增如下:
<application> <!--工程其它配置此處省略…--> <activity android:name="com.unionpay.UPPayWapActivity" android:configChanges="orientation|keyboardHidden" android:screenOrientation="portrait" android:windowSoftInputMode="adjustResize"/> </application> |
3. 呼叫介面改為4.2節中支付介面startPay,但原有的startPayByJAR介面仍保留,如下所示:
public static int startPayByJAR (Activity activity, Class<?> payCls, String spId, String sysProvider, String orderInfo, String mode) 引數說明: activity —— 用於啟動支付控制元件的活動物件 payCls ——支付外掛代表的類,填入“PayActivty.class”即可 spId —— 保留使用,這裡輸入null sysProvider —— 保留使用,這裡輸入null orderInfo —— 訂單資訊為交易流水號,即TN,為商戶後臺從銀聯後臺獲取。 mode —— 銀聯後臺環境標識,“00”將在銀聯正式環境發起交易,“01”將在銀聯測試環境發起交易 |
5.常見問題總結
1. java.lang.ClassNotFoundException:org.simalliance.openmobileapi.SEService
此條異常僅會列印異常棧,而不會引起控制元件崩潰,無視即可。
2.java.io.FileNotFoundException: UPPayPluginExPro.apk
請將開發包中的UPPayPluginExPro.apk更改檔名為 UPPayPluginEx.apk後再放到assets資料夾下,可參考控制元件指南。
3.demo程式碼UPPayAssistEx.installPlugin呼叫後無反應/“完成購買需要安裝銀聯支付控制元件,是否安裝?”的確定按鈕點選後無反應
同上一問。
4.java.lang.NoClassDefFoundError:com.unionpay.UPPayAssistEx
1. 工程裡看看jar包是不是放對。
2. Jar包是不是加到build path裡。
3. eclipse等工具裡,工程上右鍵java build path-order andexport裡需要勾上jar包。
5.Unable to start activity ComponentInfo(…): java.lang.NullPointerException《=UPPayEngine.a報的空指標
如:
比較大的可能:傳進控制元件的tn引數不能為空或空值。
Jar方式接入也有可能:data.bin檔案沒有放對位置,請參照控制元件指南放。
6. Permission異常
如:
java.lang.RuntimeException: Unable to start activityComponentInfo{com.unionpay.uppayplugin.demo/com.unionpay.uppay.PayActivity}:java.lang.SecurityException: Requires READ_PHONE_STATE: Neither user 10065 norcurrent process has android.permission.READ_PHONE_STATE.
請檢查一下許可權是否在AndroidManifest檔案中定義:
<uses-permissionandroid:name=""android.permission.INTERNET"" />
<uses-permission android:name=""android.permission.ACCESS_NETWORK_STATE""/>
<uses-permissionandroid:name=""android.permission.CHANGE_NETWORK_STATE""/>
<uses-permissionandroid:name=""android.permission.WRITE_EXTERNAL_STORAGE""/>
<uses-permissionandroid:name=""android.permission.READ_PHONE_STATE"" />
<uses-permissionandroid:name=""android.permission.ACCESS_WIFI_STATE"" />
7.java.lang.UnsatisfiedLinkErrror: Couldn’t load entryexpro: findLibrary return null或java.lang.UnsatisfiedLinkErrror: Library entryex not found
libentryexpro.so檔案應放置到libs/CPU名比如armeabi目錄下。2.1.2及以下控制元件的.so檔案直接放libs目錄下的,升級2.1.3及以上控制元件時,請務必注意目錄層級多了CPU名的資料夾。
8.java.lang.NoClassDefFoundError: com.unionpay.uppay.PayActivity
請將相關的jar包拷貝至libs目錄下,然後再add to build path。
9.can’t find reference class org.openmobileapi.SEService
如:
出現該錯誤是由於target未設定為openmobile API導致的,具體設定請參加4.3(5)節。
以上一部分是直接copy銀聯支付的文件的,因為很詳細了,再加上一些Androidstudio的東西,跑出來的demo如圖:
6.實際專案開發
完成所有的配置執行出來的Demo可以完全支付了說明Demo就已經完全配置好了銀聯的開發環境了,我們只需要參照這個Demo去配置我們自己的專案即可。
注:銀聯開發環境的編譯不能在太老的環境下編譯,否則會報類找不到異常