今天给大家详细的讲讲微信的功能,小程序红包,直接在小程序里领取红包,无需额外代码,红包是调取微信原生的红包流程,红包金额直接进用户微信零钱里
效果如下图
**步骤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 }
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 . "&" ; } $reqPar ; if ( strlen ( $buff ) > 0) { $reqPar = substr ( $buff , 0, strlen ( $buff ) - 1); } return $reqPar ; } |