当前位置: 旋风说(旋风PHPer分享网)> 技术文章> 正文
前期准备:
1. 商户平台开通小程序红包功能。操作路径:【登录微信支付商户平台——>产品中心——>小程序红包——>开通】。开通要求: 新申请商户号需满足:入驻时间超过90天、连续正常交易30天。
2. 下载API证书。微信商户平台所有牵扯资金流出的接口基本都需要带证书操作
3. 使用过程中确保商户平台资金充足
4. 获取用户openid。小程序红包只支持向指定openid发放指定金额红包
5. 红包参数设置。商户平台->产品中心->小程序红包->产品设置。此处可以设置红包使用场景及发放金额额度区间。(注:红包额度默认区间为1~200,如若使用更少0~1或者200元以上额度,需要申请审核)
开发流程:
1. 服务器拿到用户openid,随机生成红包金额,通过调用发放红包接口获取红包参数
2. 前端请求获取到红包参数,调用领取红包接口,此时前端会弹出领取红包页面
注意事项:若用户未领取,资金将会在24小时后退回商户的微信支付账户中。目前小程序红包仅支持用户微信扫码打开小程序,进行红包领取。(场景值1011,1025,1047,1124)
开发源码:
1. 获取小程序进入场景值
var options = wx.getLaunchOptionsSync();
var scene = options.scene;
2. 在想要发放红包的接口处添加场景值参数,以方便后端能根据此参数值判断是否满足发送红包条件
3. 条件满足的前提下开始调用发放红包(此处我是先判断此用户是否存在发放记录,如有记录则不发放,如果需求没有要求每个用户只领一次则自己根据条件更改)
4. 根据上述请求返回的红包的参数调用领取接口即可
小程序红包发放的接口返回存在多种可能情况,在状态码为正常,业务结果为失败情况下也有可能发放成功,具体的处理方式可以参考商户平台的文档。此处我是把所有异常的情况全都归为发放失败处理了。
部分源码内容:
//获取红包方法 function getRedPacket($openid){ //订单号 $order_no = date("YmdHis").rand(1000, 9999); $money = 1; //发放金额 可为1~200内随机数,如为其他金额需要申请 $data = [ "nonce_str"=>getNonceStr(), "mch_billno"=>$order_no, "mch_id"=>"商户号id", "wxappid"=>"公众平台id", "send_name"=>"发放名称", "re_openid"=>$openid, "total_amount"=>$money*100, "total_num"=>1, "wishing"=>"恭喜发财", "act_name"=>"新用户红包", "remark"=>"购买优惠多多", "notify_way"=>"MINI_PROGRAM_JSAPI", // "scene_id"=>"PRODUCT_1" //当金额不在1~200内时,场景值为必传值 ]; $data['sign'] = makeSign($data); //此处记录发放记录 pdo_insert("tiny_wmall_redpacket", [ "min_openid"=>$openid, "money"=>$money, "status"=>0, "create_time"=>time(), "order_no"=>$order_no ]); $post_xml = array2xml($data); $xml = postXmlCurl($post_xml, 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendminiprogramhb', true); $arr = xml2array($xml); $res = [ "code"=>0, "data"=>[], "msg"=>$xml ]; if($arr['return_code'] == "SUCCESS"){ if($arr["result_code"] == "SUCCESS"){ //业务结果成功,此次发放成功 $package = $arr['package']; //生成前端调用参数 $sign_data = [ "appId"=>$data["wxappid"], "timeStamp"=>(string)time(), "nonceStr"=>getNonceStr(), "package"=>urlencode($package) ]; $sign_data['paySign'] = makeSign($sign_data, 0); $sign_data["signType"] = "MD5"; $res['code']=1; $res['data']=$sign_data; //更新发放状态 // pdo_update("tiny_wmall_redpacket", ["status"=>1, "packet"=>$sign_data['package'], 'send_time'=>time()], ["order_no"=>$order_no]); }else{ //发放失败 // pdo_update("tiny_wmall_redpacket", ["status"=>-1], ["order_no"=>$order_no]); } }else{ //发放失败 //pdo_update("tiny_wmall_redpacket", ["status"=>-1], ["order_no"=>$order_no]); } return $res; } function getNonceStr($length=32){ $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str = ""; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } /** * 格式化参数格式化成url参数 */ function toUrlParams($data) { $buff = ""; foreach ($data as $k => $v) { if ($k != "sign" && $v != "" && !is_array($v)) { $buff .= $k . "=" . $v . "&"; } } $buff = trim($buff, "&"); return $buff; } /** * 生成签名 * 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值 */ function makeSign($data, $is_upper=1) { ksort($data); $string = toUrlParams($data); $string = $string . "&key="."23oqzgcin5jfjywvlto0aapmmmoq4kfk"; $string = md5($string); if($is_upper){ $result = strtoupper($string); }else{ $result = $string; } return $result; } function postXmlCurl($xml, $url, $useCert = false, $second = 30) { $ch = curl_init(); //设置超时 curl_setopt($ch, CURLOPT_TIMEOUT, $second); curl_setopt($ch, CURLOPT_URL, $url); if (stripos($url, "https://") !== FALSE) { curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); } else { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);//严格校验 } //设置header curl_setopt($ch, CURLOPT_HEADER, FALSE); //要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); if ($useCert == true) { //设置证书 //使用证书:cert 与 key 分别属于两个.pem文件 curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM'); curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM'); curl_setopt($ch, CURLOPT_SSLCERT, __DIR__.'/apiclient_cert.pem'); curl_setopt($ch, CURLOPT_SSLKEY, __DIR__.'/apiclient_key.pem'); } //post提交方式 curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); //运行curl $data = curl_exec($ch); //返回结果 if ($data) { curl_close($ch); return $data; } else { $error = curl_errno($ch); curl_close($ch); return $error; } }
当您发现内容错误或代码bug,以及下载链接无法使用等,请点击屏幕右下角的上报错误来进行提交,我们会尽快修正。
本程序所有源码和工具完全免费,当本网站内容如果侵犯了您的权益,请联系我们,我们会尽快处理,感谢您的合作。
上一篇: 号外号外,发现一个神奇的bug
下一篇: windows服务器时间老是变怎么办?
相关文章
评论:
文明上网理性发言,请遵守 新闻评论服务协议