微信开发|现金红包接口

小编的公司之前为了吸引用户前来评论,在网站上增加了“微信现金红包”的功能,下面给大家分享一下教程。现金红包有两种,普通红包和裂变红包,下面教程是普通红包。

1.进入微信商户平台,开通“现金红包”功能;

2.下载API证书,证书包里有4个证书文件,这里PHP开发,用到apiclient_cert.pem和apiclient_key.pem两个证书文件;

3.发红包,首先要有钱,所以需先充值费用;

4.为了防止被盗刷,在微信商户平台可以设置相关的一些规则;

前期工作准备好了,下面进入主题。

WxPayJsApi.php(该类也包含了JSAPI支付和扫码支付):

// +----------------------------------------------------------------------
// | 微信支付统一接口
// | 1.JSAPI支付
// | 2.扫码支付
// +----------------------------------------------------------------------
// | 微信现金红包
// +----------------------------------------------------------------------
// | Copyright (c) 2017 http://www.lrfun.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: lrfun <admin@lrfun.com>
// +----------------------------------------------------------------------
// | Date: 2017-06-12
// +----------------------------------------------------------------------
 
Class WxPayJsApi{
	protected $appid;
    protected $mchid;
    protected $keys;
     
    function __construct(){
		$this->appid = "xxx";
        $this->mchid = "xxx";
        $this->keys  = "xxx";
    }
	
	/***
	 * 微信JSAPI支付
	 * @data 请求返回数据
	 * @return
	 **/
	public function jsapi($data){
		$data['trade_type'] = 'JSAPI';
		$result     = $this->unifiedorder($data);
		$jsApiData  = $this->getJsApiParameters($result);
		return $jsApiData;
	}
	
	/***
	 * 微信扫码支付
	 * @data 请求返回数据
	 * @return
	 **/
	public function native($data){
		$data['trade_type'] = 'NATIVE';
		$result = $this->unifiedorder($data);
		return $result;
	}
	
	/***
	 * 微信支付统一接口
	 * @data 请求参数
	 * @return
	 **/
	private function unifiedorder($data){
		$parameters = array();
		$parameters['appid']            = $this->appid;                  //公众账号ID
		$parameters['mch_id']           = $this->mchid;                  //商户号
		$parameters['nonce_str']        = $this->getNonceStr();          //随机字符串
		$parameters['body']             = $data['body'];                 //商品描述
		$parameters['out_trade_no']     = $this->mchid . date("YmdHis"); //商户订单号
		$parameters['total_fee']        = $data['total_fee'];            //标价金额(单位:分)
		$parameters['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"];       //终端IP
		$parameters['notify_url']       = 'http://www.lrfun.com/wxPayCallback.php'; //回调网址
		$parameters['trade_type']       = $data['trade_type'];           //支付类型:JSAPI,NATIVE,APP等
		$parameters['openid']           = $data['openid'];               //微信用户的openid(前面有发表过如何获取openid的文章,这里不多说了)
		$parameters['time_start']       = date("YmdHis");                //交易起始时间
		$parameters['time_expire']      = date("YmdHis", time() + 3600); //交易结束时间
		$parameters['attach']           = $data['orderId'];              //订单ID,用于支付成功后,更新订单状态
		$parameters['sign']             = $this->getSign($parameters);   //签名
		
		$queryXml   = $this->arrayToXml($parameters);
		$url        = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
		$returnData = $this->httpRequest($url, $queryXml);
		$result     = $this->xmlToArray($returnData);
		return $result;
	}
	
	/***
	 * 微信支付生成签名
	 * @parameters 签名数据
	 * @return 签名字符串
	 **/
	public function getSign($parameters){
		ksort($parameters);
		$parametersUrl = urldecode(http_build_query($parameters)) .'&key='. $this->keys;
		$sign = strtoupper(md5($parametersUrl));
		return $sign;
	}
	
	/***
	 * 数组转xml
	 * @arr 数组
	 * @return xml
	 **/
	private function arrayToXml($arr){
		if(!is_array($arr) || count($arr) <= 0){
			exit("数组数据异常!");
		}
		
		$xml = "<xml>";
		foreach ($arr as $key=>$val){
			if (is_numeric($val)){
				$xml.="<".$key.">".$val."</".$key.">";
			}else{
				$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
			}
		}
		$xml .= "</xml>";
		return $xml; 
	}
	
	/***
     * POST或GET请求
     * @url 请求url
     * @data POST数据
     * @return
     **/
	private function httpRequest($url, $data = ""){
		$curl = curl_init();
		curl_setopt($curl, CURLOPT_URL, $url);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
		if(!empty($data)){ //判断是否为POST请求
			curl_setopt($curl, CURLOPT_POST, 1);
			curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
		}
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		$output = curl_exec($curl);
		curl_close($curl);
		return $output;
	}
	
	/***
	 * XML转数组
     * @url XML
     * @return 数组
	 **/
	private function xmlToArray($xml){
		if(!$xml){
			echo "xml数据异常!";
			exit;
		}
        libxml_disable_entity_loader(true);
        $arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
		return $arr;
	}
	
	/***
	 * 获取jsapi支付参数
     * @data 请求微信返回的数据
     * @return JSON
	 **/
	private function getJsApiParameters($data){
		$timeStamp = time();
		$jsapi["appId"]     = $this->appid;
		$jsapi["nonceStr"]  = $this->getNonceStr();
		$jsapi["timeStamp"] = "$timeStamp";
		$jsapi["signType"]  = "MD5";
		$jsapi["package"]   = "prepay_id=".$data["prepay_id"];
		$jsapi["paySign"]   = $this->getSign($jsapi);
		$jsApiParameters    = json_encode($jsapi);
		return $jsApiParameters;
	}
	
	/***
	 * 支付成功回调函数
	 **/
	public function callback(){
		$callbackXml = file_get_contents('php://input');
		$data = json_decode(json_encode(simplexml_load_string($callbackXml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
		$callbackSign = $data['sign'];
		unset($data['sign']);
		$sign = $this->getSign($data);
		if($sign == $callbackSign){
			//这里更新你的订单状态
			//根据$data['attach']获取订单信息,更新订单状态
			$returnXml = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
			echo returnXml;
		}
	}
	
	/***
	 * 生成随机数
     * @length 随机字符串长度(默认32位)
     * @return
	 * */
	private 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;
	}
	
	
	/***
	 * 微信发送现金红包
	 * @data 请求参数
	 * @return
	 **/
	public function sendRedPack($data){
		$parameters = array();
		$parameters['wxappid']      = $this->appid;            //公众账号appid
		$parameters['mch_id']       = $this->mchid;            //商户号
		$parameters['nonce_str']    = $this->getNonceStr();    //随机字符串
		$parameters['mch_billno']   = $this->getNonceStr(28);  //商户订单号
		$parameters['send_name']    = "LiuR_Fun";               //商户名称
		$parameters['client_ip']    = $_SERVER["REMOTE_ADDR"]; //Ip地址
		$parameters['re_openid']    = $data['re_openid'];      //用户openid
		$parameters['total_amount'] = 100;                            //付款金额(单位:分;金额范围:1.00~200.00之间)
		$parameters['total_num']    = 1;                              //红包发放总人数
		$parameters['wishing']      = "感谢您的评价,祝您生活愉快!"; //红包祝福语
		$parameters['act_name']     = "评价赢红包";                   //活动名称
		$parameters['remark']       = "好评越多得越多,快来抢!";     //备注
		$parameters['sign']         = $this->getSign($parameters);    //签名
		
		$queryXml   = $this->arrayToXml($parameters);
		$url        = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack';
		$returnData = $this->curl_post_ssl($url, $queryXml);
		$result     = $this->xmlToArray($returnData);
		return $result;
	}
	
	/***
     * HTTP请求(带证书)
     * @url 请求url
     * @vars 请求数据
     * @second 超时时间
     * @aHeader 请求头部参数
     * @return
     * */
	private function curl_post_ssl($url, $vars, $second=30,$aHeader=array()){
		$curl = curl_init();
		//超时时间
		curl_setopt($curl, CURLOPT_TIMEOUT, $second);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		//这里设置代理,如果有的话
		//curl_setopt($curl, CURLOPT_PROXY, '10.206.30.98');
		//curl_setopt($curl, CURLOPT_PROXYPORT, 8080);
		curl_setopt($curl, CURLOPT_URL, $url);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
		
		//以下两种方式需选择一种
		//第一种方法,cert 与 key 分别属于两个.pem文件
		//默认格式为PEM,可以注释
		curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM');
		curl_setopt($curl, CURLOPT_SSLCERT, getcwd().'/apiclient_cert.pem');
		//默认格式为PEM,可以注释
		curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM');
		curl_setopt($curl, CURLOPT_SSLKEY ,getcwd().'/apiclient_key.pem');
		
		//第二种方式,两个文件合成一个.pem文件
		//curl_setopt($curl,CURLOPT_SSLCERT,getcwd().'/all.pem');
		
		if( count($aHeader) >= 1 ){
			curl_setopt($curl, CURLOPT_HTTPHEADER, $aHeader);
		}
		
		curl_setopt($curl, CURLOPT_POST, 1);
		curl_setopt($curl, CURLOPT_POSTFIELDS, $vars);
		$data = curl_exec($curl);
		if($data){
			curl_close($curl);
			return $data;
		} else {
			$error = curl_errno($curl);
			echo "call faild, errorCode:$error\n"; 
			curl_close($curl);
			return false;
		}
	}
}

调用代码sendRedPack.php:

header("Content-type: text/html; charset=utf-8");
require_once('WxPayJsApi.php');
$wxPayJsApi = new WxPayJsApi();
$data = array("re_openid" => "oSKzJvk9U8R8WmVo7ylk3b-frjuo");
$result = $wxPayJsApi->sendRedPack($data);
if($result['result_code'] == "SUCCESS"){
	echo "现金红包发送成功!";
}


欢迎转载,原文地址:http://www.lrfun.com/html/technology/PHP/2017/0922/126.html

上一篇:微信公众平台|模板消息群发功能
下一篇:PHP 微信公众号的基本配置token验证失败