微信公众号给用户发红包
注备材料
$wxParam = [ 'appid'=>'xxxxx',//微信分配的公众账号ID 'MerchantId'=>'xxxxx', //商户号 'key'=>'xxxxx', //商户支付密钥 ];
微信商户平台,开通现金红包

官方接口文档:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_1
需要的接口参数整理
//接口参数 $input=[ 'nonce_str' => $this->getNonceStr(), //随机字符串 'mch_billno' => $this->getMillisecond(), //商户订单号 'mch_id' => $wxParam['MerchantId'], //商户号 'wxappid' => $wxParam['appid'], //公众账号appid 'send_name' =>'娜网抽奖', //商户名称(可以不用与商户平台的商名称保持一至) 're_openid'=> $openid, //用户openid 'total_amount'=>100,//付款金额,单位分 'total_num'=>1,//红包发放总人数 'wishing'=>'恭喜抽中现金奖品',//红包祝福语 'client_ip'=>$_SERVER['REMOTE_ADDR'],//Ip地址 'act_name'=>'娜网抽奖',//活动名称 'remark'=>'娜网抽奖',//备注 'scene_id'=>'PRODUCT_2',//场景id ];
发送走起
//发红包-----
//主要就是这个方法,下面的都是一些数据处理,调用即可
public function wxHb(){
	
	//微信支付数据配置
	$wxParam = [
		'appid'=>'xxxxx',//微信分配的公众账号ID
		'MerchantId'=>'xxxxx', //商户号
		'key'=>'xxxxx', //商户支付密钥
	];
	
	//接口参数
	$input=[
		'nonce_str' => $this->getNonceStr(), //随机字符串
		'mch_billno' => $this->getMillisecond(), //商户订单号
		'mch_id' => $wxParam['MerchantId'], //商户号
		'wxappid' => $wxParam['appid'], //公众账号appid
		'send_name' =>'娜网抽奖', //商户名称(可以不用与商户平台的商名称保持一至)
		're_openid'=> 'ogLM16GM0QYwBYLX3IyrTBR3q5m0', //用户openid
		'total_amount'=>100,//付款金额,单位分
		'total_num'=>1,//红包发放总人数
		'wishing'=>'恭喜抽中现金奖品',//红包祝福语
		'client_ip'=>$_SERVER['REMOTE_ADDR'],//Ip地址
		'act_name'=>'娜网抽奖',//活动名称
		'remark'=>'娜网抽奖',//备注
		'scene_id'=>'PRODUCT_2',//场景id
	
	];
	
	$input['sign'] = $this->sign($input,$wxParam['key']); //签名
	$xmlData = $this->ToXml($input); //转为xml格式数据
	$postUrl = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack'; //微信发红包请求接口
	$res = $this->postXmlCurl($xmlData,$postUrl); //psot提交
	$res = $this->xmlToArr($res); //xml转数组
	
	//返回结果示例
	// array(11) {
	  // ["return_code"] => string(7) "SUCCESS"
	  // ["return_msg"] => string(12) "发放成功"
	  // ["result_code"] => string(7) "SUCCESS"
	  // ["err_code"] => string(7) "SUCCESS"
	  // ["err_code_des"] => string(12) "发放成功"
	  // ["mch_billno"] => string(13) "1671866123326"
	  // ["mch_id"] => string(10) "1628736250"
	  // ["wxappid"] => string(18) "wx5192ea5fd79ef1cf"
	  // ["re_openid"] => string(28) "ogLM16GM0QYwBYLX3IyrTBR3q5m0"
	  // ["total_amount"] => string(3) "100"
	  // ["send_listid"] => string(31) "1000041701202212243036834108445"
	// }
	
	debug($res);
}
//xml转数组
public function xmlToArr($xmlData){
	$xmlToaArr = simplexml_load_string($xmlData, 'SimpleXMLElement', LIBXML_NOCDATA); 
	$data = json_decode(json_encode($xmlToaArr),true);
	return $data;
}
//签名
public function sign($value,$key){
	//签名步骤一:按字典序排序参数
	ksort($value);
	//--格式化参数格式化成url参数
	$buff = "";
	foreach ($value as $k => $v)
	{
		if($k != "sign" && $v != "" && !is_array($v)){
			$buff .= $k . "=" . $v . "&";
		}
	}
	$buff = trim($buff, "&");
	$string = $buff;
	 
	//签名步骤二:在string后加入KEY
	$string =  $string . "&key=".$key;
	 
	//签名步骤三:MD5加密或者HMAC-SHA256
	//$string =hash_hmac("sha256",$string,$key);
	$string = md5($string);
	//签名步骤四:所有字符转为大写
	$result = strtoupper($string);
	 
	return $result;
}
/**
 * 输出xml字符
 * @throws WxPayException
**/
public function ToXml($value)
{
	if(!is_array($value) || count($value) <= 0)
	{
		throw new WxPayException("数组数据异常!");
	}
	 
	$xml = "<xml>";
	foreach ($value as $key=>$val)
	{
		if (is_numeric($val)){
			$xml.="<".$key.">".$val."</".$key.">";
		}else{
			$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
		}
	}
	$xml.="</xml>";
	return $xml; 
}
 
 
/*
 * 以post方式提交xml到对应的接口url
 *
 * @param string $xml  需要post的xml数据
 * @param string $url  url 提交的接口地址
 * @param int $second   url执行超时时间,默认30s
 * @throws WxPayException
*/
private static function postXmlCurl($xml, $url, $second = 30)
{
	$ch = curl_init();
	//$url = 'https://www.na-wang.com/index/index/test';
	
	
	curl_setopt($ch, CURLOPT_TIMEOUT, $second);//设置超时
	curl_setopt($ch,CURLOPT_URL, $url);  //指定URL
	curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); //忽略证书
	curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);//忽略证书
	curl_setopt($ch, CURLOPT_HEADER, FALSE); //忽略header头信息
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); //设定请求后返回结果
	 
	 
	//证书
	curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); //证书的类型。支持的格式有"PEM" (默认值), "DER"和"ENG"。
	curl_setopt($ch,CURLOPT_SSLCERT,'./cer/apiclient_cert.pem'); //客户端证书路径
	curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); //客户端私钥类型,支持的私钥类型为"PEM"(默认值)、"DER"和"ENG"。
	curl_setopt($ch,CURLOPT_SSLKEY,'./cer/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);
		debug($error);
		
	}
}
 
 
 
/**
 *
 * 产生随机字符串,不长于32位
 * @param int $length
 * @return 产生的随机字符串
 */
public static 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;
}
 
 
/**
 * 获取毫秒级别的时间戳
 */
private static function getMillisecond()
{
	//获取毫秒的时间戳
	$time = explode ( " ", microtime () );
	$time = $time[1] . ($time[0] * 1000);
	$time2 = explode( ".", $time );
	$time = $time2[0];
	return $time;
}红包接品需要用到证书
帐户中心-》app安全 申请,post的时候带上
//证书 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); //证书的类型。支持的格式有"PEM" (默认值), "DER"和"ENG"。 curl_setopt($ch,CURLOPT_SSLCERT,'./cer/apiclient_cert.pem'); //客户端证书路径 curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); //客户端私钥类型,支持的私钥类型为"PEM"(默认值)、"DER"和"ENG"。 curl_setopt($ch,CURLOPT_SSLKEY,'./cer/apiclient_key.pem'); //客户端私钥的文件路径
踩坑提示:
接口中的send_name参数,微信户名称可以自已随意改不需要与商户平台的保持一至,字符不要超过32字节,一个中文算3个字节,
这样报错了的就要看一下是不是超过32字节了
