解決:微信支付坑多?其實很簡單!在WXPayEntryActivity回調方法中向後臺驗證支付結果,但獲取不到OrderID,下面幾種辦法應該可以解決。

如標題,好久沒做微信支付,之前的坑忘了,今天又遇到,記下來供朋友們參考,話不多說,先大致簡單的介紹一下集成微信支付的流程,就幾行字的事,希望朋友們有點耐心。

 

  • Step1. 在微信開放平臺上下載微信的SDK,然後扔到你的項目裏,並添加上依賴;
  • Step2. 在你準備請求微信支付的Activity裏,先註冊一下子微信支付SDK,然後調用就行了;

這是註冊奧: 

private IWXAPI api;
api = WXAPIFactory.createWXAPI(context, null);
api.registerApp("你的App id");

 這就是調用了:

PayReq req = new PayReq();
//req.appId = "wxf8b4f85f3a794e77";  // 測試用appId
req.appId			= json.getString("appid");
req.partnerId		= json.getString("partnerid");
req.prepayId		= json.getString("prepayid");
req.nonceStr		= json.getString("noncestr");
req.timeStamp		= json.getString("timestamp");
req.packageValue	= json.getString("package");
req.sign			= json.getString("sign");
// 在支付之前,如果應用沒有註冊到微信,應該先調用IWXMsg.registerApp將應用註冊到微信
api.sendReq(req);
  • Step3. ※ 完了在你項目的根目錄,就是 “com.xx.xx” 那裏面建個文件,名叫 “wxapi” ,然後在裏面建個Activity,名叫 “WXPayEntryActivity” 並集成 “IWXAPIEventHandler” 接口。這裏所有的名字必須按引號裏的寫奧,寫錯了不好使可賴不着別人。
  • Step4. 到這步了,就搞一下“WXPayEntryActivity” ,下面代碼直接複製進就OK,如有報錯簡單改一下就行,別嫌費勁奧!
    private IWXAPI api;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.微信支付返回來過渡的頁面/支付結果頁也湊合);

        api = WXAPIFactory.createWXAPI(this, Constants.WX_KEY);
        api.handleIntent(getIntent(), this);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        api.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq baseReq) {
    }

    @Override
    public void onResp(BaseResp baseResp) {
        if (baseResp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
            // 判斷一下子微信支付成功沒成功,就3個返回值
            switch (baseResp.errCode) {
                case 0:
                    // 成功 - 成功之後需要跑一下後臺接口,驗證是否真的支付成功
                    requestCheckWechatPayResult();
                    break;
                case -1:
                    // 錯誤
                    ToastUtil.getInstance()._short(this, baseResp.errStr);
                    break;
                case -2:
                    // 用戶取消
                    ToastUtil.getInstance()._short(this, "取消支付");
                    break;
            }
        }
    }
  • Step5. 上你項目的Manifest裏註冊一下這個Activity,就完事了,跑程序吧!

 

※ Ps. 重要的事情說一遍,如果你手機裏沒安裝微信,按照這5步弄完,會提示3個錯誤,並且沒有反應,這個時候就需要注意了奧!

 

接下來大概說一下幾個在WXPayEntryActivity獲取OrderID用來顯示或跑後臺接口用的辦法:

  • 方法一:※ 肯定好使的方法,但比較大衆化而且比較Low —— SharedPreference

就是在你請求微信支付接口前,肯定得先跑後臺給你的接口吧?那個時候是不是給你返回了OrderID?什麼?沒返回?找後臺去!以下說的是返回了OrderID的情況:

在你請求微信支付接口前,把後臺返回的OrderID存到本地SharedPreference裏,然後在WXPayEntryActivity的回調方法onResp() 裏取出來這個OrderID,然後再進行下一步操作,操作完了,把這個OrderID幹掉,省得到時候存多了搞混了。

 

  • 方法二:稍微高級點的方法,用EventBus 黏性事件,這個就不多說了,在你獲取到OrderID的時候給它按黏性事件發送走,完了接收的地方註冊一下EventBus,直接取就OK了。但是一定要記得,要註銷EventBus的黏性事件!

 

  • 方法三:再高級點的辦法,用自定義接口轉接,俗稱嫁接的辦法,把微信支付回調的結果轉接到其他Activity,並進行操作。(這種方法朋友說的,沒試過,理論上可行,如有機會可以試試。)

 

  • 方法四:神奇腦洞的辦法,用推送,不走微信支付結果回調了,微信支付完成後,返回商戶跳轉時,估計你就能收到推送了,因爲 —— 經測試,後臺收到微信的支付結果要快於前端收到微信的支付結果,然後這時候根據推送的結果來跳轉展示微信支付結果頁面。(但這種方法容易出現紕漏,萬一推送沒好使呢,萬一推送讓人屏蔽了呢,萬一xxx)

 

  • 方法五:※※ 最靠譜的最簡單的最高大上的辦法來了,話不多說,看代碼:

PayReq req = new PayReq();
req.appId = dataBean.getAppId();
req.partnerId = dataBean.getMchId();
req.prepayId = dataBean.getPrepayId();
...
// 就是這個微信官方文檔裏沒介紹的參數,百度上查,作用爲:未知 的參數!
req.extData = dataBean.getOrderId();

api.sendReq(req);

說白了,就是拿這個 extData 參數來傳 OrderID ,然後在WXPayEntryActivity裏的回調方法中,這麼搞一下子:

// 這兩行代碼決定了這個OrderID是咋帶過來的
PayResp resps = (PayResp) baseResp;
String orderId = resps.extData;

這OrderID就獲取到了,不信你試試?

貼個onResp() 整個的代碼你瞅瞅?


    @Override
    public void onResp(BaseResp baseResp) {
        if (baseResp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
            PayResp resps = (PayResp) baseResp;
            String orderId = resps.extData;
            switch (baseResp.errCode) {
                case 0:
                    // 成功 - 成功之後跑一下後臺 驗證是否真正支付完成 接口
                    requestCheckWechatPayResult(orderId);
                    break;
                case -1:
                    // 錯誤
                    ToastUtil.getInstance()._short(this, baseResp.errStr);
                    break;
                case -2:
                    // 用戶取消
                    ToastUtil.getInstance()._short(this, "取消支付");
                    break;
            }
        }
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章