十幾行程式碼搞定Android呼叫支付寶支付

weixin_34236497發表於2017-11-07

最近專案用到了支付寶支付,但是百度搜到的都是些如何把支付寶官方的demo進行修改,伺服器端的程式碼依舊存留在我們的專案中,非常影響我們的閱讀文件能力,在這裡,我把伺服器程式碼全部刪除,僅僅保留我們android需要呼叫的方法。

支付寶android整合地址
我們通過這裡進行支付寶的整合,相信看這篇文章的同學已經整合完成了支付寶。

在這裡postOrderInfoOnServer()方法就是通過呼叫伺服器獲取的經過加簽等一系列安全邏輯獲取我們需要拿到的資料

private String postOrderInfoOnServer() {
        OkHttpClient client = new OkHttpClient();
        FormBody.Builder builder = new FormBody.Builder();
        FormBody formBody = builder.build();
        Request request = new Request.Builder()
                .url(ConstantValue.URL + "/order/buildOrderInfo")
                .post(formBody)
                .build();
        client.newCall(request).enqueue(new Callback() {

            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String result = response.body().string();
                Log.i(TAG, "onResponse: 支付寶訂單資訊" + result);
                JSONObject jsonObject = null;
                try {
                    jsonObject = new JSONObject(result);
                    dataAlipay = jsonObject.getString("data");
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
        //返回出去的資料,我將其定義為全域性的成員變數
        return dataAlipay;
    }

我將dataAlipay返回出去的資料,我將其定義為全域性的成員變數

這樣我們就算是拿到了訂單資料資訊的一串程式碼
我們需要dataAlipay發給支付寶

下面我們直接進行支付寶的呼叫。

/**
     * 支付寶支付
     */
    private void aliPay(int orderId, int orderType) {
        //從伺服器獲取支付寶訂單資訊
        postOrderInfoOnServer();
        Log.i(TAG, "aliPay: 支付寶訂單資訊" + dataAlipay);
        Runnable payRunnable = new Runnable() {
            @Override
            public void run() {
                // 構造PayTask 物件
                PayTask alipay = new PayTask(PayActivity.this);
                // 呼叫支付介面,獲取支付結果
                Map<String, String> result = alipay.payV2(dataAlipay, true);
                Message msg = new Message();
                msg.what = SDK_PAY_FLAG;
                msg.obj = result;
                mHandler.sendMessage(msg);
            }
        };
        // 必須非同步呼叫
        Thread payThread = new Thread(payRunnable);
        payThread.start();
    }

1.在alipay.payV2()方法中,我們將從伺服器獲取到的dataAlipay傳入,將返回的result結果通過Message物件儲存。
2.最後我們通過重寫handleMessage()方法進行支付成功後的邏輯

@SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @SuppressWarnings("unused")
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SDK_PAY_FLAG: {
                    @SuppressWarnings("unchecked")
                    PayResult payResult = new PayResult((Map<String, String>) msg.obj);
                    /**
                     對於支付結果,請商戶依賴服務端的非同步通知結果。同步通知結果,僅作為支付結束的通知。
                     */
                    String resultInfo = payResult.getResult();// 同步返回需要驗證的資訊
                    String resultStatus = payResult.getResultStatus();
                    Log.i(TAG, "handleMessage: " + resultStatus);
                    // 判斷resultStatus 為9000則代表支付成功
                    if (TextUtils.equals(resultStatus, "9000")) {
                        // 該筆訂單是否真實支付成功,需要依賴服務端的非同步通知。
                        Toast.makeText(PayActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
                        //銷燬介面
                        finish();
                    } else {
                        // 該筆訂單真實的支付結果,需要依賴服務端的非同步通知。
                        Toast.makeText(PayActivity.this, "支付失敗", Toast.LENGTH_SHORT).show();
                    }
                    break;
                }
                
            }
        }

    };

到這裡我們就算基本完成了支付寶支付了。

7649747-94e7bd11bd08c959.jpg
支付成功的介面.jpg

支付的非同步通知優化

我們來分析一下handleMessage()中的方法
payResult.getResultStatus()方法即能獲取到支付寶返回給我們的狀態碼,成功即9000,錯誤即6001。下面我將通過兩點解決,9000的優化擴充套件以及如何解決6001錯誤。

9000成功

7649747-1775d99930910282.png
1754FDDC07407F6A4722BD1C3FAE27BA.png

其實在我們handleMessage()方法中,只是走到了第8步,如果我們想優化第9步,我們需要在if (TextUtils.equals(resultStatus, "9000")中呼叫我們自己伺服器,將payResult.getResultStatus()獲取到的9000狀態碼傳給伺服器,伺服器進行同步通知,如果伺服器返回給我們的資料為成功,我們在Toast顯示成功

這樣,9.10,11步即完成,剩下的我們交給後臺大神們去解決就可以了

6001錯誤碼

在我自己的專案中,呼叫出來支付寶可能沒有顯示付款介面,可能會返回

系統繁忙
交易訂單失敗

等錯誤,這說明我們客戶端其實已經配置好支付寶了,不要將錯誤擴大化,去考慮別的東西。

我解決的辦法是,重新生成一下RSA2公私鑰,開發文件中,支付寶給了我們生成公私鑰的工具,我們只要按照步驟走就行,十分簡單讓後臺重新配置一下需要返回給我們的訂單資訊,這樣,錯誤基本就能解決了。

PayResult類檔案我們可以直接從支付寶demo中copy進自己的專案,這樣,支付寶支付基本大功告成

相關文章