Android集成支付----微信支付總結(jié)與封裝

前言

之前做過(guò)一次微信支付的集成,但是沒(méi)有總結(jié)脐区。最近一個(gè)App又要集成微信支付愈诚,又要重新下載demo,重新看開(kāi)發(fā)文檔,重新寫(xiě)代碼炕柔。相信所有的程序員遇到這種事情都會(huì)抓狂酌泰。觀察了一下微信支付并不設(shè)計(jì)業(yè)務(wù)邏輯,完全可以封裝成一個(gè)工具匕累。

這里我們分三大步走:

一陵刹、導(dǎo)入微信SDK

二、寫(xiě)支付邏輯

三欢嘿、封裝

下面開(kāi)始詳解:

一衰琐、集成微信支付SDK

在集成第三方的時(shí)候,首先是要在自己的項(xiàng)目中集成對(duì)應(yīng)的SDK后才可以開(kāi)發(fā)的炼蹦。這個(gè)毋庸置疑羡宙。這里給出微信官方的集成文檔,讀者可自行查看掐隐,我在這里只對(duì)關(guān)鍵地方做出說(shuō)明狗热。
微信官方集成文檔: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)可以通過(guò)gradle來(lái)導(dǎo)入了虑省,所以建議還在堅(jiān)守eclipse的同學(xué)趕緊轉(zhuǎn)入Android studio匿刮。


Paste_Image.png
2.大坑---接收微信的請(qǐng)求及返回值

先看官方文檔,仔細(xì)理解下圖被框住的文字慷妙。第一次做微信支付被這句話(huà)坑慘了僻焚,搞了兩天都TM找不到我到底錯(cuò)在哪里了,現(xiàn)在想起來(lái)就生氣膝擂。所以這句話(huà)的正確解讀是:在你的包名下一級(jí)目錄里面虑啤,新建一個(gè)文件夾名字為wxapi。而不是像下圖一樣有兩個(gè)并列的net.sourceforge.simcpux架馋。

image.png

當(dāng)時(shí)之所以被坑的慘狞山,也跟包結(jié)構(gòu)顯示樣式不同有關(guān)系。用Android Studio開(kāi)發(fā)時(shí)包結(jié)構(gòu)多半是這樣的:

Paste_Image.png

對(duì)比以上兩張圖叉寂,相信聰明的你一點(diǎn)會(huì)發(fā)現(xiàn)問(wèn)題萍启。

二、微信支付開(kāi)發(fā)步驟

微信SDK集成之后屏鳍,準(zhǔn)備工作也就做好了勘纯,接下來(lái)就是要寫(xiě)代碼了,有木有一點(diǎn)小激動(dòng)呢钓瞭。官方文檔:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2

1.統(tǒng)一下單(服務(wù)端做)

為了更加安全驳遵,微信推薦統(tǒng)一下單是交給服務(wù)端人員來(lái)做的,當(dāng)然也有一下服務(wù)端開(kāi)發(fā)人員覺(jué)得麻煩山涡,會(huì)推到客戶(hù)端來(lái)做堤结,這個(gè)時(shí)候千萬(wàn)別慫唆迁,一定要跟他講。

2.請(qǐng)求我們自己的接口

在我們自己的APP中點(diǎn)擊微信支付按鈕后竞穷,我們首先要請(qǐng)求一個(gè)我們自己服務(wù)端的接口唐责,這時(shí)服務(wù)端需要走統(tǒng)一下單的邏輯,然后將一些參數(shù)返回給我們瘾带。這里需要注意鼠哥,嚴(yán)格來(lái)說(shuō)的話(huà),這個(gè)接口應(yīng)該返回如下所有參數(shù):

Paste_Image.png

尤其是這個(gè)簽名的過(guò)程看政,微信官方強(qiáng)烈建議放在服務(wù)端來(lái)做肴盏。
而事實(shí)上,會(huì)有一些服務(wù)端開(kāi)發(fā)人員為了他們自己方便帽衙,返回過(guò)來(lái)的數(shù)據(jù)是這樣的:

Paste_Image.png

如果這樣的話(huà),簽名過(guò)程就要放在客戶(hù)端來(lái)做嘍贞绵。

3.調(diào)起微信APP進(jìn)行支付

調(diào)起微信APP是需要請(qǐng)求參數(shù)的厉萝,也就是上一步中說(shuō)到的那些參數(shù),當(dāng)你把這些參數(shù)都湊夠了榨崩,那么這一步也就沒(méi)什么難度了谴垫,就是照著模板寫(xiě)了:

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

        Runnable payRunnable = new Runnable() {  //這里注意要放在子線(xiàn)程
            @Override
            public void run() {
                PayReq request = new PayReq(); //調(diào)起微信APP的對(duì)象
                //下面是設(shè)置必要的參數(shù),也就是前面說(shuō)的參數(shù),這幾個(gè)參數(shù)從何而來(lái)請(qǐng)看上面說(shuō)明
                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)起微信的請(qǐng)求
            }
        };
        Thread payThread = new Thread(payRunnable);
        payThread.start();
    }
4.處理微信支付的回調(diào)

處理微信支付的回調(diào)就是在剛剛創(chuàng)建的WXPayEntryActivity中處理母蛛。需要實(shí)現(xiàn)IWXAPIEventHandler接口翩剪,這個(gè)接口會(huì)要求你實(shí)現(xiàn)onResp方法,我們就在這個(gè)方法中處理回調(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();
        }
    }

到此微信支付也就完成了前弯,是不是很簡(jiǎn)單呀。

簽名問(wèn)題

前面提到秫逝,有時(shí)候簽名會(huì)讓客戶(hù)端來(lái)做恕出,那么我們就來(lái)看看簽名怎么來(lái)搞搞吧。
先看看官方的簽名規(guī)則:

Paste_Image.png

仔細(xì)閱讀上面的簽名規(guī)則违帆,應(yīng)該不難理解浙巫。理解不了也沒(méi)關(guān)系,下面就是我寫(xiě)好的代碼:

    /**
     * 調(diào)起微信APP支付刷后,簽名
     */
    public static String genPackageSign2(List<NameValuePair> params) {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < params.size(); i++) {    //將參數(shù)拼接成鍵值對(duì)樣式的字符串
            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)為大寫(xiě)
        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ù)邏輯尝胆,因此完全可以封裝成工具類(lèi)丧裁。這里對(duì)微信支付做了封裝,并且用了Builder設(shè)計(jì)模塊(類(lèi)似Dialog的使用)班巩。
封裝后的使用案例:

        //在服務(wù)端簽名
        findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //假裝請(qǐng)求了服務(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");
            }
        });
        //在客戶(hù)端簽名
        findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //假裝請(qǐng)求了服務(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)過(guò)這樣封裝后逊桦,下次再接入微信支付就簡(jiǎn)單多了眨猎。會(huì)少走很多彎路。
微信支付到此也就總結(jié)完了强经,是不是感覺(jué)很簡(jiǎn)單呢睡陪,不過(guò)一定要注意別掉坑里。
詳細(xì)代碼請(qǐng)參考github:https://github.com/chaohengxing/WXPayUtils.git

另外在開(kāi)發(fā)中遇到問(wèn)題可以直接私信我匿情,希望可以幫助到大家

分享一個(gè)在線(xiàn)測(cè)試接口兰迫,可能大家用得到
https://wxpay.wxutil.com/pub_v2/app/app_pay.php
以前不知道這個(gè),感謝下面這位兄弟

image.png

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末炬称,一起剝皮案震驚了整個(gè)濱河市汁果,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌玲躯,老刑警劉巖据德,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異跷车,居然都是意外死亡棘利,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)朽缴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)善玫,“玉大人,你說(shuō)我怎么就攤上這事密强∶├桑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵誓斥,是天一觀的道長(zhǎng)只洒。 經(jīng)常有香客問(wèn)我,道長(zhǎng)劳坑,這世上最難降的妖魔是什么毕谴? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮距芬,結(jié)果婚禮上涝开,老公的妹妹穿的比我還像新娘。我一直安慰自己框仔,他們只是感情好舀武,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著离斩,像睡著了一般银舱。 火紅的嫁衣襯著肌膚如雪瘪匿。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天寻馏,我揣著相機(jī)與錄音棋弥,去河邊找鬼。 笑死诚欠,一個(gè)胖子當(dāng)著我的面吹牛顽染,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播轰绵,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼粉寞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了左腔?” 一聲冷哼從身側(cè)響起唧垦,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎液样,沒(méi)想到半個(gè)月后业崖,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蓄愁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了狞悲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撮抓。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖摇锋,靈堂內(nèi)的尸體忽然破棺而出丹拯,到底是詐尸還是另有隱情,我是刑警寧澤荸恕,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布乖酬,位于F島的核電站,受9級(jí)特大地震影響融求,放射性物質(zhì)發(fā)生泄漏咬像。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一生宛、第九天 我趴在偏房一處隱蔽的房頂上張望县昂。 院中可真熱鬧,春花似錦陷舅、人聲如沸倒彰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)待讳。三九已至芒澜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間创淡,已是汗流浹背痴晦。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留辩昆,地道東北人阅酪。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像汁针,于是被迫代替她去往敵國(guó)和親术辐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容