目录
数据表结构
整体思路
获取礼物列表
得到支付二维码
用户拿手机支付
小结
首页 微信小程序 微信开发 三招教你怎样实现微信礼物打赏功能 (代码全)

三招教你怎样实现微信礼物打赏功能 (代码全)

Jul 25, 2018 pm 02:36 PM
yii2 微信 微信支付

教程中的内容未实现识别哪个帖子或文章收到的打款,当然我的站点已经实现,你可以试试哈。有段时间没有写实战类的文章了,今天分享一篇,使用yii2+houjs+yii2-wx实现微信送礼物功能。

先来个效果图

1455607284-5b236e4ad6e7d_articlex.jpg

简单点说就是点击“送礼物”按钮后出现一个弹出框,里面有很多礼物,点击某个礼物后弹出框刷新并出现一个二维码,微信扫码支付。

当然这个钱会进入到会员的个人账号内,然后提现。

为何要做这样一个功能那? 说心里话我真心没想过通过这个得到多少,更多算一种激励吧,如果你在我们学习社群分享了有价值的文章,你非常有可能受到我的礼物。

好了,还是说功能吧,功能有几个

  • 建立数据表结构(礼物以及送礼物日志)

  • 使用houjs完成前台弹出框

  • 使用yii2-wx实现支付二维码

  • 为用户增加账户功能

  • 使用yii2-wx的企业付款到零钱和yii2的控制台模式现实为用户打款功能(大于等于2元就打款)。

我勒个去,干货满满呀。开始。

数据表结构

既然是送礼品,那自然包含礼品表,还有送礼物的日志表,我规划如下。

礼物表gift

1130941675-5b236e5905e16_articlex.jpg

礼物日志表gift_log

37530968-5b236e6267994_articlex.jpg

对于 gift_log 表可以不用lang_id,这里为了统计方便添加了这个字段。

整体思路

用户送礼物的整体逻辑如下

  1. 点击“送礼物”和后台进行交互获取此社群礼物列表。

  2. 获取数据后使用jsmart引擎渲染出具体礼物的html代码。

  3. 使用modal将礼物列表放到弹出框弹出。

  4. 点击礼物和后台交互,后台生成二维码返回。

  5. 用户扫码付款。

  6. 付款成功。

获取礼物列表

接下来我们使用houjs来构建前台功能,关于houjs的使用可以去社群查看 传送门,我们主要使用其modal弹出框助手和jsmart模板引擎。

首先指定一个按钮

<button class="ui green button" id="giftBtn" data-url="<?= Url::to([&#39;/gift/list&#39;,&#39;id&#39;=>$lang->id]);?>">
    <i class="share icon"></i>送礼物
</button>
登录后复制

data-url代表用于获取礼物列表的路由,为按钮做一个click事件处理

requirejs([&#39;mods/modal&#39;,&#39;jSmart&#39;],function(modal,jSmart){
    $(&#39;#giftBtn&#39;).click(function(){
        var url = $(this).attr(&#39;data-url&#39;);
        $.getJSON(url,{},function(d){
            if(d.result === &#39;ok&#39;){
                // d.data
            }else{
                modal.msg(d.message);
            }
        });
    });
})
登录后复制

发起了一个请求用来获取礼物列表,如果失败则提示错误信息。

接下来我们新建GiftController.php并定义list动作。

public function actionList($id){
    Yii::$app->response->format = &#39;json&#39;;
    try {
        $data = Gift::find()->where([&#39;lang_id&#39;=>$id])->asArray()->all();

        return [&#39;result&#39;=>&#39;ok&#39;,&#39;data&#39;=>$data];
    }catch(Exception $e){
        return [&#39;result&#39;=>&#39;fail&#39;,&#39;message&#39;=>$e->getMessage()];
    }
}
登录后复制

从这里我们知道现在点击按钮后获得的数据里d.data就是此社群的礼物列表。

当前台得到了礼物列表后,使用jsmart将数据转换成html代码,为此我们需要先做一个jsmart的模板,在送礼物按钮页面增加此模板。

<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=&#39;{$gift.icon}&#39;/></p>
                <p class="gift-name">{$gift.name}</p>
            </a>
        {/foreach}
        </p>
    </p>
</script>
登录后复制

这个模板的大体意思就是讲过来的d.data中的数据进行循环,每个礼物放到标签a中,然后我们向后台获取礼物列表的js代码进行补充,如下。

requirejs([&#39;mods/modal&#39;,&#39;jSmart&#39;],function(modal,jSmart){
    $(&#39;#giftBtn&#39;).click(function(){
        var url = $(this).attr(&#39;data-url&#39;);
        $.getJSON(url,{},function(d){
            if(d.result === &#39;ok&#39;){
                var tplText = $(&#39;#giftTpl&#39;).html();
                var compiledTemplate = new jSmart(tplText);
                var output = compiledTemplate.fetch(d);
                modal.alert(output,{
                    inPage:false,
                    title:&#39;送礼物&#39;,
                    size:&#39;tiny&#39;
                });
            }else{
                modal.msg(d.message);
            }
        });
    });
})
登录后复制

进行模板渲染,到了我们看效果的时候了。

1585242546-5b236eb94918f_articlex.jpg

我很喜欢,使用yii2和houjs的modal&jsmart,完成了礼物列表的功能。接下来我们要做一个重要的事情,和后台交互并且得到支付二维码。

得到支付二维码

在本章我们使用yii2-wx扩展实现微信支付功能,其思路点击礼物后获取支付二维码。

在进行之前我们对上一步的js方法进行优化,将代码放到一个单独的js模块中,在houjs中对于业务上的js代码推荐放到houjs/js/modules中,如下

define(function(require,exports,modules){
    var modal = require(&#39;mods/modal&#39;);
    var jSmart = require(&#39;jSmart&#39;);

    exports.list = function(){
        $(&#39;#giftBtn&#39;).click(function(){
            var url = $(this).attr(&#39;data-url&#39;);
            $.getJSON(url,{},function(d){
                if(d.result === &#39;ok&#39;){
                    var tplText = $(&#39;#giftTpl&#39;).html();
                    var compiledTemplate = new jSmart(tplText);
                    var output = compiledTemplate.fetch(d);
                    modal.alert(output,{
                        inPage:false,
                        title:&#39;送礼物给作者&#39;,
                        size:&#39;tiny&#39;
                    });
                }else{
                    modal.msg(d.message);
                }
            });
        });
    };
});
登录后复制

因此获取礼物列表的js代码调用就变的简单了,如下

requirejs([&#39;modules/gift&#39;],function(gift){
    gift.list();
})
登录后复制

以后关于gift的js代码都可以放到houjs/js/modules/gift.js中。

好,还是说本部分话题。如何获取支付二维码?

我的思路如下:用户点击每个礼品后发起一次get请求到服务器,本次请求包含了礼物的ID,后台收到后生成送礼物日志并和微信服务器通讯得到支付二维码,返回给浏览器,前台渲染此二维码。

说干就干。

首先补充礼物列表,每个礼物的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([&#39;/gift/qrcode&#39;]);?>?id={$gift.id}">
                <p class="gift-icon"><img src=&#39;{$gift.icon}&#39;/></p>
                <p class="gift-name">{$gift.name}</p>
            </a>
        {/foreach}
        </p>
    </p>
</script>
登录后复制

我们为每个礼物的a链接设置了3个属性

  • 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(&#39;mods/modal&#39;);
    var jSmart = require(&#39;jSmart&#39;);
    
    .....

    /**
     * 获取某一个礼物的支付二维码
     */
    exports.qrcode = function(){
        $(&#39;._get_qrcode&#39;).click(function(){
            var url = $(this).attr(&#39;data-url&#39;);
            $.getJSON(url,{},function(d){
                if(d.result === &#39;ok&#39;){
                    $(&#39;#payQrcode&#39;)
                        .html("<img width=&#39;120&#39; src=&#39;"+d.qrcode+"&#39;/>");
                }else{
                    modal.msg(d.message);
                }
            });
        });
    };
});
登录后复制

有一点要说明,因此礼物列表是在页面dom渲染后加入的html代码,因此如果想让礼物列表的a链接被监听,在获取礼物列表成功后需要调用exports.qrcode()函数进行监听,如下

// houjs/js/modules/gift.js
define(function(require,exports,modules){
    var modal = require(&#39;mods/modal&#39;);
    var jSmart = require(&#39;jSmart&#39;);
    
    exports.list = function(){
        $(&#39;#giftBtn&#39;).click(function(){
            var url = $(this).attr(&#39;data-url&#39;);
            $.getJSON(url,{},function(d){
                if(d.result === &#39;ok&#39;){
                    ....

                    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 = &#39;json&#39;;
        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 = &#39;unpay&#39;;
            $order->lang_id = $model->lang_id;
            if($order->save() == false){
                throw new Exception(implode(&#39;,&#39;,$order->getFirstErrors()));
            }

            $out_trade_no = "gift-{$order->id}-".rand(1000,9999);

            $totalFee = $order->money*100;

            $conf = Yii::$app->params[&#39;wx&#39;];
            $app = new Application([&#39;conf&#39;=>$conf[&#39;mp&#39;]]);
            $pay = $app->driver("mp.pay");

            $attributes = [
                &#39;body&#39;=>"送礼物",
                &#39;detail&#39;=>"{$model->name}",
                &#39;out_trade_no&#39;=>$out_trade_no,
                &#39;total_fee&#39;=>$totalFee,
                &#39;notify_url&#39;=>Yii::$app->urlManager->createAbsoluteUrl([&#39;/gift/notify&#39;]),
                &#39;product_id&#39;=>&#39;gift-&#39;.$id
            ];

            $native = $pay->native($attributes);

            $qrCode = (new QrCode($native[&#39;code_url&#39;]))->setSize(250)->setMargin(20);

            return [&#39;result&#39;=>&#39;ok&#39;,&#39;qrcode&#39;=>$qrCode->writeDataUri()];
        }catch(Exception $e){
            return [&#39;result&#39;=>&#39;fail&#39;,&#39;message&#39;=>$e->getMessage()];
        }
    }

}
登录后复制

首先要说明的是上述代码没有问题,但如果上线还是要处理细节的。

在actionQrcode方法中我们做了3件事情

  1. 生成送礼物日志

  2. 调用yii2-wx生成支付二维码

  3. 使用QrCode生成二维码并传给浏览器

这里使用的是yii2-wx提供的生成二维码方法native,剩下的事情就是如何显示这个二维码。

为了让用户可以在支付前重新选择礼物,本次并没有选择弹出二维码,而是使用了礼物页面替换的方法,如下图

1.jpg

在礼物的右侧我增加了一个p来存放二维码,没有选择的时候用一些帮助来填充。这个二维码的存放工作由gift.qrcode()方法实现

$(&#39;#payQrcode&#39;).html("<img width=&#39;120&#39; src=&#39;"+d.qrcode+"&#39;/>");
登录后复制

对应的礼物列表模板也增加了支付区域

<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([&#39;/gift/qrcode&#39;]);?>?id={$gift.id}">
                <p class="gift-icon"><img src=&#39;{$gift.icon}&#39;/></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>
登录后复制

好,看下效果。

2.jpg

用户拿手机支付

当用户得到支付二维码后必然是扫码支付,接下来有两个事情要做

  • 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[&#39;wx&#39;];
        $app = new Application([&#39;conf&#39;=>$conf[&#39;mp&#39;]]);
        $pay = $app->driver("mp.pay");

        $response = $pay->handleNotify(function($notify,$isSuccess){
            if($isSuccess){
                @list($_,$id,$_) = explode(&#39;-&#39;,$notify[&#39;out_trade_no&#39;]);

                $model = GiftLog::findOne($id);
                if($model->status == &#39;pay&#39;){
                    return true;
                }

                $model->status = &#39;pay&#39;;
                $model->paid_at = time();
                $model->transaction_id = $notify[&#39;transaction_id&#39;];
                $model->update();

                return true;
            }
        });

        return $response;
    }

}
登录后复制

对上面的逻辑有几点要注意,这也是我们用yii2-wx的时候要注意的。

  • 关闭csrf验证 主要是防止yii2将微信给我们的结果通知请求屏蔽掉。

  • 在设置礼物日志已付款前要判断下,如果已经付款则返回true,这样微信就不会再发请求。

现在我们搞定了回调,看下效果。

3.jpg

不错不错

离成功越来越近了!接下来我们要解决一个问题,就是当用户支付后在浏览器上礼物列表的变化,我希望二维码消失同时出现一个支付成功的页面。

我需要一个轮询,那么开始吧,为此我在gift.js中增加一个轮询功能,这个功能在渲染出二维码后被触发。

//gift.js
exports.askIsPay = function(id){
    var url = &#39;/gift/is-pay.html&#39;;
    $.getJSON(url,{id:id},function(d){
        if(d.result === &#39;ok&#39;){
            $(&#39;#payQrcode&#39;).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 === &#39;ok&#39;){
    $(&#39;#payQrcode&#39;).empty()
        .html("<img width=&#39;120&#39; src=&#39;"+d.qrcode+"&#39;/>");
    exports.askIsPay(d.oId);
}else{
    modal.msg(d.message);
}
...
登录后复制

当然我们还要在服务器上新建一个控制器的动作。

// GiftController.php
public function actionIsPay($id){
    Yii::$app->response->format = &#39;json&#39;;
    try {
        $model = GiftLog::findOne($id);
        if($model->status == &#39;unpay&#39;){
            throw new Exception(&#39;还没有支付&#39;);
        }

        return [&#39;result&#39;=>&#39;ok&#39;];
    }catch(Exception $e){
        return [&#39;result&#39;=>&#39;fail&#39;,&#39;message&#39;=>$e->getMessage()];
    }
}
登录后复制

大功告成,看看效果。

4.jpg

小结

到此我们就完成了永不打赏礼物的全过程,算上部吧,下部我们将实现具体的打款到用户账号以及使用yii2-wx调用微信企业付款到零钱包接口实现钱到微信功能。

相关推荐:

微信小程序开发实战视频教程

TP5.0实现简易管理员登录注册功能

以上是三招教你怎样实现微信礼物打赏功能 (代码全)的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
<🎜>掩盖:探险33-如何获得完美的色度催化剂
2 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1677
14
CakePHP 教程
1430
52
Laravel 教程
1333
25
PHP教程
1278
29
C# 教程
1257
24
公司安全软件导致应用无法运行?如何排查和解决? 公司安全软件导致应用无法运行?如何排查和解决? Apr 19, 2025 pm 04:51 PM

公司安全软件导致部分应用无法正常运行的排查与解决方法许多公司为了保障内部网络安全,会部署安全软件。...

H5页面制作和微信小程序有什么不同 H5页面制作和微信小程序有什么不同 Apr 05, 2025 pm 11:51 PM

H5更灵活,可定制性强,但需要娴熟的技术;小程序上手快,维护便捷,但受限于微信框架。

企业微信中的JS资源缓存问题如何解决? 企业微信中的JS资源缓存问题如何解决? Apr 04, 2025 pm 05:06 PM

企业微信的JS资源缓存问题探讨在进行项目功能升级时,常常会遇到部分用户未能成功升级的情况,尤其是在企�...

H5和小程序与APP的区别 H5和小程序与APP的区别 Apr 06, 2025 am 10:42 AM

H5、小程序和APP的主要区别在于:技术架构:H5基于网页技术,小程序和APP为独立应用程序。体验和功能:H5轻便易用,功能受限;小程序轻量级,交互性好;APP功能强大,体验流畅。兼容性:H5跨平台兼容,小程序和APP受平台限制。开发成本:H5开发成本低,小程序中等,APP最高。适用场景:H5适合信息展示,小程序适合轻量化应用,APP适合复杂功能应用。

欧易交易所app国内下载教程 欧易交易所app国内下载教程 Mar 21, 2025 pm 05:42 PM

本文提供国内安全下载欧易OKX App的详细指南。由于国内应用商店限制,建议用户通过欧易OKX官方网站下载App,或使用官网提供的二维码扫描下载。下载过程中,务必核实官网地址,检查应用权限,安装后进行安全扫描,并启用双重验证。 使用过程中,请遵守当地法律法规,使用安全网络环境,保护账户安全,警惕诈骗,理性投资。 本文仅供参考,不构成投资建议,数字资产交易风险自负。

公司安全软件与应用冲突怎么办?HUES安全软件导致常用软件无法打开如何排查? 公司安全软件与应用冲突怎么办?HUES安全软件导致常用软件无法打开如何排查? Apr 01, 2025 pm 10:48 PM

公司安全软件与应用兼容性问题及排查方法许多企业为了保障内网安全,会安装安全软件。然而,安全软件有时...

H5和小程序的开发工具有哪些 H5和小程序的开发工具有哪些 Apr 06, 2025 am 09:54 AM

H5开发工具推荐:VSCode、WebStorm、Atom、Brackets、Sublime Text;小程序开发工具:微信开发者工具、支付宝小程序开发者工具、百度智能小程序IDE、头条小程序开发者工具、Taro。

币安虚拟币怎么买进卖出详细教程 币安虚拟币怎么买进卖出详细教程 Mar 18, 2025 pm 01:36 PM

本文提供2025年更新的币安虚拟货币买卖简明指南,详细讲解了在币安平台上进行虚拟货币交易的操作步骤。指南涵盖了法币购买USDT、币币交易购买其他币种(如BTC)以及卖出操作,包括市价交易和限价交易两种方式。 此外,指南还特别提示了法币交易的支付安全和网络选择等关键风险,帮助用户安全、高效地进行币安交易。 通过本文,您可以快速掌握在币安平台上买卖虚拟货币的技巧,降低交易风险。

See all articles