映月读书网 > 微信公众平台开发:从零基础到ThinkPHP5高性能框架实践 > 17.6.1 普通红包 >

17.6.1 普通红包

微信普通红包是指发放红包时,一次只有一个用户的形式。

发放普通红包的接口如下。


https:// api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack
  

发放普通红包时,POST数据示例如下。


<xml>
    <sign><![CDATA[E1EE61A91C8E90F299DE6AE075D60A2D]]></sign>
    <mch_billno><![CDATA[0010010404201411170000046545]]></mch_billno>
    <mch_id><![CDATA[888]]></mch_id>
    <wxappid><![CDATA[wxcbda96de0b165486]]></wxappid>
    <send_name><![CDATA[send_name]]></send_name>
    <re_openid><![CDATA[onqOjjmM1tad-3ROpncN-yUfa6uI]]></re_openid>
    <total_amount><![CDATA[200]]></total_amount>
    <total_num><![CDATA[1]]></total_num>
    <wishing><![CDATA[恭喜发财]]></wishing>
    <client_ip><![CDATA[127.0.0.1]]></client_ip>
    <act_name><![CDATA[新年红包]]></act_name>
    <remark><![CDATA[新年红包]]></remark>
    <scene_id><![CDATA[PRODUCT_2]]></scene_id>
    <consume_mch_id><![CDATA[10000097]]></consume_mch_id>
    <nonce_str><![CDATA[50780e0cca98c8c8e814883e5caa672e]]></nonce_str>
    <risk_info>posttime%3d123123412%26clientversion%3d234134%26mobile%3d122344545%26
    deviceid%3dIOS</risk_info>
</xml>
  

同时,发送普通红包时需要带上文件证书,提高安全级别。

上述数据的参数说明如表17-6所示。

表17-6 发放普通红包接口的参数说明

正确创建时,返回的数据示例如下。


<xml>
    <return_code><![CDATA[SUCCESS]]></return_code>
    <return_msg><![CDATA[发放成功.]]></return_msg>
    <result_code><![CDATA[SUCCESS]]></result_code>
    <err_code><![CDATA[0]]></err_code>
    <err_code_des><![CDATA[发放成功.]]></err_code_des>
    <mch_billno><![CDATA[0010010404201411170000046545]]></mch_billno>
    <mch_id>10010404</mch_id>
    <wxappid><![CDATA[wx6fa7e3bab7e15415]]></wxappid>
    <re_openid><![CDATA[onqOjjmM1tad-3ROpncN-yUfa6uI]]></re_openid>
    <total_amount>1</total_amount>
</xml>
  

上述数据的参数说明如表17-7所示。

表17-7 发放普通红包接口返回参数说明

微信红包接口类的实现代码如下。


  1 class WxPay
  2 {
  3     var $appid = APPID;
  4     var $appsecret = APPSECRET;
  5 
  6     // 构造函数,获取Access Token
  7     public function __construct($appid = NULL, $appsecret = NULL)
  8     {
  9         if($appid && $appsecret){
 10             $this->appid = $appid;
 11             $this->appsecret = $appsecret;
 12 
 13             // 3. 本地写入
 14             $res = file_get_contents('access_token.json');
 15             $result = json_decode($res, true);
 16             $this->expires_time = $result["expires_time"];
 17             $this->access_token = $result["access_token"];
 18             if (time > ($this->expires_time + 3600)){
 19                 $url = "https:// api.weixin.qq.com/cgi-bin/token?grant_type=client_
                    credential&appid=".$this->appid."&secret=".$this->appsecret;
 20                 var_dump($url);
 21                 $res = $this->http_request($url, null, false);
 22                 $result = json_decode($res, true);
 23                 $this->access_token = $result["access_token"];
 24                 $this->expires_time = time;
 25                 file_put_contents('access_token.json', '{"access_token": "'.$this-
                    >access_token.'", "expires_time": '.$this->expires_time.'}');
 26             }
 27         }
 28     }
 29 
 30     // 发起支付请求
 31     function wxpay($url, $obj, $cert = false)
 32     {
 33         $obj['nonce_str'] = $this->create_noncestr;
 34         $stringA = $this->formatQueryParaMap($obj, false);
 35         $stringSignTemp = $stringA . "&key=" . PARTNERKEY;
 36         $sign = strtoupper(md5($stringSignTemp));
 37         $obj['sign'] = $sign;
 38         $postXml = $this->arrayToXml($obj);
 39         $responseXml = $this->http_request($url, $postXml, $cert);
 40         return $responseXml;
 41     }
 42 
 43     // 随机字符串
 44     function create_noncestr($length = 32)
 45     {
 46         $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 47         $str = "";
 48         for ( $i = 0; $i < $length; $i++ )  {
 49             $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
 50         }
 51         return $str;
 52     }
 53 
 54     // 格式化字符串
 55     function formatQueryParaMap($paraMap, $urlencode)
 56     {
 57         $buff = "";
 58         ksort($paraMap);
 59         foreach ($paraMap as $k => $v){
 60             if (null != $v && "null" != $v && "sign" != $k) {
 61                 if($urlencode){
 62                    $v = urlencode($v);
 63                 }
 64                 $buff .= $k . "=" . $v . "&";
 65             }
 66         }
 67         $reqPar;
 68         if (strlen($buff) > 0) {
 69             $reqPar = substr($buff, 0, strlen($buff)-1);
 70         }
 71         return $reqPar;
 72     }
 73 
 74     // 数组转XML
 75     function arrayToXml($arr)
 76     {
 77         $xml = "<xml>";
 78         foreach ($arr as $key=>$val)
 79         {
 80             if (is_numeric($val)){
 81                 $xml.="<".$key.">".$val."</".$key.">";
 82             }else{
 83                  $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
 84             }
 85         }
 86         $xml.="</xml>";
 87         return $xml;
 88     }
 89 
 90     // 将XML转为array
 91     function xmlToArray($xml)
 92     {    
 93         // 禁止引用外部XML实体
 94         libxml_disable_entity_loader(true);
 95         $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', 
            LIBXML_NOCDATA)), true);
 96         return $values;
 97     }
 98 
 99     // 带证书的POST请求
100     function http_request($url, $fields = null, $cert = true)
101     {
102         $ch = curl_init;
103         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
104         curl_setopt($ch, CURLOPT_URL, $url);
105         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,false);
106         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,false);
107         curl_setopt($ch, CURLOPT_SSLCERT, 'cert'.DIRECTORY_SEPARATOR.'apiclient_
            cert.pem');
108         curl_setopt($ch, CURLOPT_SSLKEY, 'cert'.DIRECTORY_SEPARATOR.'apiclient_
            key.pem');
109         curl_setopt($ch, CURLOPT_CAINFO, 'cert'.DIRECTORY_SEPARATOR.'rootca.pem');
110         if (!empty($fields)){
111             curl_setopt($ch, CURLOPT_POST, 1);
112             curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
113         }
114         $data = curl_exec($ch);
115         if(!$data){echo "CURL ErrorCode: ".curl_errno($ch);}
116         curl_close($ch);
117         return $data;
118     }
119 }
 

调用微信红包的方法如下。


 1 $money = 101;
 2 $sender = "方倍工作室";
 3 $obj = array;
 4 $obj['wxappid']         = APPID;
 5 $obj['mch_id']          = MCHID;
 6 $obj['mch_billno']      = MCHID.date('YmdHis').rand(1000, 9999);
 7 $obj['client_ip']       = $_SERVER['REMOTE_ADDR'];
 8 $obj['re_openid']       = $openid;
 9 $obj['total_amount']    = $money;
10 $obj['total_num']       = 1;
11 $obj['nick_name']       = $sender;
12 $obj['send_name']       = $sender;
13 $obj['wishing']         = "恭喜发财";
14 $obj['act_name']        = "猜灯谜抢红包";
15 $obj['remark']          = "猜越多得越多";
16 var_dump($obj);
17 $url = 'https:// api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack';
18 $wxHongBaoHelper = new WxPay;
19 $data = $wxHongBaoHelper->wxpay($url, $obj, true);
20 $res = $wxHongBaoHelper->xmlToArray($data);
21 var_dump($res);
  

执行上述代码后,用户将收到红包,效果如图17-9所示。

图17-9 微信支付普通红包