The content in the tutorial does not realize which post or article has received the payment. Of course, my site has implemented it, you can try it. It’s been a while since I’ve written a practical article. Today I’ll share one, using yii2 houjs yii2-wx to implement the gift-sending function on WeChat.
Let’s take a look at the renderings first
To put it simply, after clicking the "Send Gift" button, a pop-up box will appear, which contains There are many gifts. After clicking on a gift, the pop-up box refreshes and a QR code appears. Scan the code on WeChat to pay.
Of course, the money will be entered into the member's personal account and then withdrawn.
Why do you want to do such a function? To be honest, I really didn’t think about getting much from this. It is more of an incentive. If you share valuable articles in our learning community, you are very likely to receive a gift from me.
Okay, let’s talk about functions. There are several functions.
Creating a data table structure (gifts and gift-delivery logs)
Use houjs to complete the front-end pop-up box
Use yii2-wx to implement payment QR code
Add account functions for users
Enterprises using yii2-wx can pay in small change and the console mode of yii2 can realize the payment function for users (payment is made if it is greater than or equal to 2 yuan).
Let me check it out, it’s full of useful information. start.
Since it is giving gifts, it naturally includes a gift table and a log table for giving gifts. I plan as follows.
Gift table gift
Gift log table gift_log
For the gift_log table, lang_id is not required. This field is added here for statistical convenience.
The overall logic for users to send gifts is as follows
Click "Send Gift" to interact with the background to obtain this community gift list.
After obtaining the data, use the jsmart engine to render the html code of the specific gift.
Use modal to put the gift list into the pop-up box.
Click on the gift to interact with the background, and the background will generate a QR code and return it.
Users scan the QR code to pay.
Payment successful.
Next we use houjs to build the front-end function. Regarding the use of houjs, you can go to the community to view the portal. We mainly use its modal pop-up box. Helper and jsmart template engine.
First specify a button
<button class="ui green button" id="giftBtn" data-url="<?= Url::to(['/gift/list','id'=>$lang->id]);?>"> <i class="share icon"></i>送礼物 </button>
data-url represents the route used to obtain the gift list, and do a click event processing for the button
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); } }); }); })
Initiated a request to obtain Gift list, error message if failed.
Next we create a new GiftController.php and define the list action.
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()]; } }
From here we know that d.data in the data obtained after clicking the button is the gift list of this community.
After the front desk gets the gift list, use jsmart to convert the data into html code. To do this, we need to make a jsmart template first and add this template to the gift button page.
<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}'/ alt="Three tips to teach you how to implement WeChat gift tipping function (full code)" ></p> <p class="gift-name">{$gift.name}</p> </a> {/foreach} </p> </p> </script>
The general meaning of this template is that the data in d.data mentioned above is circulated, each gift is placed in tag a, and then we add the js code to obtain the gift list from the background, as follows.
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); } }); }); })
Perform template rendering, and it’s time for us to see the effect.
I like it very much, using yii2 and houjs's modal&jsmart to complete the gift list function. Next we have to do an important thing, interact with the backend and get the payment QR code.
In this chapter we use the yii2-wx extension to implement the WeChat payment function. The idea is to obtain the payment QR code after clicking on the gift.
Before proceeding, we optimize the js method in the previous step and put the code into a separate js module. In houjs, it is recommended to put the business js code in houjs/js/modules, as follows
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); } }); }); }; });
Therefore, the js code call to obtain the gift list becomes simple, as follows
requirejs(['modules/gift'],function(gift){ gift.list(); })
In the future, the js code for gift can be placed in houjs/js/modules/gift.js.
Okay, let’s talk about this part of the topic. How to obtain the payment QR code?
My idea is as follows: After the user clicks on each gift, he initiates a get request to the server. This request contains the ID of the gift. After receiving it in the background, a gift log is generated. It communicates with the WeChat server to obtain the payment QR code, returns it to the browser, and renders the QR code in the frontend.
Just do it.
First add the gift list, the a link of each gift, as follows
<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}'/ alt="Three tips to teach you how to implement WeChat gift tipping function (full code)" ></p> <p class="gift-name">{$gift.name}</p> </a> {/foreach} </p> </p> </script>
We set 3 attributes for the a link of each gift
class="_get_qrcode" 一个类,这个类并不起到样式作用,主要是为js监听此标签使用。
href="javascript:;" 防止点击跳转
data-url 点击连接后,js函数将根据data-url提供的地址发起请求
接下来我们做一个js方法实现a链接点击的监听,如下
// houjs/js/modules/gift.js define(function(require,exports,modules){ var modal = require('mods/modal'); var jSmart = require('jSmart'); ..... /** * 获取某一个礼物的支付二维码 */ exports.qrcode = function(){ $('._get_qrcode').click(function(){ var url = $(this).attr('data-url'); $.getJSON(url,{},function(d){ if(d.result === 'ok'){ $('#payQrcode') .html("<img style="max-width:90%"+d.qrcode+"'/ alt="Three tips to teach you how to implement WeChat gift tipping function (full code)" >"); }else{ modal.msg(d.message); } }); }); }; });
有一点要说明,因此礼物列表是在页面dom渲染后加入的html代码,因此如果想让礼物列表的a链接被监听,在获取礼物列表成功后需要调用exports.qrcode()函数进行监听,如下
// 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); } }); }); }; /** * 获取某一个礼物的支付二维码 */ exports.qrcode = function(){ .... }; });
此刻用户点击了礼物的a链接,gift.qrcode()方法开始运作,请求达到了yii2的gift/qrcode动作,我写了如下代码。
// 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()]; } } }
首先要说明的是上述代码没有问题,但如果上线还是要处理细节的。
在actionQrcode方法中我们做了3件事情
生成送礼物日志
调用yii2-wx生成支付二维码
使用QrCode生成二维码并传给浏览器
这里使用的是yii2-wx提供的生成二维码方法native,剩下的事情就是如何显示这个二维码。
为了让用户可以在支付前重新选择礼物,本次并没有选择弹出二维码,而是使用了礼物页面替换的方法,如下图
在礼物的右侧我增加了一个p来存放二维码,没有选择的时候用一些帮助来填充。这个二维码的存放工作由gift.qrcode()方法实现
$('#payQrcode').html("<img style="max-width:90%"+d.qrcode+"'/ alt="Three tips to teach you how to implement WeChat gift tipping function (full code)" >");
对应的礼物列表模板也增加了支付区域
<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}'/ alt="Three tips to teach you how to implement WeChat gift tipping function (full code)" ></p> <p class="gift-name">{$gift.name}</p> </a> {/foreach} </p> <p id="payQrcode"> <h1>使用小提示</h1> <p> 点击左侧的小礼物后会出现支付二维码,扫码即送。 </p> </p> <p class="clear"></p> </p> </script>
好,看下效果。
当用户得到支付二维码后必然是扫码支付,接下来有两个事情要做
yii2要处理微信支付结果通知,将此礼物日志设置为已经支付。
浏览器上次礼物列表二维码消失,提示支付成功。
先来处理结果通知,这个使用yii2-wx非常好实现。在GiftController中增加一个notify动作。
// 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; } }
对上面的逻辑有几点要注意,这也是我们用yii2-wx的时候要注意的。
关闭csrf验证 主要是防止yii2将微信给我们的结果通知请求屏蔽掉。
在设置礼物日志已付款前要判断下,如果已经付款则返回true,这样微信就不会再发请求。
现在我们搞定了回调,看下效果。
不错不错
离成功越来越近了!接下来我们要解决一个问题,就是当用户支付后在浏览器上礼物列表的变化,我希望二维码消失同时出现一个支付成功的页面。
我需要一个轮询,那么开始吧,为此我在gift.js中增加一个轮询功能,这个功能在渲染出二维码后被触发。
//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>感谢您对作者的支持,他会知道您的名字以及打款。</p>"); }else{ setTimeout(function(){ exports.askIsPay(id) },3000); } }); }
每3秒询问一次服务器上gift/is-pay动作是否此送礼物日志已经付款,当然要告诉是哪个订单,如果已经付款则改变p#payQrcode的内容,否则继续调用exports.askIsPay(id)再一次询问。一点注意的是我们在生成二维码的时候需要服务器将此日志的id返回(这需要服务器的gift/qrcode动作返回此送礼物日志的ID),当exports.askIsPay触发时export.qrcode将其传入。
... if(d.result === 'ok'){ $('#payQrcode').empty() .html("<img style="max-width:90%"+d.qrcode+"'/ alt="Three tips to teach you how to implement WeChat gift tipping function (full code)" >"); exports.askIsPay(d.oId); }else{ modal.msg(d.message); } ...
当然我们还要在服务器上新建一个控制器的动作。
// GiftController.php public function actionIsPay($id){ Yii::$app->response->format = 'json'; try { $model = GiftLog::findOne($id); if($model->status == 'unpay'){ throw new Exception('还没有支付'); } return ['result'=>'ok']; }catch(Exception $e){ return ['result'=>'fail','message'=>$e->getMessage()]; } }
大功告成,看看效果。
到此我们就完成了永不打赏礼物的全过程,算上部吧,下部我们将实现具体的打款到用户账号以及使用yii2-wx调用微信企业付款到零钱包接口实现钱到微信功能。
相关推荐:
The above is the detailed content of Three tips to teach you how to implement WeChat gift tipping function (full code). For more information, please follow other related articles on the PHP Chinese website!