Android集成支付----微信支付總結(jié)與封裝
前言
之前做過一次微信支付的集成,但是沒有總結(jié)。最近一個App又要集成微信支付,又要重新下載demo,重新看開發(fā)文檔,重新寫代碼。相信所有的程序員遇到這種事情都會抓狂。觀察了一下微信支付并不設(shè)計業(yè)務(wù)邏輯,完全可以封裝成一個工具。
集成微信支付SDK
在集成第三方的時候,首先是要在自己的項目中集成對應(yīng)的SDK后才可以開發(fā)的。這個毋庸置疑。這里給出微信官方的集成文檔,讀者可自行查看,我在這里只對關(guān)鍵地方做出說明。
微信官方集成文檔:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417751808&token=6e7c5d2622dcc43878e06cd70caaa27a86d3d1d7&lang=zh_CN
1.導(dǎo)入sdk
如下圖,微信支付sdk已經(jīng)可以通過gradle來導(dǎo)入了,所以建議還在堅守eclipse的同學(xué)趕緊轉(zhuǎn)入Android studio。
Paste_Image.png2.大坑---支付回調(diào)頁面
先看官方文檔,仔細(xì)理解下圖被框住的文字。第一次做微信支付被這句話坑慘了,搞了兩天都TM找不到我到底錯在哪里了,現(xiàn)在想起來就生氣。所以這句話的正確解讀是:在你的包名下一級目錄里面,新建一個文件夾名字為wxapi。而不是像下圖一樣有兩個并列的net.sourceforge.simcpux。
Paste_Image.png
當(dāng)時之所以被坑的慘,也跟包結(jié)構(gòu)顯示樣式不同有關(guān)系。用Android Studio開發(fā)時包結(jié)構(gòu)多半是這樣的:
Paste_Image.png
對比以上兩張圖,相信聰明的你一點(diǎn)會發(fā)現(xiàn)問題。
微信支付開發(fā)步驟
微信SDK集成之后,準(zhǔn)備工作也就做好了,接下來就是要寫代碼了,有木有一點(diǎn)小激動呢。官方文檔:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2
1.統(tǒng)一下單(服務(wù)端做)
為了更加安全,微信推薦統(tǒng)一下單是交給服務(wù)端人員來做的,當(dāng)然也有一下服務(wù)端開發(fā)人員覺得麻煩,會推到客戶端來做,這個時候千萬別慫,一定要跟他講。
2.請求我們自己的接口
在我們自己的APP中點(diǎn)擊微信支付按鈕后,我們首先要請求一個我們自己服務(wù)端的接口,這時服務(wù)端需要走統(tǒng)一下單的邏輯,然后將一些參數(shù)返回給我們。這里需要注意,嚴(yán)格來說的話,這個接口應(yīng)該返回如下所有參數(shù):
Paste_Image.png
尤其是這個簽名的過程,微信官方強(qiáng)烈建議放在服務(wù)端來做。
而事實(shí)上,會有一些服務(wù)端開發(fā)人員為了他們自己方便,返回過來的數(shù)據(jù)是這樣的:
Paste_Image.png
如果這樣的話,簽名過程就要放在客戶端來做嘍。
3.調(diào)起微信APP進(jìn)行支付
調(diào)起微信APP是需要請求參數(shù)的,也就是上一步中說到的那些參數(shù),當(dāng)你把這些參數(shù)都湊夠了,那么這一步也就沒什么難度了,就是照著模板寫了:
?private?IWXAPI?iwxapi;?//微信支付api ?/** ?*調(diào)起微信支付的方法 ?**/ ?private?void?toWXPay()?{ ????????iwxapi?=?WXAPIFactory.createWXAPI(this,?null);?//初始化微信api ????????iwxapi.registerApp(appid);?//注冊appid??appid可以在開發(fā)平臺獲取 ????????Runnable?payRunnable?=?new?Runnable()?{??//這里注意要放在子線程 ????????????@Override ????????????public?void?run()?{ ????????????????PayReq?request?=?new?PayReq();?//調(diào)起微信APP的對象 ????????????????//下面是設(shè)置必要的參數(shù),也就是前面說的參數(shù),這幾個參數(shù)從何而來請看上面說明 ????????????????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);//發(fā)送調(diào)起微信的請求 ????????????} ????????}; ????????Thread?payThread?=?new?Thread(payRunnable); ????????payThread.start(); ????}
4.處理微信支付的回調(diào)
處理微信支付的回調(diào)就是在剛剛創(chuàng)建的WXEntryActivity中處理。需要實(shí)現(xiàn)IWXAPIEventHandler接口,這個接口會要求你實(shí)現(xiàn)onResp方法,我們就在這個方法中處理回調(diào)。
@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(); ????????} ????}
到此微信支付也就完成了,是不是很簡單呀。
簽名問題
前面提到,有時候簽名會讓客戶端來做,那么我們就來看看簽名怎么來搞搞吧。
先看看官方的簽名規(guī)則:
Paste_Image.png
仔細(xì)閱讀上面的簽名規(guī)則,應(yīng)該不難理解。理解不了也沒關(guān)系,下面就是我寫好的代碼:
????/** ?????*?調(diào)起微信APP支付,簽名 ?????*/ ????public?static?String?genPackageSign2(Listparams)?{ ????????StringBuilder?sb?=?new?StringBuilder(); ????????for?(int?i?=?0;?i?<?params.size();?i++)?{????//將參數(shù)拼接成鍵值對樣式的字符串 ????????????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 ????????//進(jìn)行MD5加密,并轉(zhuǎn)為大寫 ????????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; ????????}
微信支付的封裝
由于微信支付不涉及很多業(yè)務(wù)邏輯,因此完全可以封裝成工具類。這里對微信支付做了封裝,并且用了Builder設(shè)計模塊(類似Dialog的使用)。
封裝后的使用案例:
????????//在服務(wù)端簽名 ????????findViewById(R.id.btn1).setOnClickListener(new?View.OnClickListener()?{ ????????????@Override ????????????public?void?onClick(View?view)?{ ????????????????//假裝請求了服務(wù)器?獲取到了所有的數(shù)據(jù) ????????????????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)?{ ????????????????//假裝請求了服務(wù)端信息,并獲取了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"); ????????????} ????????});
經(jīng)過這樣封裝后,下次再接入微信支付就簡單多了。會少走很多彎路。具體封裝請參考github:https://github.com/chaohengxing/WXPayUtils.git
微信支付到此也就總結(jié)完了,是不是感覺很簡單呢,不過一定要注意別掉坑里。
詳細(xì)代碼請參考github:https://github.com/chaohengxing/WXPayUtils.git