手把手教你完成App端-支付寶支付Android
部落格停更了好幾個月,這段時間由於生活上的瑣事不斷,靜不下心來寫,前端時間公司給了2個月完成一個類似攜程的軟體。而我作為公司的主力,在經歷了一系列難題以後,我認為第三方支付的流程,應該做一下記錄。因為它真的坑太多了。
本文將會把大多數程式碼上傳至GitHub上,當然,我希望在這之前,認真的看一遍支付流程。
申請
接入
在此之前,一定要人認真的的看一遍流程圖
知道了大概流程,我們需要接入支付寶到專案裡。
開發
在商戶應用工程的AndroidManifest.xml檔案裡面新增宣告:
<activity
android:name="com.alipay.sdk.app.H5PayActivity"
android:configChanges="orientation|keyboardHidden|navigation|screenSize"
android:exported="false"
android:screenOrientation="behind"
android:windowSoftInputMode="adjustResize|stateHidden" >
</activity>
<activity
android:name="com.alipay.sdk.app.H5AuthActivity"
android:configChanges ="orientation|keyboardHidden|navigation"
android:exported="false"
android:screenOrientation="behind"
android:windowSoftInputMode="adjustResize|stateHidden" >
</activity>
和許可權宣告:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name ="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
新增混淆規則
-libraryjars libs/alipaySDK-20150602.jar
-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}
由於支付是需要耗時的操作,因此使用新執行緒是必要的。
首先從後臺獲取訂單,接下來,非同步調起支付程式(由於RxJava實在太流行了所以我用到了專案裡,不懂RxJava的也不要緊,因為這一步完全可以用Handler替代。):
Observable.create(new Observable.OnSubscribe<Map<String, String>>()
{
@Override
public void call(Subscriber<? super Map<String, String>> subscriber)
{
PayTask alipay = new PayTask(mActivity);
if (orders.getAliPayOrderString() == null) //orders.getAliPayOrderString()是後臺請求得到的預付單,這個是必要條件。後臺如何生成請參照下一篇部落格。
{
subscriber.onNext(null);
return;
}
String orderInfo = orders.getAliPayOrderString();
Map<String, String> result = alipay.payV2(orderInfo, true);
subscriber.onNext(result);
subscriber.onCompleted();
}
}).observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io
())
.subscribe(new Observer<Map<String, String>>()
{
@Override
public void onCompleted()
{
}
@Override
public void onError(Throwable e)
{
}
@Override
public void onNext(Map<String, String> stringStringMap)
{
if (stringStringMap == null)
{
Toast.error("返回資料異常!");
return;
}
PayResult payResult = new PayResult(stringStringMap);
/**
對於支付結果,請商戶依賴服務端的非同步通知結果。同步通知結果,僅作為支付結束的通知。
*/
String resultInfo = payResult.getResult();// 同步返回需要驗證的資訊
String resultStatus = payResult.getResultStatus();
// 判斷resultStatus 為9000則代表支付成功
if (TextUtils.equals(resultStatus, "9000"))
{
// 該筆訂單是否真實支付成功,需要依賴服務端的非同步通知。
startActivity(new Intent(mActivity, OrderResult.class).putExtra("status", order)); // 付款頁面
finish();
} else
{
// 該筆訂單真實的支付結果,需要依賴服務端的非同步通知。
order = null;
startActivity(new Intent(mActivity, OrderResult.class).putExtra("resultStatus", resultInfo)); // 付款結果頁面,在跳轉到此頁面後,像伺服器端發起請求檢視非同步通知的支付結果,由於只是呼叫一個介面因此這裡不做演示。
finish();
}
}
});
首先確保獲取了預付單以後,建立一個PayTask 物件,此物件封裝了支付的操作。然後將預付單傳入它的payV2()方法內,
Map<String, String> result = alipay.payV2(orderInfo, true);
這一步就是耗時操作,下面的判斷都比較簡單了。
由於程式碼都加上了註釋,看了流程圖一定會秒懂。我這裡的流程是,下單後後臺生成下單號,再手機端點選支付的時候,後臺去支付寶獲取預付單,然後手機端收到資料後開始付款,付款後,根據resultStatus判斷結果。當然,真是的支付結果依賴於後來的資料。
支付寶伺服器在支付完成後,會以POST方式呼叫notify_url傳輸資料。所以當手機端支付後,需要去服務端檢視資料真實性。
在實際開發中,建議拿到後臺支付單後,先將資料寫死在支付寶提供的Demo中嘗試是否能跑通,然後再將邏輯寫在自己的專案中。
附加:
首次使用支付的要記得,接下來支付寶客戶端顯示支付成功後,應該在下一步操作中呼叫後臺人員的介面來確認該筆交易是否真實,前面也有講過,真實支付結果依賴於伺服器的資料,手機在支付後支付寶後臺會推送支付結果到後臺,此時後臺應該記錄支付結果,以便於前端查詢。沒錯,Android端需要做的,就是這麼簡單,因為大部分工作,都在伺服器端來完成。對伺服器端感興趣的,可以檢視我下一篇部落格。