一聚教程网:一个值得你收藏的教程网站

微信小程序实现红包功能(后端PHP实现逻辑)

时间:2018-07-11 20:17:28 编辑:猪哥 来源:转载

本文为大家分享了微信小程序红包功能的具体代码,供大家参考,具体内容如下

首先说明一点:微信小程序红包功能一定记得用企业付款到钱包功能,别用微信的现金红包接口,否则你就有踩不完的坑。

直接上代码了

微信小程序代码:

index.js

 //抢红包相关
 view_moneysure: function () {
  var that = this;
  wx.request({
   url: app.globalData.baseurl +'api/wxopen/applet/grab',//这个链接是后端写的 
   header: {
    'Content-Type': 'application/x-www-form-urlencoded'
   },
   data: {
    openid: app.globalData.openid,
    auth: app.globalData.pcUserInfo.auth
   },
   method: 'POST',
   success: function (response) {
    console.log(response);
    if (response.data.status==1){
     that.setData({
      paymsg: response.data.total_amount+'元\n现金红包',
      paymsg2: '恭喜您\n成功领取下单红包奖励'
     })
    }else{
     that.setData({
      paymsg: '领取失败\n'+response.data.msg,
      paymsg2: '非常抱歉\n如不不明,请联系客服'
     })
    }

   },
   fail: function (res) {
    console.log(response);
    that.setData({
     paymsg: '领取失败'
    })
   }
  })
 },
 showHb: function () {
  this.setData({
   showFlag: 1
  })
 },
 openHb: function () {
  this.setData({
   paymsg: '',
   paymsg2: ''
  })
  this.view_moneysure()
  var _self = this;
  _self.setData({
   _num: 1
  })
  setTimeout(function () {
   _self.setData({
    _num: 0,
    showFlag: 0,
    bghide: 1
   })
  }, 1000)

 },
 closeHb:function(){
  this.setData({
   bghide:0
  })
 },

wxml代码:

<button class="btn" bindtap="showHb">领红包</button>

<view class="draw-list {{showFlag == 1? 'active':''}}">
 <image bindtap="openHb" class="{{_num==1?'active':''}}" src="http://www.17sucai.com/preview/1/2017-11-02/hb/image/open.png"></image>
</view>

<view id="receive1" class="win1 {{bghide==1?'active':''}}">
  <view class="openhb {{bghide==1?'active':''}}">
    <view class="winBody2">
      <view class="receive1-bg1">
       <view class="receive1-head">
        <text>{{paymsg}}</text>
       </view>
       <view class="receive1-body"><text>{{paymsg2}}</text></view>
       <button class="receive1-but1" bindtap="closeHb">确定</button>
       <view class="receive1-bg2"></view>
     </view>
   </view>
  </view>
</view>

PHP代码:

/*
 * 企业付款到零钱
 **/
public function weixin_pay_person($re_openid)
{
  $obj = new WxopenWechatService();
  // 请求参数
  $data['mch_appid'] = WxopenWechatConfig::$init_config_applet['appid'];//商户号
  $data['mchid'] = WxopenWechatConfig::$compay_config['mch_id'];//商户账号appid
  $data['nonce_str'] = $this->get_unique_value();// 随机字符串
  //商户订单号,可以按要求自己组合28位的商户订单号
  $data['partner_trade_no'] = $this->get_tradeno($data['mchid']);
  $data['openid'] = $re_openid;//用户openid
  $data['check_name'] = 'NO_CHECK';//校验用户姓名选项
  $data['amount'] = '100';//金额,单位为分
  $data['desc'] = "恭喜你得到一个红包";//企业付款描述信息
  $data['spbill_create_ip'] = $obj->get_client_ip();//IP地址

  $appsecret = WxopenWechatConfig::$compay_config['key'];
  $data['sign'] = $this->sign($data, $appsecret);
  //发红包接口地址
  $url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";

  //将请求数据由数组转换成xml
  $xml = $this->arraytoxml($data);
  //进行请求操作
  $res = $this->curl($xml, $url);
  //将请求结果由xml转换成数组
  $arr = $this->xmltoarray($res);

  if (is_array($arr)) {
    $arr['total_amount'] = $data['amount'];
  }
  //请请求信息和请求结果录入到数据库中
  // 输出请求结果数组
  return $arr;
}

public function create_rand_money($start = 30, $end = 100)
{
  return mt_rand($start, $end);
}

public function sign($params, $appsecret)
{
  ksort($params);
  $beSign = array_filter($params, 'strlen');
  $pairs = array();
  foreach ($beSign as $k => $v) {
    $pairs[] = "$k=$v";
  }

  $sign_data = implode('&', $pairs);
  $sign_data .= '&key=' . $appsecret;
  return strtoupper(md5($sign_data));
}

/*
 * 生成32位唯一随机字符串
 **/
private
function get_unique_value()
{
  $str = uniqid(mt_rand(), 1);
  $str = sha1($str);
  return md5($str);
}

/*
 * 将数组转换成xml
 **/
private
function arraytoxml(
  $arr
) {
  $xml = "<xml>";
  foreach ($arr as $k => $v) {
    $xml .= "<" . $k . ">" . $v . "</" . $k . ">";
  }
  $xml .= "</xml>";
  return $xml;
}

/*
 * 将xml转换成数组
 **/
private
function xmltoarray(
  $xml
) {
  //禁止引用外部xml实体
  libxml_disable_entity_loader(true);
  $xmlstring = simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA);
  $arr = json_decode(json_encode($xmlstring), true);
  return $arr;
}

/*
 * 进行curl操作
 **/
private
function curl(
  $param = "", $url
) {
  $postUrl = $url;
  $curlPost = $param;
  //初始化curl
  $ch = curl_init();
  //抓取指定网页
  curl_setopt($ch, CURLOPT_URL, $postUrl);
  //设置header
  curl_setopt($ch, CURLOPT_HEADER, 0);
  //要求结果为字符串且输出到屏幕上
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  //post提交方式
  curl_setopt($ch, CURLOPT_POST, 1);
  // 增加 HTTP Header(头)里的字段
  curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
  // 终止从服务端进行验证
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

  //这个是证书的位置
  curl_setopt($ch, CURLOPT_SSLCERT, __DIR__ . '/cert/apiclient_cert.pem');
  //这个也是证书的位置
  curl_setopt($ch, CURLOPT_SSLKEY, __DIR__ . '/cert/apiclient_key.pem');
  //运行curl
  $data = curl_exec($ch);
  //关闭curl
  curl_close($ch);

  return $data;

}

public function get_tradeno($str)
{
  return $str . date("Ymd", time()) . date("His", time()) . rand(1111, 9999);
}

别人总结的相当宝贵的踩坑经验:

1、红包是以分为单位,必须大于100分,小于20000分之间。

2、用户无需关注你的公众号(或服务号,下同),如果关注了你的公众号,红包会通过公众号发送,如果没有,通过服务通知发送。

3、接口中的订单号由“微信支付商户号+4位年+2为月份+2位日期+10位一天内不能重复的数字”,这个一天是自然日。

4、目前不支持发送随机红包,因此接口中提交的字段min_value、max_value、total_amount这3个值大小必须一样,total_num值必须为1.

5、随机红包可以自己的程序实现,在100~20000随机出一个数值,然后给上面3个值设定这个随机结果。

6、活动名称看起来没用,注意高级红包接口和商户平台现金红包中的管理红包和创建红包无关,这两个地方是给手工发送红包使用的。

7、可选的4个参数,目前看来都没用,不要传。logo_imgurl, share_content, share_url, share_imgurl。

8、签名注意,值为空的不要参与签名。最后附加的key是微信支付的API密钥,不是公众平台的密钥,在商户平台->账户设置->安全设置->API安全右下角设置密钥中设置,第一次使用微信支付需要设置。

9、中文不需要UrlEncode,Hash输入是byte数组,用Encoding.UTF8.GetBytes来获取。

10、证书强烈建议不采用微信官方Demo文件访问形式证书,应该安装在系统证书存储容器中(在命令行输入certmgr可以查看),并设置为私钥不可以导出。

11、如果你采用10的方式,你很容易遇到无法找到证书的问题,要求运行程序windows账号有访问这个证书的权限。比如,如果双击运行的控制台程序,证书安装在当前用户的个人类别中,那么程序就可以访问证书。

  如果是IIS账户,你可能需要指定应用程序池的执行账号为指定账号,然后这个证书安装在这个账号下。

  微信官方Demo采用文件的访问形式,就不会有权限问题,但是要求你对证书文件保管好,以及证书密钥保管好。

文章评论

热门栏目