0

0

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

php是最好的语言

php是最好的语言

发布时间:2018-07-25 14:36:23

|

9622人浏览过

|

来源于php中文网

原创

教程中的内容未实现识别哪个帖子或文章收到的打款,当然我的站点已经实现,你可以试试哈。有段时间没有写实战类的文章了,今天分享一篇,使用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(['/gift/list','id'=>$lang->id]);?>">
    <i class="share icon"></i>送礼物
</button>

data-url代表用于获取礼物列表的路由,为按钮做一个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);
            }
        });
    });
})

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

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

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()];
    }
}

从这里我们知道现在点击按钮后获得的数据里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='{$gift.icon}'/></p>
                <p class="gift-name">{$gift.name}</p>
            </a>
        {/foreach}
        </p>
    </p>
</script>

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

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);
            }
        });
    });
})

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

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('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代码调用就变的简单了,如下

requirejs(['modules/gift'],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(['/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>

我们为每个礼物的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('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 width='120' src='"+d.qrcode+"'/>");
                }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件事情

  1. 生成送礼物日志

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

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

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

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

1.jpg

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

$('#payQrcode').html("<img width='120' src='"+d.qrcode+"'/>");

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

<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>
                点击左侧的小礼物后会出现支付二维码,扫码即送。
            </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['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,这样微信就不会再发请求。

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

3.jpg

不错不错

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

我需要一个轮询,那么开始吧,为此我在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 width='120' src='"+d.qrcode+"'/>");
    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()];
    }
}

大功告成,看看效果。

4.jpg

小结

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

相关推荐:

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

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

相关文章

微信app下载
微信app下载

微信是一款手机通信软件,支持通过手机网络发送语音短信、视频、图片和文字。微信可以单聊及群聊,还能根据地理位置找到附近的人,带给大家全新的移动沟通体验,有需要的小伙伴快来保存下载体验吧!

下载

相关标签:

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

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

46

2026.03.12

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

178

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

51

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

92

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

102

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

227

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

532

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

171

2026.03.04

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
第二十二期_综合实战
第二十二期_综合实战

共96课时 | 8.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号