公众号给用户发红包
场景:公众号里面,通过指定openid给用户发送红包,比如用户在公众号中提现,发福利红包都可以使用。
直接上代码:
class wxHongbao
{
// 商户id
private $mch_id = '********';
// 订单号
private $mch_billno = '';
// 公众号id
private $wxappid = '';
// 调用接口机器ip
private $client_ip = '';
// 商户平台密钥
private $apikey = '';
// 红包发放人数
private $total_num = 1;
// 红包发送者名称
private $send_name = '正义的程序猿';
// 祝福语
private $wishing = '欢迎再次参与';
// 活动名称
private $act_name = '';
// 备注
private $remark = '';
// 随机字符串
private $nonce_str = '';
// 接收用户的openid
private $re_openid = '';
//红包金额,单位 分
private $total_amount = 1;
// 签名
private $sign;
/**
* 活动信息
* @var array
*/
private $risk_info;
// 发放红包使用场景,红包金额大于200或者小于1元时必传
// PRODUCT_1:商品促销
// PRODUCT_2:抽奖
// PRODUCT_3:虚拟物品兑奖
// PRODUCT_4:企业内部福利
// PRODUCT_5:渠道分润
// PRODUCT_6:保险回馈
// PRODUCT_7:彩票派奖
// PRODUCT_8:税务刮奖
private $scene_id;
// 证书
private $apiclient_cert;
private $apiclient_key;
private $apiclient_ca;
private $api_hb_single = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
/**
* wxHongbao constructor.
*/
public function __construct()
{
// todo 初始化证书目录
$this->apiclient_cert = '';
$this->apiclient_key = '';
$this->apiclient_ca = '';
}
/**
* @return string
*/
public function getSendName()
{
return $this->send_name;
}
/**
* @param string $send_name
* @return $this
*/
public function setSendName($send_name)
{
$this->send_name = $send_name;
return $this;
}
/**
* @return string
*/
public function getWishing()
{
return $this->wishing;
}
/**
* @param string $wishing
* @return $this
*/
public function setWishing($wishing)
{
$this->wishing = $wishing;
return $this;
}
/**
* @return string
*/
public function getActName()
{
return $this->act_name;
}
/**
* @param string $act_name
* @return $this
*/
public function setActName($act_name)
{
$this->act_name = $act_name;
return $this;
}
/**
* @return string
*/
public function getRemark()
{
return $this->remark;
}
/**
* @param string $remark
* @return $this
*/
public function setRemark($remark)
{
$this->remark = $remark;
return $this;
}
/**
* @return string
*/
public function getReOpenid()
{
return $this->re_openid;
}
/**
* @param string $re_openid
* @return $this
*/
public function setReOpenid($re_openid)
{
$this->re_openid = $re_openid;
return $this;
}
/**
* @return int
*/
public function getTotalAmount()
{
return $this->total_amount;
}
/**
* 红包金额,单位 分
* @param int $total_amount
* @return $this
*/
public function setTotalAmount($total_amount)
{
$this->total_amount = (int)$total_amount;
return $this;
}
/**
* 创建红包
* @param $openid string
* @param $amount int 红包金额,单位分
* @return $this
*/
public function createHongbao($openid, $amount)
{
if (! $openid) {
throw new \InvalidArgumentException('openid error');
}
if ($amount <= 0) {
throw new \InvalidArgumentException('amount error');
}
$this->generate_nonce_str();
$this->generate_mch_billno();
$this->setReOpenid($openid);
$this->setTotalAmount($amount);
return $this;
}
/**
* 发送红包
* @return bool
*/
public function send()
{
$this->generate_sign();
$data = $this->generate_xml_params();
$data_obj = $this->https_request($this->api_hb_single, $data);
if ($data_obj->return_code === 'SUCCESS' && $data_obj->result_code === 'SUCCESS') {
$log = json_encode((array)$data_obj);
error_log(sprintf("[%s]\twx hongbao send success.\tmch_billno:%s\tret:%s", date("Y-m-d H:i:s"), $this->mch_billno, $log));
return true;
}
$log = json_encode((array)$data_obj);
error_log(sprintf("[%s]\twx hongbao send failed.\tmch_billno:%s\tret:%s", date("Y-m-d H:i:s"), $this->mch_billno, $log));
return false;
}
private function generate_xml_params()
{
$xml = "<xml>
<sign><![CDATA[{$this->sign}]]></sign>
<mch_billno><![CDATA[{$this->mch_billno}]]></mch_billno>
<mch_id><![CDATA[{$this->mch_id}]]></mch_id>
<wxappid><![CDATA[{$this->wxappid}]]></wxappid>
<send_name><![CDATA[{$this->send_name}]]></send_name>
<re_openid><![CDATA[{$this->re_openid}]]></re_openid>
<total_amount><![CDATA[{$this->total_amount}]]></total_amount>
<total_num><![CDATA[{$this->total_num}]]></total_num>
<wishing><![CDATA[{$this->wishing}]]></wishing>
<client_ip><![CDATA[{$this->client_ip}]]></client_ip>
<act_name><![CDATA[{$this->act_name}]]></act_name>
<remark><![CDATA[{$this->remark}]]></remark>
<nonce_str><![CDATA[{$this->nonce_str}]]></nonce_str>";
if ($this->scene_id) {
$xml .= "<scene_id><![CDATA[{$this->scene_id}]]></scene_id>";
}
if ($this->risk_info) {
$rsk = http_build_query($this->risk_info);
$rsk = urlencode($rsk);
$xml .= "<risk_info>{$rsk}</risk_info>";
}
$xml .= "</xml>";
return $xml;
}
// 生成签名
private function generate_sign()
{
$params = array(
'nonce_str' => $this->nonce_str,
'mch_billno'=> $this->mch_billno,
'mch_id' => $this->mch_id,
'wxappid' => $this->wxappid,
'send_name' => $this->send_name,
're_openid' => $this->re_openid,
'total_amount' => $this->total_amount,
'total_num' => $this->total_num,
'wishing' => $this->wishing,
'client_ip' => $this->client_ip,
'act_name' => $this->act_name,
'remark' => $this->remark
);
if ($this->scene_id) {
$params['scene_id'] = $this->scene_id;
}
if ($this->risk_info) {
$rsk = http_build_query($this->risk_info);
$params['risk_info'] = urlencode($rsk);
}
ksort($params);
$params['key'] = $this->apikey;
$s = http_build_query($params);
$this->sign = strtoupper(md5($s));
}
// 随机字符串
private function generate_nonce_str($length = 16)
{
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$chars_len = strlen($chars);
$str = '';
for ($i = 0; $i < $length; $i++) {
$str .= $chars[mt_rand(0, $chars_len - 1)];
}
$this->nonce_str = $str;
}
// 订单号
private function generate_mch_billno()
{
$s = substr($this->getReOpenid(), -4);
$this->mch_billno = date('YmdHis') . $s;
}
private function https_request($url, $data = null)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// curl_setopt($curl, CURLOPT_TIMEOUT, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_SSLCERT, $this->apiclient_cert);
curl_setopt($curl, CURLOPT_SSLKEY, $this->apiclient_key);
curl_setopt($curl, CURLOPT_CAINFO, $this->apiclient_ca);
if (!empty($data)){
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
$data = curl_exec($curl);
curl_close($curl);
return simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
}
}
代码中引入这个类,需要配置一下商户id$mch_id
,关联的公众号$wxappid
,服务器的公网ip$client_ip
,还有$apikey
,然后在构造函数中配置下证书,就能直接用了:
$hongbao = new wxHongbao();
$hongbao->createHongbao('xxxx', 100)->send();
Happy Coding~