<?php
//商户付款 到 个人
class mchPay
{
protected $key = 'c2a7d6411111111f1662e795'; //商户号API KEY
protected $appId = 'wxbb111111f5e5f04';
protected $mchid = '141111582';
protected $CertPem = BASE_ROOT_PATH.'/data/cert/apiclient_cert.pem'; //证书的位置 绝对路径
protected $KeyPem = BASE_ROOT_PATH.'/data/cert/apiclient_key.pem'; //证书的位置 绝对路径
/*
商户付款到 用户零钱
out_trade_no 外单订单号
openid 用户openid
total_fee 操作的金额
*/
public function payToChange($data)
{
$params = array();
$params['mch_appid'] = $this->appId;
$params['mchid'] = $this->mchid;
$params['nonce_str'] = $this->createNoncestr();
$params['partner_trade_no'] = $data['out_trade_no'];
$params['openid'] = $data['openid'];
$params['check_name'] = 'NO_CHECK';
$params['amount'] = $data['total_fee'];
$params['desc'] = '提现';
$params['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"];
$params['sign'] = $this->getSign($params);
$postXml = $this->arrayToXml($params);
$resXml = $this->postXmlCurl('https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers',$postXml,30,true);
$resData = $this->xmlToArray($resXml);
if(!$resData || $resData['return_code']!='SUCCESS' || $resData['result_code']!='SUCCESS') return false;
// var_dump($resData);
return $resData;
}
/*
商户付款到 用户银行卡
out_trade_no 外单订单号
total_fee 操作的金额
enc_bank_no 收款用户的银行卡号
enc_true_name 收款用户的姓名
bank_code 收款银行对应的编号 微信文档获取
*/
public function payToBank($data)
{
$params = array();
$params['mch_id'] = $this->mchid;
$params['nonce_str'] = $this->createNoncestr();
$params['partner_trade_no'] = $data['out_trade_no'];
$params['enc_bank_no'] = $data['enc_bank_no'];
$params['enc_true_name'] = $data['enc_true_name'];
$params['amount'] = $data['total_fee'];
$params['bank_code'] = $data['bank_code'];
$params['sign'] = $this->getSign($params);
$postXml = $this->arrayToXml($params);
$resXml = $this->postXmlCurl('https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank',$postXml,30);
$resData = $this->xmlToArray($resXml);
if(!$resData || $resData['return_code']!='SUCCESS' || $resData['result_code']!='SUCCESS') return false;
return $resData;
}
//作用:生成签名
private function getSign($Obj)
{
$Parameters = array();
foreach ($Obj as $k => $v) {
$Parameters[$k] = $v;
}
//签名步骤一:按字典序排序参数
ksort($Parameters);
$String = $this->formatBizQueryParaMap($Parameters, false);
//签名步骤二:在string后加入KEY
$String = $String . "&key=" . $this->key;
//签名步骤三:MD5加密
$String = md5($String);
//签名步骤四:所有字符转为大写
$result_ = strtoupper($String);
return $result_;
}
///作用:格式化参数,签名过程需要使用
private function formatBizQueryParaMap($paraMap, $urlencode)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v) {
if ($urlencode) {
$v = urlencode($v);
}
$buff .= $k . "=" . $v . "&";
}
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff) - 1);
}
return $reqPar;
}
//将数组转换为xml格式
private function arrayToXml($arr)
{
$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;
}
//xml转换成数组
private function xmlToArray($xml)
{
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
$val = json_decode(json_encode($xmlstring), true);
return $val;
}
//作用:产生随机字符串,不长于32位
private function createNoncestr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
//发送请求
private function postXmlCurl($url,$xml, $second = 30)
{
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
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);
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
//默认格式为PEM,可以注释
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, $this->CertPem);
//默认格式为PEM,可以注释
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY, $this->KeyPem);
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_TIMEOUT, 40);
set_time_limit(0);
//运行curl
$data = curl_exec($ch);
//返回结果
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
var_dump($error);
curl_close($ch);
return false;
}
}
}
//支付到用户零钱
$obj = new mchPay();
$params = array(
'out_trade_no' => date('YmdHis'),
'openid' => 'ouD2222222228',
'total_fee' => 100,
);
$res = $obj->payToChange($params);
?>
商户付款给用户是需要用到证书的,证书的申请在商户后台。一步步申请即可。还有就是如果一直报签名错误, 可以先到签名工具里对签名进行验证。 如果在签名工具里校验签名是正确的,那很有可能是api key的问题,重新在商户后台 ,设置一下api key,一般就可以正常了
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。