小程序红包开发注意事项
2019-09-30 09:03:44 阅读:2884
前期准备:1.商户平台开通小程序红包功能。操作路径:【登录微信支付商户平台——>产品中心——>小程序红包——>开通】。开通要求:新申请商户号需满足:入驻时间超过90天、连续正常交易30天。2.下载API证书。微信商户平台所有牵扯资金流出的接口基本都需要带证书操作3.使用过程中确保商户平台资金充足4.获取用户openid。小程序红包只支持向指定openid发放指定金额红包5.红包参数设置。商户平台->产品中心->小程序红包->产品设置。此处可以设置红包使用场景及发放金额额度区间。(注:红包额度默认区间为1~200,如若使用更少0~1或者200元以上额度,需要申请审核)开发流程:1.服务器拿到用户openid,随机生成红包金额,通过调用发放红包接口获取红包参数2.前端请求获取到红包参数,调用领取红包接口,此时前端会弹出领取红包页面注意事项:若用户未领取,资金将会在24小时后退回商户的微信支付账户中。目前小程序红包仅支持用户微信扫码打开小程序,进行红包领取。(场景值1011,1025,1047,1124)开发源码:1.获取小程序进入场景值varoptions=wx.getLaunchOptionsSync();varscene=options.scene;2.在想要发放红包的接口处添加场景值参数,以方便后端能根据此参数值判断是否满足发送红包条件3.条件满足的前提下开始调用发放红包(此处我是先判断此用户是否存在发放记录,如有记录则不发放,如果需求没有要求每个用户只领一次则自己根据条件更改)4.根据上述请求返回的红包的参数调用领取接口即可小程序红包发放的接口返回存在多种可能情况,在状态码为正常,业务结果为失败情况下也有可能发放成功,具体的处理方式可以参考商户平台的文档。此处我是把所有异常的情况全都归为发放失败处理了。部分源码内容:
//获取红包方法
functiongetRedPacket($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;
}
functiongetNonceStr($length=32){
$chars="abcdefghijklmnopqrstuvwxyz0123456789";
$str="";
for($i=0;$i$v){
if($k!="sign"&&$v!=""&&!is_array($v)){
$buff.=$k."=".$v."&";
}
}
$buff=trim($buff,"&");
return$buff;
}
/**
*生成签名
*签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
*/
functionmakeSign($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;
}
functionpostXmlCurl($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;
}
}