一、封装微信企业付款类WeiXinPayToUser,如下图代码所示:
class WeixinPayToUser
{
/**
* API 参数
* @var array
* 'mch_appid' # 公众号APPID
* 'mchid' # 商户号
* 'device_info' # 设备号
* 'nonce_str' # 随机字符串
* 'partner_trade_no' # 商户订单号
* 'openid' # 收款用户openid
* 'check_name' # 校验用户姓名选项 针对实名认证的用户
* 're_user_name' # 收款用户姓名
* 'amount' # 付款金额
* 'desc' # 企业付款描述信息
* 'spbill_create_ip' # Ip地址
* 'sign' # 签名
*/
public $parameters = [];
public $SSLROOTCA_PATH='';
public $SSLCERT_PATH='';
public $SSLKEY_PATH='';
public $appid='';
public $secret='';
public $mchid='';
public $key='';//商户密钥 public function __construct()
{ $this->url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
$this->curl_timeout = 10;
$this->SSLROOTCA_PATH=dirname(__FILE__).'/weixin/cert/rootca.pem';
$this->SSLCERT_PATH=dirname(__FILE__).'/weixin/cert/apiclient_cert.pem';
$this->SSLKEY_PATH=dirname(__FILE__).'/weixin/cert/apiclient_key.pem';
} public function setParameter($key,$value){
$this->parameters[$key]=$value;
} function arrayToXml($arr,$dom=0,$item=0){
if (!$dom){
$dom = new DOMDocument("1.0");
}
if(!$item){
$item = $dom->createElement("xml");
$dom->appendChild($item);
}
foreach ($arr as $key=>$val){
$itemx = $dom->createElement(is_string($key)?$key:"item");
$item->appendChild($itemx);
if (!is_array($val)){
$text = $dom->createTextNode($val);
$itemx->appendChild($text); }else {
$this->arrayToXml($val,$dom,$itemx);
}
}
$dom->encoding = 'UTF-8'; // insert proper
return $dom->saveXML();
} public function getSign($paramArr){//print_r($paramArr);
ksort($paramArr);
$paramStr = http_build_query($paramArr);
$paramStr=urldecode($paramStr);
$param_temp=$paramStr.'&key='.$this->key;//echo $param_temp.'<br>';
$signValue=strtoupper(md5($param_temp));//echo $signValue.'<br>';
return $signValue; } /**
* 生成请求xml数据
* @return string
*/
public function createXml()
{
$this->parameters['mch_appid'] = $this->appid;
$this->parameters['mchid'] = $this->mchid;
// $this->parameters['nonce_str'] = md5(time());
$this->parameters['nonce_str'] = 'dddfff';
$this->parameters['sign'] = $this->getSign($this->parameters);
$a= $this->arrayToXml($this->parameters);
//echo $a;
return $a;
} public function pay(){
$xml=$this->createXml();
$url=$this->url;
return $this->postXmlSSLCurl($xml,$url,$second=30);
} /**
* 作用:使用证书,以post方式提交xml到对应的接口url
*/
function postXmlSSLCurl($xml,$url,$second=30)
{ $ch = curl_init();
//超时时间
curl_setopt($ch,CURLOPT_TIMEOUT,$second);
//这里设置代理,如果有的话
//curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
//设置header
curl_setopt($ch,CURLOPT_HEADER,FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
//设置证书
//curl_setopt($ch,CURLOPT_CAINFO, $this->SSLROOTCA_PATH);
//使用证书:cert 与 key 分别属于两个.pem文件
//默认格式为PEM,可以注释
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, $this->SSLCERT_PATH);
//默认格式为PEM,可以注释
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY, $this->SSLKEY_PATH); //post提交方式
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
$data = curl_exec($ch);
//返回结果
if($data){
curl_close($ch);
return $data;
}
else {
$error = curl_errno($ch);
echo "curl出错,错误码:$error"."<br>";
echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
curl_close($ch);
return false;
}
} }
?>
二、调用WeiXinPayToUser,如下图所示:
/**
* 企业付款测试
*/
public function payToUser()
{ $mchPay = new WeiXinPayToUser();
// 用户openid
$mchPay->setParameter('openid', 'oy2lbszskklaslEKThrzqEziKEBzqU');
// 商户订单号
$mchPay->setParameter('partner_trade_no', 'test-'.time());
// 校验用户姓名选项
$mchPay->setParameter('check_name', 'NO_CHECK');
// 企业付款金额 单位为分
$mchPay->setParameter('amount', 100);
// 企业付款描述信息
$mchPay->setParameter('desc', '开发测试');
// 调用接口的机器IP地址 自定义
$mchPay->setParameter('spbill_create_ip', '127.0.0.1'); # getClientIp()
// 收款用户姓名
// $mchPay->setParameter('re_user_name', 'Max wen');
// 设备信息
// $mchPay->setParameter('device_info', 'dev_server'); $response = $mchPay->postXmlSSL();
if( !empty($response) ) {
$data = simplexml_load_string($response, null, LIBXML_NOCDATA);
echo json_encode($data);
}else{
echo json_encode( array('return_code' => 'FAIL', 'return_msg' => 'transfers_接口出错', 'return_ext' => array()) );
}
}
}