Android集成微信支付 總結與封裝

集成微信支付SDK
在集成第三方的時候,首先是要在自己的項目中集成對應的SDK后才可以開發的。這個毋庸置疑。這里給出微信官方的集成文檔,讀者可自行查看,我在這里只對關鍵地方做出說明。
微信官方集成文檔:
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417751808&token=6e7c5d2622dcc43878e06cd70caaa27a86d3d1d7&lang=zh_CN

如下圖,微信支付sdk已經可以通過gradle來導入了,所以建議還在堅守eclipse的同學趕緊轉入Android studio。

image.png

2.大坑---支付回調頁面

先看官方文檔,仔細理解下圖被框住的文字。第一次做微信支付被這句話坑慘了,搞了兩天都TM找不到我到底錯在哪里了,現在想起來就生氣。所以這句話的正確解讀是:在你的包名下一級目錄里面,新建一個文件夾名字為wxapi。而不是像下圖一樣有兩個并列的net.sourceforge.simcpux。

image.png

Paste_Image.png

當時之所以被坑的慘,也跟包結構顯示樣式不同有關系。用Android Studio開發時包結構多半是這樣的:

image.png

Paste_Image.png

對比以上兩張圖,相信聰明的你一點會發現問題。

微信支付開發步驟

微信SDK集成之后,準備工作也就做好了,接下來就是要寫代碼了,有木有一點小激動呢。官方文檔:pay.weixin.qq.com/wiki/doc/ap…

1.統一下單(服務端做)
為了更加安全,微信推薦統一下單是交給服務端人員來做的,當然也有一下服務端開發人員覺得麻煩,會推到客戶端來做,這個時候千萬別慫,一定要跟他講。

2.請求我們自己的接口
在我們自己的APP中點擊微信支付按鈕后,我們首先要請求一個我們自己服務端的接口,這時服務端需要走統一下單的邏輯,然后將一些參數返回給我們。這里需要注意,嚴格來說的話,這個接口應該返回如下所有參數:


image.png

尤其是這個簽名的過程,微信官方強烈建議放在服務端來做。而事實上,會有一些服務端開發人員為了他們自己方便,返回過來的數據是這樣的:

image.png

如果這樣的話,簽名過程就要放在客戶端來做嘍。

3.調起微信APP進行支付
調起微信APP是需要請求參數的,也就是上一步中說到的那些參數,當你把這些參數都湊夠了,那么這一步也就沒什么難度了,就是照著模板寫了:

private IWXAPI iwxapi; //微信支付api
/**
*調起微信支付的方法
**/
private void toWXPay() {
iwxapi = WXAPIFactory.createWXAPI(this, null); //初始化微信api
iwxapi.registerApp(appid); //注冊appid appid可以在開發平臺獲取

    Runnable payRunnable = new Runnable() {  //這里注意要放在子線程
        @Override
        public void run() {
            PayReq request = new PayReq(); //調起微信APP的對象
            //下面是設置必要的參數,也就是前面說的參數,這幾個參數從何而來請看上面說明
            request.appId = appid;
            request.partnerId = partnerId;
            request.prepayId = prepayId;
            request.packageValue = "Sign=WXPay";
            request.nonceStr = nonceStr;
            request.timeStamp = timeStamp;
            request.sign = sign;
            iwxapi.sendReq(request);//發送調起微信的請求
        }
    };
    Thread payThread = new Thread(payRunnable);
    payThread.start();
}

4.處理微信支付的回調
處理微信支付的回調就是在剛剛創建的WXEntryActivity中處理。需要實現IWXAPIEventHandler接口,這個接口會要求你實現onResp方法,我們就在這個方法中處理回調。

@Override
public void onResp(BaseResp resp) {

    if(resp.getType()==ConstantsAPI.COMMAND_PAY_BY_WX){
        if(resp.errCode==0){
            Toast.makeText(this, "支付成功", Toast.LENGTH_LONG).show();
        }
        else {
            Toast.makeText(this, "支付失敗", Toast.LENGTH_LONG).show();
        }
        finish();
    }
}

到此微信支付也就完成了,是不是很簡單呀。

簽名問題
前面提到,有時候簽名會讓客戶端來做,那么我們就來看看簽名怎么來搞搞吧。先看看官方的簽名規則:

image.png

仔細閱讀上面的簽名規則,應該不難理解。理解不了也沒關系,下面就是我寫好的代碼:
/**
* 調起微信APP支付,簽名
*/
public static String genPackageSign2(List<NameValuePair> params) {
StringBuilder sb = new StringBuilder();

    for (int i = 0; i < params.size(); i++) {    //將參數拼接成鍵值對樣式的字符串
        sb.append(params.get(i).getName());
        sb.append('=');
        sb.append(params.get(i).getValue());
        sb.append('&');
    }
    sb.append("key=");
    sb.append(Constants.API_KEY); //拼接key

    //進行MD5加密,并轉為大寫
    String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
    return packageSign;    //返回簽名
}

 /**
 * MD5加密算法
 */
public final static String getMessageDigest(byte[] buffer) {
    char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    try {
        MessageDigest mdTemp = MessageDigest.getInstance("MD5");
        mdTemp.update(buffer);
        byte[] md = mdTemp.digest();
        int j = md.length;
        char str[] = new char[j * 2];
        int k = 0;
        for (int i = 0; i < j; i++) {
            byte byte0 = md[i];
            str[k++] = hexDigits[byte0 >>> 4 & 0xf];
            str[k++] = hexDigits[byte0 & 0xf];
        }
        return new String(str);
    } catch (Exception e) {
        return null;
    }

微信支付的封裝

由于微信支付不涉及很多業務邏輯,因此完全可以封裝成工具類。這里對微信支付做了封裝,并且用了Builder設計模塊(類似Dialog的使用)。封裝后的使用案例:

        //在服務端簽名
        findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //假裝請求了服務器 獲取到了所有的數據
                WXPayUtils.WXPayBuilder builder = new WXPayUtils.WXPayBuilder();
                builder.setAppId("123")
                        .setPartnerId("56465")
                        .setPrepayId("41515")
                        .setPackageValue("5153")
                        .setNonceStr("5645")
                        .setTimeStamp("56512")
                        .setSign("54615")
                        .build().toWXPayNotSign(MainActivity.this,"123");
            }
        });
        //在客戶端簽名
        findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //假裝請求了服務端信息,并獲取了appid、partnerId、prepayId
                WXPayUtils.WXPayBuilder builder = new WXPayUtils.WXPayBuilder();
                builder.setAppId("123")
                        .setPartnerId("213")
                        .setPrepayId("3213")
                        .setPackageValue("Sign=WXPay")
                        .build()
                        .toWXPayAndSign(MainActivity.this,"123","key");
            }
        });

經過這樣封裝后,下次再接入微信支付就簡單多了。會少走很多彎路。具體封裝請參考github:github.com/chaohengxin…
微信支付到此也就總結完了,是不是感覺很簡單呢,不過一定要注意別掉坑里。
詳細代碼請參考github:github.com/chaohengxin…

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。