WeChat cash red envelope interface implements red envelope issuance:
1: Process: [
Process: WeChat users access the red envelope activity page--"The backend determines whether it is accessed by WeChat
[No: Prompt to use WeChat to open the connection, Yes: Prompt the user whether to authorize permission, obtain their user information [openID and other information]]--》
Enter the red envelope activity page--- 》The user clicks to receive the red envelope [Judge whether the red envelope has been received] Yes: [Prompt that the red envelope has been received] No
--》The back-end program calls the interface to issue the red envelope
--》WeChat user in Receive a red envelope in WeChat
--》Open the red envelope
--》The amount of the red envelope will be added to the wallet change
--》Complete the distribution of the red envelope.
】
2: To implement the WeChat cash red envelope interface to issue red envelopes, the following conditions must first be met:
1. The WeChat public account used to issue red envelopes must be of service type
2. After logging in to the official website of the WeChat official platform, on the public platform backend management page - Developer Center page,
click the "Modify Configuration" button and fill in the server address (URL), Token and EncodingAESKey ,
where URL is the interface URL used by developers to receive WeChat messages and events. Token can be filled in arbitrarily by the developer, and
is used to generate a signature (the Token will be compared with the Token contained in the interface URL to verify security).
EncodingAESKey is manually filled in by the developer or randomly generated, and will be used as the message body encryption and decryption key.
3. Obtain access_token: Official accounts can use AppID and AppSecret to call this interface to obtain access_token.
[AppID and AppSecret can be obtained from the official website of WeChat public platform - Developer Center page (you need to have become a developer, and the account has no abnormal status). 】
4. The WeChat public account must open a "webpage authorization interface" for users to obtain basic user information [especially openID, which is used when sending red envelopes]
5. The "WeChat payment" of the WeChat public account "Merchant number" in " To activate WeChat payment [the amount of red envelopes will be deducted from the payment account], open the "cash red envelope" interface [call this interface to issue red envelopes].
6. Log in to “Merchant Account” [the merchant account assigned by WeChat official account. There are instructions in Chapter 5] In "API Security", download the PHP version of the certificate [.pem format]
If the above description is not clear, please check the WeChat Developer Documentation which has detailed flash sales.
Part of the code is as follows [please see the attachment for the rest]:
<?php namespace RedClient\Controller; use Think\Controller; use RedClient\Redpack\WeiXinInfo; use RedClient\Redpack\Oauth; use RedClient\Redpack\SendRedPack; use RedClient\Redpack\CreateRedPack; class IndexController extends Controller { public function index() { $this->isWeixin();//是否是微信打开 if($this->access) { $this->display(); } else { $class=new Oauth(); $class->index('http://www.myweb.com/index.php/Index/oauth'); } } //获取用户信息 openID public function oauth() { $code=isset($_GET['code'])?strip_tags(trim($_GET['code'])):''; $state=isset($_GET['state'])?strip_tags(trim($_GET['state'])):''; $class=new Oauth(); $userInfo=$class->getCode($code,$state);//获取用户信息 if(!empty($userInfo['data'])) { //$model=M('wxuser'); //$result=$model->where('openid = "'.$userInfo['data']->openid.'"')->field('openid')->select(); if(empty($result)) { $userInfo['data']=$this->object2array($userInfo['data']); $model->data($userInfo['data'])->add(); } } $userInfo['data']=$this->object2array($userInfo['data']); //创建红包 $class=new CreateRedPack(); $red=$class->redval(); //发红包 $class=new SendRedPack(); $configs=array( 'send_name'=>'红包发送者名称',//红包发送者名称 're_openid'=>$userInfo['data']['openid'],//接受红包的用户,用户在wxappid下的openid 'total_amount'=>$red,//付款金额,单位分 'total_num'=>'1',//红包发放总人数 'wishing'=>'红包祝福语',//红包祝福语 'client_ip'=>$_SERVER['SERVER_ADDR'],//调用接口的机器Ip地址 'act_name'=>'活动名称',//活动名称 'remark'=>'备注信息',// 备注信息 ); $class->setFields($configs); $result=$class->requestXml(); //微信返回信息处理 if(strtoupper($result['return_code'])=='SUCCESS') { if(strtoupper($result['result_code'])=='SUCCESS') { //红包发送成功! $datas['flag']=1; echo $result['err_code_des']; } else { //红包发送失败 $datas['flag']=0; $datas['msg']=$result['err_code_des']; echo $result['err_code_des']; } } else { //红包发送失败 $datas['flag']=0; $datas['msg']=$result['err_code_des']; echo $result['err_code_des']; } } public function isWeixin() { if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false) { $this->access=true; } return false; } //类转换成数组 public function object2array($object) { if (is_object($object)) { foreach ($object as $key => $value) { $array[$key] = $value; } } else { $array = $object; } return $array; } } ?>
<?php namespace RedClient\Redpack; /** 简单红包算法类 **/ class CreateRedPack { private $rid=0;//当前红包随机数 private $rand_arr=array();//35%是1.0到1.1 红包随机数 private $rand_arr1=array();//35%是1.1到1.2 红包随机数 private $rand_arr2=array();//30%是1.2到1.95 红包随机数 private $red=0;//红包金额 private $simplered=0; private $red_config=array( array('min'=>1.0,'max'=>1.1), array('min'=>1.1,'max'=>1.2), array('min'=>1.2,'max'=>1.95) ); public function __construct() { $this->rid=mt_rand(1,10000);//当前红包随机数 $this->rand_arr=range(1,3500);//35%是1.0到1.1 $this->rand_arr1=range(3501,7000);//35%是1.1到1.2 $this->rand_arr2=range(7001,10000);//30%是1.2到1.95 $this->simplered=666; } public function redval() { $maxrp=$this->maxred();//随机最大红包金额 if($maxrp!=$this->simplered) { if(in_array($this->rid,$this->rand_arr)) { $red_val=$this->red_config[0]; $min=$red_val['min']*100; $max=$red_val['max']*100; $this->red=mt_rand($min,$max); $this->red=$this->red/100; } elseif(in_array($this->rid,$this->rand_arr1)) { $red_val=$this->red_config[1]; $min=$red_val['min']*100; $max=$red_val['max']*100; $red=mt_rand($min,$max); $this->red=$this->red/100; } elseif(in_array($this->rid,$this->rand_arr2)) { $red_val=$this->red_config[2]; $min=$red_val['min']*100; $max=$red_val['max']*100; $this->red=mt_rand($min,$max); $this->red=$this->red/100; } } else { $this->red=$maxrp; } return $this->red?$this->red:1; } protected function maxred() { $rid=mt_rand(1,100000); $rid1=mt_rand(1,100000); $red=0; $dff=$rid-$rid1; if($dff > 0) { if(($rid1%$rid1)==$this->simplered) { $red=$this->simplered; } } else { if(($rid1%$rid)==$this->simplered) { $red=$this->simplered; } } return $red; } } ?>
<?php namespace RedClient\Redpack; /********* 先在公共平台配置授权的域名; 然后才能通过, 网页授权方式获取微信用户基本信息 网页授权流程分为四步: 1.引导用户进入授权页面同意授权,获取code 2.通过code换取网页授权access_token(与基础支持中的access_token不同) 3.如果需要,开发者可以刷新网页授权access_token,避免过期 4.通过网页授权access_token和openid获取用户基本信息 **********/ class Oauth { protected $appid=''; protected $redirect_uri=''; protected $state='';//mt_rand(100,999); protected $appsecret=''; protected $data=array('flag'=>0,'msg'=>'','data'=>''); public function __construct() { $this->appid='appid';// $this->appsecret='secret';//; $this->state=mt_rand(100,999); } //引导用户访问链接处理函数 public function index($redirect_uri) { $this->redirect_uri=urlencode($redirect_uri);//微信自动跳转到$redirect_uri header('location:https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->appid.'&redirect_uri='.$this->redirect_uri.'/oauth.php&response_type=code&scope=snsapi_userinfo&state='.$this->state.'&connect_redirect=1#wechat_redirect'); } public function getCode($code='',$state='',$token='',$webToken='') { $data=array( 'errorno'=>'', 'errormsg'=>'', 'data'=>'' ); if(empty($code)) { $this->data['flag']=0; $this->data['msg']='授权失败!'; } else { /* 1获取webtoken 2获取reflash_token 3获取用户信息 */ $token_url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->appid.'&secret='.$this->appsecret.'&code='.$code.'&grant_type=authorization_code'; $token = json_decode(file_get_contents($token_url)); if (isset($token->errcode)) { $data['errorno']=$token->errcode; $data['errormsg']=$token->errmsg; } else { $access_token_url = 'https://api.weixin.qq.com/sns/oauth2/refresh_token?appid='.$this->appid.'&grant_type=refresh_token&refresh_token='.$token->refresh_token; //转成对象 $accessToken = json_decode(file_get_contents($access_token_url)); if (isset($accessToken->errcode)) { $data['errorno']=$token->errcode; $data['errormsg']=$token->errmsg; } else { $user_info_url = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$accessToken->access_token.'&openid='.$accessToken->openid.'&lang=zh_CN'; //转成对象 $userInfo = json_decode(file_get_contents($user_info_url)); if (isset($userInfo->errcode)) { $data['errorno']=$token->errcode; $data['errormsg']=$token->errmsg; } else { $data['data']=$userInfo; } } } } return $data; } } ?>
<?php /****** 用于企业向微信用户个人发现金红包 目前支持向指定微信用户的openid发放指定金额红包。 (获取openid参见微信公众平台开发者文档: 网页授权获取用户基本信息) ****/ namespace RedClient\Redpack; class SendRedPack { private $config=array( 'nonce_str'=>'',//随机字符串,不长于32位 'sign'=>'',//签名 'mch_billno'=>'',//商户订单号 'mch_id'=>'1111sdfsafsaddf',//微信支付分配的商户号 'wxappid'=>'sddafdsadfdsafdsdd',//微信分配的公众账号ID 'send_name'=>'',//红包发送者名称 're_openid'=>'',//接受红包的用户,用户在wxappid下的openid 'total_amount'=>'',//付款金额,单位分 'total_num'=>'',//红包发放总人数 'wishing'=>'',//红包祝福语 'client_ip'=>'',//调用接口的机器Ip地址 'act_name'=>'',//活动名称 'remark'=>'',// 备注信息 ); protected $key=''; protected $url='https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack'; protected $requestXml=''; //设置必要参数 public function setFields($conf=array()) { foreach($conf as $k=>$v) { if(isset($this->config[$k]) && !empty($v)) { $this->config[$k]=$v; } } $this->config['mch_billno']=$this->billno(); $this->config['nonce_str']=$this->createNonceStr(); $this->createSign($conf); $this->createXml(); //echo $this->requestXml; } protected function billno() { return $this->config['mch_id'].time().md5(mt_rand(1000,9999)); } /* //检查必要参数是否为空! public function checkConfig() { $flag=true; foreach($this->config as $k=>$v) { if(empty($v)) { $flag=false; break; } } } */ //随机字符串,不长于32位 public function createNonceStr( $len=32 ) { $strs = "abcdefghijklmnopqrstuvwxyz0123456789"; $str =""; $len=$len<=32?$len:32; for ( $i = 0; $i < $len; $i++ ) { $str.= substr($strs, mt_rand(0, strlen($strs)-1), 1); } return $str; } //格式化参数 public function formatParam($config=array(),$flag=1) { $format=''; if(!empty($config)) { ksort($config); foreach($config as $k=>$v) { if($flag) { $v=urlencode($v); } if($flag==0 && strtolower($k)=='sign') { continue; } $format.=$k.'='.$v.'&'; } $format=trim($format,'&'); } return $format; } //创建SIGNATURE protected function createSign($config) { $format=$this->formatParam($config,0); $format.='&key='.$this->key; $signature=strtoupper(md5($format)); $this->config['sign']=$signature; return true;//$signature; } //创建xml格式数据 protected function createXml() { $xml='<xml>'; foreach($this->config as $k=>$v) { if(!empty($v)) { $xml.='<'.$k.'><![CDATA['.$v.']]></'.$k.'>'; } } $xml.='</xml>'; $this->requestXml=$xml; } //XML格式数据转换为数组 public function createArray($xml='') { $arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $arr; } //发送红包 public function requestXml($timeout=30,$header=array()) { $ch = curl_init(); //超时时间 curl_setopt($ch,CURLOPT_TIMEOUT,$timeout); curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch,CURLOPT_URL,$this->url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false); //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLCERT,dirname(__FILE__).'/apiclient_cert.pem');//pem证书地址 //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEY,dirname(__FILE__).'/apiclient_key.pem');//key证书地址 curl_setopt($ch,CURLOPT_CAINFO,'PEM'); curl_setopt($ch,CURLOPT_CAINFO,dirname(__FILE__).'/rootca.pem');//CA证书地址 //两个文件合成一个.pem文件 //curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem'); if( count($header) >= 1 ) { curl_setopt($ch, CURLOPT_HTTPHEADER, $header); } curl_setopt($ch,CURLOPT_POST, 1); curl_setopt($ch,CURLOPT_POSTFIELDS,$this->requestXml); $data = curl_exec($ch); var_dump($data); if($data) { curl_close($ch); var_dump($data); return $data; } else { $error = curl_errno($ch); echo 'ERROR:'.$error; curl_close($ch); return false; } } //返回非空值,非NULL public function notEmpty($val='') { $return=''; if(null !=$val && strlen($val) != 0) { $return=$val; } return $return?$return:false; } } ?>
<?php namespace RedClient\Redpack; class WeiXinInfo { private $AppID='appid'; private $AppSecret='secret'; private $grant_type='client_credential'; private $url='https://api.weixin.qq.com/cgi-bin/token'; public function __construct() { //$arr=array('access_token'=>'1','expires'=>'7200'); } //设置获取ACCESSTOKEN 的URL public function setUrl() { return $this->url=$this->url.'?grant_type='.$this->grant_type.'&appid='.$this->AppID.'&secret='.$this->AppSecret; } //获取APPID,SECRET public function getAppid() { $sql='select appid,secret from ly_appid where flag=1'; $model=M(); $result=$model->query($sql); if(!empty($result)) { $this->AppID=$result[0]['appid']; $this->AppSecret=$result[0]['secret']; return $result[0]; } } public function object2array($object) { if (is_object($object)) { foreach ($object as $key => $value) { $array[$key] = $value; } } else { $array = $object; } return $array; } //检验URL有效 public function checkUrl() { $signature=isset($_GET['signature'])?strip_tags(trim($_GET['signature'])):''; $timestamp=isset($_GET['timestamp'])?strip_tags(trim($_GET['timestamp'])):''; $nonce=isset($_GET['nonce'])?strip_tags(trim($_GET['nonce'])):''; $echostr=isset($_GET['echostr'])?$_GET['echostr']:''; if(!empty($signature) && !empty($timestamp) && !empty($nonce)) { if($this->checkSign($signature,$timestamp,$nonce)) { echo $echostr; return true; } else { return false; } } } //验证SIGNATURE是否有效 private function checkSign($sign,$timestamp,$nonce) { $token=$this->getAccessToken(); //$token=$this->object2array($token); $sign_arr=array($token,$timstamp,$nonce); sort($sign_arr,SORT_STRING); $signStr=implode($sign_arr); $signStr=sha1($signStr); if(strtoupper($signStr)==strtoupper($sign)) { return true; } return false; } //通过微信接口获取微信Access_Token public function getAccessToken() { $token=''; $this->setUrl(); $check=$this->checkToken(); if(session('?'.md5('getaccesstoken')) && $check) { $tokens=session(md5('getaccesstoken')); $token=$tokens->access_token; } else { $result=file_get_contents($this->url); $result=json_decode($result); $token=$result->access_token; $result->expires_in=$result->expires_in+time(); session(md5('getaccesstoken'),$result); } return $token; } //检查微信ACCESS_TOKEN是否有效 public function checkToken() { if(session('?'.md5('getaccesstoken')) && session(md5('getaccesstoken'))) { $time=time(); $token=session(md5('getaccesstoken')); if($token->expires_in-$time > 30) { return true; } else { session(md5('getaccesstoken'),null); } } return false; } //保存微信ACCESSTOKEN到数据库 public function saveAccessToken() { $token=$this->getAccessToken(); $sql='select `id`,`rate`,token,ex_time,createtime from ly_token where token="'.$token.'" where appid="'.$this->AppID.'" AND secret="'.$this->AppSecret.'"'; $model=M(); $result=$model->query($sql); if(!empty($result)) { $time=time(); $expires=$time-$result[0]['createtime']; if($result[0]['ex_time']-$expires > 0) { return $result[0]['token']; } else { $token=$this->getAccessToken(); if(!empty($token)) { $token=json_decode($token); if(!isset($token['errcode']) or !$token['errcode']) { if(isset($token['access_token']) && $token['access_token']) { $data['access_token']=$token['access_token']; $data['createtime']=$time; $data['ex_time']=$token['expires_in']; $data['rate']=$result[0]['rate']+1; //$sql='update ly_token set token="'.$token['access_token'].'" ,createtime='.$time.',ex_time='.$token['expires_in'].' where `id`='.$result[0]['id']; $model=M('token'); $update=$model->where('`id`='.$result[0]['id'])->save($data); if($update) { return $token['access_token']; } } } else {//微信返回的错误信息 $data['errcode']=$token['errcode']; $data['errmsg']=$token['errmsg']; $data['appid']=$this->AppID; $data['secret']=$this->AppSecret; $data['createtime']=time(); $data['rate']=$result[0]['rate']+1; $ein=$model->where('`id`='.$result[0]['id'])->save($data); if($ein) { return false; } } } } } else {//新插入数据库保存 $token=$this->getAccessToken(); $model=M('token'); if(!empty($token)) { $data=array(); $token=json_decode($token); if(!isset($token['errcode']) or !$token['errcode']) { if(isset($token['access_token']) && $token['access_token']) { $data['access_token']=$token['access_token']; $data['createtime']=$time; $data['ex_time']=$token['expires_in']; //$sql='insert into ly_token() vlaues()'; $data['rate']=1; $in=$model->data($data)->add(); if($ein) { $token['access_token']; } } } else {//微信返回的错误信息 $data['errcode']=$token['errcode']; $data['errmsg']=$token['errmsg']; $data['appid']=$this->AppID; $data['secret']=$this->AppSecret; $data['createtime']=time(); $data['rate']=1; $ein=$model->data($data)->add(); if($ein) { return false; } } } } return false; } } ?>
The above is the detailed content of WeChat cash red envelope interface implements sample code sharing for red envelope issuance. For more information, please follow other related articles on the PHP Chinese website!