1. 程式人生 > >手把手教你完成App端-支付寶支付Android

手把手教你完成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端需要做的,就是這麼簡單,因為大部分工作,都在伺服器端來完成。對伺服器端感興趣的,可以檢視我下一篇部落格。

請支援我,掃描左側二維碼打賞,謝謝。