導(dǎo)讀微信(WeChat)是騰訊公司于2011年1月21日推出的一個(gè)為智能終端提供即時(shí)通訊服務(wù)的免費(fèi)應(yīng)用程序,由張小龍所帶領(lǐng)的騰訊廣州研發(fā)中心產(chǎn)品團(tuán)隊(duì)打造 [2] 。微信支持跨通信運(yùn)營(yíng)商、跨操作系統(tǒng)平臺(tái)... 微信(WeChat)是騰訊公司于2011年1月21日推出的一個(gè)為智能終端提供即時(shí)通訊服務(wù)的免費(fèi)應(yīng)用程序,由張小龍所帶領(lǐng)的騰訊廣州研發(fā)中心產(chǎn)品團(tuán)隊(duì)打造 [2] 。微信支持跨通信運(yùn)營(yíng)商、跨操作系統(tǒng)平臺(tái)通過(guò)網(wǎng)絡(luò)快速發(fā)送免費(fèi)(需消耗少量網(wǎng)絡(luò)流量)語(yǔ)音短信、視頻、圖片和文字,同時(shí),也可以使用通過(guò)共享流媒體內(nèi)容的資料和基于位置的社交插件“搖一搖”、“漂流瓶”、“朋友圈”、”公眾平臺(tái)“、”語(yǔ)音記事本“等服務(wù)插件。 教程中的內(nèi)容未實(shí)現(xiàn)識(shí)別哪個(gè)帖子或文章收到的打款,當(dāng)然我的站點(diǎn)已經(jīng)實(shí)現(xiàn),你可以試試哈。有段時(shí)間沒(méi)有寫實(shí)戰(zhàn)類的文章了,今天分享一篇,使用yii2+houjs+yii2-wx實(shí)現(xiàn)微信送禮物功能。先來(lái)個(gè)效果圖 簡(jiǎn)單點(diǎn)說(shuō)就是點(diǎn)擊“送禮物”按鈕后出現(xiàn)一個(gè)彈出框,里面有很多禮物,點(diǎn)擊某個(gè)禮物后彈出框刷新并出現(xiàn)一個(gè)二維碼,微信掃碼支付。 當(dāng)然這個(gè)錢會(huì)進(jìn)入到會(huì)員的個(gè)人賬號(hào)內(nèi),然后提現(xiàn)。 為何要做這樣一個(gè)功能那? 說(shuō)心里話我真心沒(méi)想過(guò)通過(guò)這個(gè)得到多少,更多算一種激勵(lì)吧,如果你在我們學(xué)習(xí)社群分享了有價(jià)值的文章,你非常有可能受到我的禮物。 好了,還是說(shuō)功能吧,功能有幾個(gè)
我勒個(gè)去,干貨滿滿呀。開(kāi)始。 數(shù)據(jù)表結(jié)構(gòu)既然是送禮品,那自然包含禮品表,還有送禮物的日志表,我規(guī)劃如下。 禮物表gift 禮物日志表gift_log 對(duì)于 gift_log 表可以不用lang_id,這里為了統(tǒng)計(jì)方便添加了這個(gè)字段。 整體思路用戶送禮物的整體邏輯如下
獲取禮物列表接下來(lái)我們使用houjs來(lái)構(gòu)建前臺(tái)功能,關(guān)于houjs的使用可以去社群查看 傳送門,我們主要使用其modal彈出框助手和jsmart模板引擎。 首先指定一個(gè)按鈕 <button class="ui green button" id="giftBtn" data-url="<?= Url::to(['/gift/list','id'=>$lang->id]);?>"> <i class="share icon"></i>送禮物 </button> data-url代表用于獲取禮物列表的路由,為按鈕做一個(gè)click事件處理 requirejs(['mods/modal','jSmart'],function(modal,jSmart){ $('#giftBtn').click(function(){ var url = $(this).attr('data-url'); $.getJSON(url,{},function(d){ if(d.result === 'ok'){ // d.data }else{ modal.msg(d.message); } }); }); }) 發(fā)起了一個(gè)請(qǐng)求用來(lái)獲取禮物列表,如果失敗則提示錯(cuò)誤信息。 接下來(lái)我們新建GiftController.php并定義list動(dòng)作。 public function actionList($id){ Yii::$app->response->format = 'json'; try { $data = Gift::find()->where(['lang_id'=>$id])->asArray()->all(); return ['result'=>'ok','data'=>$data]; }catch(Exception $e){ return ['result'=>'fail','message'=>$e->getMessage()]; } } 從這里我們知道現(xiàn)在點(diǎn)擊按鈕后獲得的數(shù)據(jù)里d.data就是此社群的禮物列表。 當(dāng)前臺(tái)得到了禮物列表后,使用jsmart將數(shù)據(jù)轉(zhuǎn)換成html代碼,為此我們需要先做一個(gè)jsmart的模板,在送禮物按鈕頁(yè)面增加此模板。 <script id="giftTpl" type="text/x-jsmart-tmpl"> <p class="gifts-box"> <p class="gifts"> {foreach $data as $key=>$gift} <a href=""> <p class="gift-icon"><img src='{$gift.icon}'/></p> <p class="gift-name">{$gift.name}</p> </a> {/foreach} </p> </p> </script> 這個(gè)模板的大體意思就是講過(guò)來(lái)的d.data中的數(shù)據(jù)進(jìn)行循環(huán),每個(gè)禮物放到標(biāo)簽a中,然后我們向后臺(tái)獲取禮物列表的js代碼進(jìn)行補(bǔ)充,如下。 requirejs(['mods/modal','jSmart'],function(modal,jSmart){ $('#giftBtn').click(function(){ var url = $(this).attr('data-url'); $.getJSON(url,{},function(d){ if(d.result === 'ok'){ var tplText = $('#giftTpl').html(); var compiledTemplate = new jSmart(tplText); var output = compiledTemplate.fetch(d); modal.alert(output,{ inPage:false, title:'送禮物', size:'tiny' }); }else{ modal.msg(d.message); } }); }); }) 進(jìn)行模板渲染,到了我們看效果的時(shí)候了。 我很喜歡,使用yii2和houjs的modal&jsmart,完成了禮物列表的功能。接下來(lái)我們要做一個(gè)重要的事情,和后臺(tái)交互并且得到支付二維碼。 得到支付二維碼在本章我們使用yii2-wx擴(kuò)展實(shí)現(xiàn)微信支付功能,其思路點(diǎn)擊禮物后獲取支付二維碼。 在進(jìn)行之前我們對(duì)上一步的js方法進(jìn)行優(yōu)化,將代碼放到一個(gè)單獨(dú)的js模塊中,在houjs中對(duì)于業(yè)務(wù)上的js代碼推薦放到houjs/js/modules中,如下 define(function(require,exports,modules){ var modal = require('mods/modal'); var jSmart = require('jSmart'); exports.list = function(){ $('#giftBtn').click(function(){ var url = $(this).attr('data-url'); $.getJSON(url,{},function(d){ if(d.result === 'ok'){ var tplText = $('#giftTpl').html(); var compiledTemplate = new jSmart(tplText); var output = compiledTemplate.fetch(d); modal.alert(output,{ inPage:false, title:'送禮物給作者', size:'tiny' }); }else{ modal.msg(d.message); } }); }); }; }); 因此獲取禮物列表的js代碼調(diào)用就變的簡(jiǎn)單了,如下 requirejs(['modules/gift'],function(gift){ gift.list(); }) 以后關(guān)于gift的js代碼都可以放到houjs/js/modules/gift.js中。 好,還是說(shuō)本部分話題。如何獲取支付二維碼? 我的思路如下:用戶點(diǎn)擊每個(gè)禮品后發(fā)起一次get請(qǐng)求到服務(wù)器,本次請(qǐng)求包含了禮物的ID,后臺(tái)收到后生成送禮物日志并和微信服務(wù)器通訊得到支付二維碼,返回給瀏覽器,前臺(tái)渲染此二維碼。 說(shuō)干就干。 首先補(bǔ)充禮物列表,每個(gè)禮物的a鏈接,如下 <script id="giftTpl" type="text/x-jsmart-tmpl"> <p class="gifts-box"> <p class="gifts"> {foreach $data as $key=>$gift} <a class="_get_qrcode" href="javascript:;" data-url="<?= Url::to(['/gift/qrcode']);?>?id={$gift.id}"> <p class="gift-icon"><img src='{$gift.icon}'/></p> <p class="gift-name">{$gift.name}</p> </a> {/foreach} </p> </p> </script> 我們?yōu)槊總(gè)禮物的a鏈接設(shè)置了3個(gè)屬性
接下來(lái)我們做一個(gè)js方法實(shí)現(xiàn)a鏈接點(diǎn)擊的監(jiān)聽(tīng),如下 // houjs/js/modules/gift.js define(function(require,exports,modules){ var modal = require('mods/modal'); var jSmart = require('jSmart'); ..... /** * 獲取某一個(gè)禮物的支付二維碼 */ exports.qrcode = function(){ $('._get_qrcode').click(function(){ var url = $(this).attr('data-url'); $.getJSON(url,{},function(d){ if(d.result === 'ok'){ $('#payQrcode') .html("<img width='120' src='"+d.qrcode+"'/>"); }else{ modal.msg(d.message); } }); }); }; }); 有一點(diǎn)要說(shuō)明,因此禮物列表是在頁(yè)面dom渲染后加入的html代碼,因此如果想讓禮物列表的a鏈接被監(jiān)聽(tīng),在獲取禮物列表成功后需要調(diào)用exports.qrcode()函數(shù)進(jìn)行監(jiān)聽(tīng),如下 // houjs/js/modules/gift.js define(function(require,exports,modules){ var modal = require('mods/modal'); var jSmart = require('jSmart'); exports.list = function(){ $('#giftBtn').click(function(){ var url = $(this).attr('data-url'); $.getJSON(url,{},function(d){ if(d.result === 'ok'){ .... exports.qrcode(); }else{ modal.msg(d.message); } }); }); }; /** * 獲取某一個(gè)禮物的支付二維碼 */ exports.qrcode = function(){ .... }; }); 此刻用戶點(diǎn)擊了禮物的a鏈接,gift.qrcode()方法開(kāi)始運(yùn)作,請(qǐng)求達(dá)到了yii2的gift/qrcode動(dòng)作,我寫了如下代碼。 // yii2 GiftController/actionQrcode <?php namespace app\controllers; use app\models\Gift; use app\models\GiftLog; use yii\helpers\Url; use abei2017\wx\Application; use Da\QrCode\QrCode; use Yii; use yii\base\Exception; class GiftController extends NBase { .... public function actionQrcode($id){ Yii::$app->response->format = 'json'; try { $model = Gift::findOne($id); // order $order = new GiftLog(); $order->gift_id = $id; $order->user_id = Yii::$app->user->id; $order->created_at = time(); $order->number = 1; $order->money = $order->number*$model->price; $order->status = 'unpay'; $order->lang_id = $model->lang_id; if($order->save() == false){ throw new Exception(implode(',',$order->getFirstErrors())); } $out_trade_no = "gift-{$order->id}-".rand(1000,9999); $totalFee = $order->money*100; $conf = Yii::$app->params['wx']; $app = new Application(['conf'=>$conf['mp']]); $pay = $app->driver("mp.pay"); $attributes = [ 'body'=>"送禮物", 'detail'=>"{$model->name}", 'out_trade_no'=>$out_trade_no, 'total_fee'=>$totalFee, 'notify_url'=>Yii::$app->urlManager->createAbsoluteUrl(['/gift/notify']), 'product_id'=>'gift-'.$id ]; $native = $pay->native($attributes); $qrCode = (new QrCode($native['code_url']))->setSize(250)->setMargin(20); return ['result'=>'ok','qrcode'=>$qrCode->writeDataUri()]; }catch(Exception $e){ return ['result'=>'fail','message'=>$e->getMessage()]; } } } 首先要說(shuō)明的是上述代碼沒(méi)有問(wèn)題,但如果上線還是要處理細(xì)節(jié)的。 在actionQrcode方法中我們做了3件事情
這里使用的是yii2-wx提供的生成二維碼方法native,剩下的事情就是如何顯示這個(gè)二維碼。 為了讓用戶可以在支付前重新選擇禮物,本次并沒(méi)有選擇彈出二維碼,而是使用了禮物頁(yè)面替換的方法,如下圖 在禮物的右側(cè)我增加了一個(gè)p來(lái)存放二維碼,沒(méi)有選擇的時(shí)候用一些幫助來(lái)填充。這個(gè)二維碼的存放工作由gift.qrcode()方法實(shí)現(xiàn) $('#payQrcode').html("<img width='120' src='"+d.qrcode+"'/>"); 對(duì)應(yīng)的禮物列表模板也增加了支付區(qū)域 <script id="giftTpl" type="text/x-jsmart-tmpl"> <p class="gifts-box"> <p class="gifts"> {foreach $data as $key=>$gift} <a class="_get_qrcode" href="javascript:;" data-url="<?= Url::to(['/gift/qrcode']);?>?id={$gift.id}"> <p class="gift-icon"><img src='{$gift.icon}'/></p> <p class="gift-name">{$gift.name}</p> </a> {/foreach} </p> <p id="payQrcode"> <h1>使用小提示</h1> <p> 點(diǎn)擊左側(cè)的小禮物后會(huì)出現(xiàn)支付二維碼,掃碼即送。 </p> </p> <p class="clear"></p> </p> </script> 好,看下效果。 用戶拿手機(jī)支付當(dāng)用戶得到支付二維碼后必然是掃碼支付,接下來(lái)有兩個(gè)事情要做
先來(lái)處理結(jié)果通知,這個(gè)使用yii2-wx非常好實(shí)現(xiàn)。在GiftController中增加一個(gè)notify動(dòng)作。 // GiftController.php <?php namespace app\controllers; use app\models\Gift; use app\models\GiftLog; use yii\data\ActiveDataProvider; use yii\helpers\Url; use abei2017\wx\Application; use Da\QrCode\QrCode; use Yii; use yii\base\Exception; class GiftController extends NBase { public $enableCsrfValidation = false; ...... public function actionNotify(){ $conf = Yii::$app->params['wx']; $app = new Application(['conf'=>$conf['mp']]); $pay = $app->driver("mp.pay"); $response = $pay->handleNotify(function($notify,$isSuccess){ if($isSuccess){ @list($_,$id,$_) = explode('-',$notify['out_trade_no']); $model = GiftLog::findOne($id); if($model->status == 'pay'){ return true; } $model->status = 'pay'; $model->paid_at = time(); $model->transaction_id = $notify['transaction_id']; $model->update(); return true; } }); return $response; } } 對(duì)上面的邏輯有幾點(diǎn)要注意,這也是我們用yii2-wx的時(shí)候要注意的。
現(xiàn)在我們搞定了回調(diào),看下效果。 不錯(cuò)不錯(cuò) 離成功越來(lái)越近了!接下來(lái)我們要解決一個(gè)問(wèn)題,就是當(dāng)用戶支付后在瀏覽器上禮物列表的變化,我希望二維碼消失同時(shí)出現(xiàn)一個(gè)支付成功的頁(yè)面。 我需要一個(gè)輪詢,那么開(kāi)始吧,為此我在gift.js中增加一個(gè)輪詢功能,這個(gè)功能在渲染出二維碼后被觸發(fā)。 //gift.js exports.askIsPay = function(id){ var url = '/gift/is-pay.html'; $.getJSON(url,{id:id},function(d){ if(d.result === 'ok'){ $('#payQrcode').empty() .html("<h1>支付成功</h1><p>感謝您對(duì)作者的支持,他會(huì)知道您的名字以及打款。</p>"); }else{ setTimeout(function(){ exports.askIsPay(id) },3000); } }); } 每3秒詢問(wèn)一次服務(wù)器上gift/is-pay動(dòng)作是否此送禮物日志已經(jīng)付款,當(dāng)然要告訴是哪個(gè)訂單,如果已經(jīng)付款則改變p#payQrcode的內(nèi)容,否則繼續(xù)調(diào)用exports.askIsPay(id)再一次詢問(wèn)。一點(diǎn)注意的是我們?cè)谏啥S碼的時(shí)候需要服務(wù)器將此日志的id返回(這需要服務(wù)器的gift/qrcode動(dòng)作返回此送禮物日志的ID),當(dāng)exports.askIsPay觸發(fā)時(shí)export.qrcode將其傳入。 ... if(d.result === 'ok'){ $('#payQrcode').empty() .html("<img width='120' src='"+d.qrcode+"'/>"); exports.askIsPay(d.oId); }else{ modal.msg(d.message); } ... 當(dāng)然我們還要在服務(wù)器上新建一個(gè)控制器的動(dòng)作。 // GiftController.php public function actionIsPay($id){ Yii::$app->response->format = 'json'; try { $model = GiftLog::findOne($id); if($model->status == 'unpay'){ throw new Exception('還沒(méi)有支付'); } return ['result'=>'ok']; }catch(Exception $e){ return ['result'=>'fail','message'=>$e->getMessage()]; } } 大功告成,看看效果。 小結(jié)到此我們就完成了永不打賞禮物的全過(guò)程,算上部吧,下部我們將實(shí)現(xiàn)具體的打款到用戶賬號(hào)以及使用yii2-wx調(diào)用微信企業(yè)付款到零錢包接口實(shí)現(xiàn)錢到微信功能。 相關(guān)推薦: 微信小程序開(kāi)發(fā)實(shí)戰(zhàn)視頻教程 TP5.0實(shí)現(xiàn)簡(jiǎn)易管理員登錄注冊(cè)功能 以上就是三招教你怎樣實(shí)現(xiàn)微信禮物打賞功能 (代碼全)的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章! 微信提供公眾平臺(tái)、朋友圈、消息推送等功能,用戶可以通過(guò)“搖一搖”、“搜索號(hào)碼”、“附近的人”、掃二維碼方式添加好友和關(guān)注公眾平臺(tái),同時(shí)微信將內(nèi)容分享給好友以及將用戶看到的精彩內(nèi)容分享到微信朋友圈。 |
溫馨提示:喜歡本站的話,請(qǐng)收藏一下本站!