小程序营销利器,wx.sendBizRedPacket小程序红包完整详细开发代码,小程序中直接领取微信红包,无需任何资质

发布于 6 年前作者 duxiulan2557 次浏览最后编辑 6 年前来自 share

 今天给大家详细的讲讲微信的功能,小程序红包,直接在小程序里领取红包,无需额外代码,红包是调取微信原生的红包流程,红包金额直接进用户微信零钱里

   效果如下图

 

 

 

 

   **步骤1: 开通小程序红包权限**

 

   开通条件

1、即时入账且结算周期为T+1的商户,需满足1)入驻满90天,2)连续正常交易30天,3)保持正常健康交易。

2、其他结算周期的商户,暂无90/30天开通限制,但需保持正常健康交易。

3、商户选择开通权限的小程序未开通社交红包类目。

4、小程序主体不存在限制该功能使用的违规情况,包括但不限于:涉嫌欺诈,涉嫌违反相关法律法规等。

这个90/30天不清楚  ,反正我的是没程序开发差不多了就点击开通 直接可以开通,好像没到30天就行了.

在微信商户号->产品中心找到小程序红包,点击开通

开通后需要到产品设置里,按APPID开通商户号绑定的小程序的权限,这步很重要

  **步骤2:编写代码 **

 

  先讲一下程序逻辑

 

 1.像商户号里充值金额,有金额才能发红包

 2.以用户OPENID为基础生成一个红包,这个可以让客户在前端调取后台接口生成,然后在前端直接领取,如果提前有了用户OPENID也可以后台直接预先生成红包,用户在进入前端指定页面领取.   所以  这个有俩个流程   一个是生成红包,一个是领取红包   要调用俩次业务逻辑

废话不多说 下面附上代码  ,我这里是直接让客户在前端生成并直接领取红包

首先在想让客户领取红包的指定前端JS界面编写代码生成红包

onLoad: function (options) {

 if (!!options.scene) {

id = decodeURIComponent(options.scene)

 } else {

id = options.id

 }

 var that = this

  util.getauth().then(function (res) { 在自己写在Uitl里的方法,主要是获取用户openid
    if(res){
      var data = wx.getLaunchOptionsSync()//获取场景代码
      if (data.scene == 1047 || data.scene == 1011 || data.scene == 1025 || data.scene == 1124){
        that.getredpacket()
      }
    }

 })

},



//领取红包方法

getredpacket: function () {

var that = this

wx.showLoading({

title: '加载中~',

mask: true

})

wx.request({

url: getApp().globalData.url + 'detail/createredpacket',

method: 'POST',

header: {// 设置请求的 header  

'content-type': 'application/x-www-form-urlencoded'

},

data: {

orderid: id,

openid: getApp().globalData.openid

},

success: function (res) {


//这里是向服务器判断该页面是否有红包 ,如果有的话像服务器传用户OPENID,生成一个红包,这里可以先不用看下面代码,直接看服务器端代码 然后再回来看后面的代码

console.log(res.data)

wx.hideLoading()

if(res.data==2){

return

}

if (res.data.code == 1) {

console.log(res.data)

wx.sendBizRedPacket({

timeStamp: res.data.timeStamp, // 支付签名时间戳,

nonceStr: res.data.nonceStr, // 支付签名随机串,不长于 32 位

package: res.data.package, //扩展字段,由商户传入

signType: res.data.signType, // 签名方式,

paySign: res.data.paySign, // 支付签名

success: function (res) {

console.log(res)

},

fail: function (res) {

console.log(res)

},

complete: function (res) {

console.log(res)

}

})

} else {

//生成红包失败,提示错误码

wx.showToast({

title: res.data.msg,

icon: 'none'

})

}

},

fail: function (res) {

wx.showToast({

title: '请求失败',

})

},

})

},


服务器端代码  这里用的是PHP

//生成小程序红包方法
public function createredpacket(){ 
    $post = input('post.');
    if(db('order')->where('id',$post['orderid'])->value('isredpacket')==0){
        echo 2;
        die;

    }//这里是我自己程序的逻辑  判断这个订单是否开启红包,没有的话直接退出




    $setting =db('setting')->field('miniappid,appsecret,mch_id')->find();
    $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendminiprogramhb';//请求生成红包的网址
    $parameters = array(
        'nonce_str' => createNoncestr(), //随机字符串,不长于32位 这个方法就是随机获得32位随机字符
        'mch_billno' => '13513841535135153', //商户订单号
        'mch_id' => $setting['mch_id'], //随机字符串
        'wxappid' => $setting['miniappid'],//小程序appid,这里不用文档的公众号APPID,直接填你的小程序APPID就行
        'send_name' => '我是土豪',//红包发送者名称
        're_openid'=>$post['openid'],//用户OpenId
        'total_amount'=>1000,//付款金额,单位分
        'total_num'=>1,//红包发放总人数
        'wishing' => '祝您万事大吉',//红包祝福语String(128)
        'act_name' => '测试活动',//活动名称String(32)
        'remark'=>'恭喜你',//备注String(256)
        'notify_way' => 'MINI_PROGRAM_JSAPI',//通过JSAPI方式领取红包,小程序红包固定传MINI_PROGRAM_JSAPI
        'scene_id'=>'PRODUCT_1',
    );
    //统一下单签名
    $parameters['sign'] = getSign($parameters);
    $xmlData = arrayToXml($parameters);
    $return = xmlToArray(postXmlSSLCurl($xmlData,$url));
    if($return['return_code']=='FAIL'){
        $res['code']=0;
        $res['msg']=$return['return_msg'];
        echo json_encode($res);
        die;
    }
    if($return['result_code']=='FAIL'){
        $res['code']=0;
        $res['msg']=$return['return_msg'];
        echo json_encode($res);
        die;
    }
    if($return['return_code']=='SUCCESS'&&$return['result_code']=='SUCCESS'){
        $res = array(
            'appId'=>$setting['miniappid'],//应用ID
            'timeStamp' => time()."", //时间戳,必须为字符串,增加.""转为字符串,
            'nonceStr' => createNoncestr(), //随机字符串
            'package' => urlencode($return['package']), //红包详情的扩展
        );
        $res['paySign'] = $this->getSign($res);
        $res['signType'] ='MD5';
        $res['code'] = 1;
        echo json_encode($res);
    }else{
        $res['code']=0;
        $res['msg']='生成红包错误,请重试';
        echo json_encode($res);
    }
}

步骤3:开发时遇到的天坑,注意注意,重点重点:!!!

1.createNoncestr(),getSign,arrayToXml,xmlToArray,postXmlSSLCurl这几个方式是我集成的方法,开发微信支付的时候都会用的 感觉没必要写出来,不会的可以搜一搜微信支付的教程里面都有    这里的请求时需要商户号证书的哦

2.每个号测试的时候一天一个openID只能生成10个红包,怕测试失败  就把生成红包接口返回的$return[‘package’]保存起来   生成红包全靠他了

3.timeStamp’ => time().“”,  这个timeStamp必须是字符串,如果直接time(),用数字的话前端会报错请求不成功,而且wx.sendBizRedPacket()小程序的这个接口小程序开发文档里没有该接口文档,测试了下 FAIL回调方法里   不管什么错误   只会给你返回一个请求不成功,我就是没细心看文档被这个数字的时间戳搞死了  最后才发现是传的数字…

4.urlencode($return[‘package’])  这个是生成签名的时候就urlencode 

5.签名的时候看好参数,和其他的接口不一样不要按老经验来,这里是用appId,timeStamp,nonceStr,package这4个参数生成签名,没有signType 这个参数,返回前端您的时候确实不需要APPID,需要SIGNTYPE.

6.这里返回前端领取红包的签名最后不要转为大写哦,之前写错了   现在更正一下

7.wx.getLaunchOptionsSync()//获取场景代码   必须要用这个判断一下页面场景值,就是你通过什么方式进入的小程序,每个进入方法都有一个值,叫场景值.如果没有判断,那就是所有场景都生成红包,哈哈这下你会发现 红包是生成了 可是领不了.除非你把每个package都保存起来,或者不是和我一样直接生成待领取…要不你冲的那点钱根本不够用…好像没有撤回红包方法,乖乖等24小时后退回把

8.这个是最坑的一点,为什么写到最后,因为我也想让您们体验一下我的绝望…这个红包只在1011,1025,1047,1124这四个场景值中触发,不用查资料弄这4个场景值是啥意思了    现在我就可以负责人的告诉你,   只能手机用摄像头扫   不要和我一样妄想着把图片放朋友圈  别人长按识别就能领取了…你想到的方法我都试过了  一维码   二维码    小程序码   甚至一物一码   都只支持用摄像头扫,    长按和微信扫一扫在相册里扫都不行 都不触发…


结束语:第一眼看这个是营销炸弹般牛的功能,结果这个场景值砍了百分之90的营销力度…官方一句话其他场景暂不支持…期待把

__
__

__
__

第二次给前端使用的签名和第一次的不太一样,不需要转化大写  在这里补上

/作用:生成签名 
 function getSign($Obj) { 
  foreach ($Obj as $k => $v) { 
   $Parameters[$k] = $v
  
  //签名步骤一:按字典序排序参数 
  ksort($Parameters); 
  $String = $this->formatBizQueryParaMap($Parameters, false); 
  $mchkey = db('setting')->value('mch_key'); 
  //签名步骤二:在string后加入KEY 
  $String = $String . "&key=".$mchkey
  //签名步骤三:MD5加密 
  $String = md5($String); 
  return $String
 }
  
///作用:格式化参数,签名过程需要使用 
function formatBizQueryParaMap($paraMap, $urlencode) { 
 $buff = ""
 ksort($paraMap); 
 foreach ($paraMap as $k => $v) { 
  if ($urlencode) { 
   $v = urlencode($v); 
  
  $buff .= $k . "=" . $v . "&"
 

...

10 回复
tianmin
tianmin1 楼6 年前

这个红包的单位是可以自己定的吗?

vhe
vhe2 楼6 年前

大佬麻烦帮我看看我这哪里有问题啊

iding
iding3 楼6 年前

有没有现成的源码

taoxiuying
taoxiuying4 楼6 年前

我想问一下 这里sign签名和微信支付的签名是一样的吗?

WXPay wxpay = new WXPay(myWeixinConfig);
      //生成的随机字符串
      String nonce_str = WXPayUtil.generateNonceStr();
      //获取客户端的ip地址
      //获取本机的ip地址
      InetAddress addr = InetAddress.getLocalHost();
      String spbill_create_ip = addr.getHostAddress();
      //支付金额,需要转成字符串类型,否则后面的签名会失败
      int  total_fee = 1;
      //商品描述
      String body = "车费支付";
      //商户订单号
      String out_trade_no= WXPayUtil.generateNonceStr();
      //统一下单接口参数
      HashMap<String, String> data = new HashMap<String, String>();
      data.put("appid", myWeixinConfig.getAppID());
      data.put("mch_id", myWeixinConfig.getMchID());
      data.put("nonce_str", nonce_str);
      data.put("body", body);
      data.put("out_trade_no",out_trade_no);
      data.put("total_fee", String.valueOf(total_fee));
      data.put("spbill_create_ip", spbill_create_ip);
      data.put("notify_url", notify_url);
      data.put("trade_type", "JSAPI");
      data.put("openid", openid);
      try {
          Map<String, String> rMap = wxpay.unifiedOrder(data);
          System.out.println("统一下单接口返回: " + rMap);
          String return_code = (String) rMap.get("return_code");
          String result_code = (String) rMap.get("result_code");
          String nonceStr = WXPayUtil.generateNonceStr();
          Map resultMap = new HashMap();
          resultMap.put("nonceStr", nonceStr);
          Long timeStamp = System.currentTimeMillis() / 1000;
          if ("SUCCESS".equals(return_code) && return_code.equals(result_code)) {
              String prepayid = rMap.get("prepay_id");
              resultMap.put("package", "prepay_id="+prepayid);
              resultMap.put("signType", "MD5");
              //这边要将返回的时间戳转化成字符串,不然小程序端调用wx.requestPayment方法会报签名错误
              resultMap.put("timeStamp", timeStamp + "");
              //再次签名,这个签名用于小程序端调用wx.requesetPayment方法
              resultMap.put("appId",myWeixinConfig.getAppID());
              String sign = WXPayUtil.generateSignature(resultMap, myWeixinConfig.getKey());
              resultMap.put("paySign", sign);
              System.out.println("生成的签名paySign : "+ sign);
              //response.setData(resultMap);
              return null;
          }else{
              return  null;
          }
      } catch (Exception e) {
          e.printStackTrace();
          return  null;
      }
tao24
tao245 楼6 年前

结算商户是第三方公司的话,要对账该怎么办?

xiuyingliao
xiuyingliao6 楼6 年前

在吗?第二次签名是和第一次签名的区别是最后转大写的时候去掉吗

wantao
wantao7 楼6 年前

测试能领取红包,正式调不出来,有解决办法吗?

wei07
wei079 楼6 年前

这个是用公众号的OpenID发红包还是小程序的OpenID发红包???

xiaguo
xiaguo10 楼4 年前

我现在遇到的问题是  我商户平台开通小程序红包功能  产品设置里 授权小程序APPID也显示为开通  但是请求微信接口时 返回 该商户号未开通该现金红包功能(加入了小程序表示 MINI_PROGRAM_JSAPI),但是微信公众号就可以(取掉MINI_PROGRAM_JSAPI