微信群抢小程序分享的红包

最近项目上线了一个小程序抢红包的迭代,其实小程序是目前是没有开放这个接口的,抢红包接口目前只对公众号开放,怎么实现的是不是大家很好奇呢?

首先,我们先来分析小程序抢红包功能的使用场景,在小程序里面微信付款,然后跳转到小程序红包分享页面,最后将该页面分享到微信群抢红包。

下图就是分享到微信群的小程序抢红包打开页面:

               

了解完使用场景之后,接下来是不是应该分析怎样去实现了?

我们先来理清这个使用流程,画一个简单的流程图来理解,能更清晰一点:

现在流程已经清楚了,我们再来分析分析抢红包这个看似简单的过程,可能会出现的问题(跟钱有关,得谨慎处理)?

分析来,分析去,除了支付和抢红包这两模块,其他的该怎样做还怎样做。

在这里先给大家填个坑,小程序虽然没有提供企业支付的sdk,但是你只需要明白一点,企业支付所需的openid只和当初申

请商户平台的appid有关,简单的说,就是小程序下申请的商户平台关联的openid也可完成企业支付。

(1)那就先来说说支付吧。就目前而言,微信支付已经做得很成熟了,有很多现成的第三方包,

直接集成到框架里面就可以用了【这里我啰嗦一句,集成的虽好,可不要贪杯澳】,有时间还是多研究研究官方的支付demo吧,这样在出现问题的时候才会如虎添翼。

 这里,我想说的重点不是这个,关于小程序支付参考一下微信支付就可以了,要注意微信支付在付款成功之后注意回调接口,付款成功不一定是真正的支付成功,有时候存在网络或者其他一些不可控因素导致不是真正的支付成功。

(2)接下来,再来说说抢红包这个问题吧。看似一个简单的问题,这里面涉及到并发性问题,通俗点讲,红包就那么几个,可是抢红包的人成百上千(手慢无澳)。

l 利用redis的原子操作,将多线程理论上变成单线程,redis列表(红包生成)+队列(支付、发通知)来解决这个问题,一起来看看这种方案的具体实现。

项目中我使用的laravel框架,这里就用laravel来举例吧?

1、在小程序之后成功之后(发红包的人已将红包个数已设置好了,这里的红包金额是随机的),这个时候就会生成已经设置好金额和个数的红包列表。

**
 *--------------------------------------------------------------------------
 * wechatPay [  微信支付,此处使用的是easywechat 4.*非官方包  ]
 *--------------------------------------------------------------------------
 * $config  小程序相关支付配置
 * @Author Docker
 *
 */
function wechatPay()
{   //小程序支付
    $wechatPay = Factory::payment($config);
    $result = $wechatPay->order->unify([
        'body' => '-红包充值',
        'out_trade_no' => $payment->out_trade_no,
        'total_fee' => $payment->total_fee, //单位:分
        'trade_type' => 'JSAPI',
        'openid' => $openid
    ]);

    $prepay_id = $result['prepay_id'];
    $result = $wechatPay->jssdk->bridgeConfig($result['prepay_id'], false);
    // 生成支付订单,订单状态为null 
    /* ........*/
}
/**
 *--------------------------------------------------------------------------
 * payCallBack [ 支付回调 ]
 *--------------------------------------------------------------------------
 * @Author Docker
 *
 * @return mixed
 */
function payCallBack()
{
    $wechatPay = Factory::payment($config);
    $response = $wechatPay->payment->handleNotify(
        function ($notify, $successful) {
            //使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
            $order = Payment::where('out_trade_no', $notify['out_trade_no'])->first();
            if (!$order  || $order->result_code === "SUCCESS") {
                return true;
            }
            if ($notify['return_code'] === 'SUCCESS') {
                $order->pay_time = Carbon::now()->toDayDateTimeString(); // 更新支付时间为当前时间
                $order->status = 'PAID'; //支付成功,
                $order->save();
               /* ***************************/
                //微信小程序支付成功后,生成红包
                $this->inRedPackets($order);
                /* ***************************/
            } else {
                $order->status = 'PAID_FAIL'; //待付款
                $order->save();
            }

            return true;
        });
    return $response;

}
 */
function inRedPackets($packet)
{
    //检查此红包是否已经生成红包记录
    if (Redis::exists('BOUNCE_GENERATOR_' . $packet->unique_id)) {
        return false;
    }
    $array = $this->generatePacket($packet->money, $packet->number, 100);
    shuffle($array);
    foreach ($array as $key => $value) {
        Redis::lpush('BOUNCE_GENERATOR_' . $packet->unique_id, $value);
    }
    return true;
}


/**
 *--------------------------------------------------------------------------
 * generatePacket [ 红包金额算法 ]
 *--------------------------------------------------------------------------
 * @Author Docker
 *
 * @param $total_money
 * @param $number
 * @param $per
 */
function generatePacket($total_money ,$number, $per)
{
    //不同红包类型,红包金额的生成方式不一样,此处使用随机生成
}

2、将红包转发到微信群之后,现在就开始抢红包,抢不完的24小时后退款,抢完了,给金主发小程序服务通知;

/**
 *--------------------------------------------------------------------------
 * grabRedPacket [ 抢红包并企业付款 ]
 *--------------------------------------------------------------------------
 * @Author Docker
 *
 * @param Request $request
 * @return string
 */
function grabRedPacket($packet)
{   //是否领取过红包(同一个群、同一个人、同一份红包)
        //  未领取过  查看是否已领取完  没领取过--抢红包
        //  领取过 【提醒已领取过】
    //显示该红包的领取记录

    //未领取过--现在开始使用redis
    $bounce_money = (int)(Redis::lpop('BOUNCE_GENERATOR_' . $packet->unique_id));
    //企业付款
    $job = (new \App\Jobs\Payment($bounce_money)->onQueue('PACKET.payment');
    dispatch($job); 

    //抢完红包后,给金主发小程序服务消息
    if (!Redis::exists('BOUNCE_GENERATOR_' . $packet->unique_id)) {
        $job = (new \App\Jobs\PacketDrawedOver($packet->unique_id, $this->getAccessToken()))->onQueue('pushMessageWx')->delay(2);//推迟两秒执行
        dispatch($job);
    }


}

/**
 *--------------------------------------------------------------------------
 * enterprisePay [ 企业付款队列 ]
 *--------------------------------------------------------------------------
 * @Author Docker
 *
 */
function enterprisePay()
{
    $config = [
        // 必要配置
        'app_id'             => 'xxxx',
        'mch_id'             => 'your-mch-id',
        'key'                => 'key-for-signature',   // API 密钥
        // 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书)
        'cert_path'          => '/path/to/your/cert.pem', // XXX: 绝对路径!!!!
        'key_path'           => '/path/to/your/key',      // XXX: 绝对路径!!!!
        // 将上面得到的公钥存放路径填写在这里
        'rsa_public_key_path' => '/path/to/your/rsa/publick/key/public-14339221228.pem', // <<<-----
        'notify_url'         => '默认的订单回调地址',     // 你也可以在下单时单独设置来想覆盖它
    ];

    $app = Factory::payment($config);
    $result =  $app->transfer->toBalance([
        'partner_trade_no' => '1233455', // 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有符号)
        'openid' => 'oxTWIuGaIt6gTKsQRLau2M0yL16E',
        'check_name' => 'FORCE_CHECK', // NO_CHECK:不校验真实姓名, FORCE_CHECK:强校验真实姓名
        //   're_user_name' => '王小帅', 如果 check_name 设置为FORCE_CHECK,则必填用户真实姓名
        'amount' => 10000, // 企业付款金额,单位为分
        'desc' => '理赔', // 企业付款操作说明信息。必填
    ]);
    if($response['result_code'] !== "SUCCESS") {
        return "你支付失败啦";
    }
    //生成一条红包领取记录,一条插入语句,省略...
    $packet_record = PacketRecord::create(企业付款相关数据);
    return "支付成功啦";
}
 

 
 

哎呀,终于说完了,主要看思路。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值