最近在做微信提现功能,查阅了官方文档和网上的的一些博文。最终实现了该功能,今天分享给大家,希望可以帮到有需要的朋友。
微信企业付款文档:[微信企业付款文档](https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 "微信企业付款文档")
####首先生成签名
```
/*
生成签名
@param $data 提现需要的一些基本参数
@return mixed
*/
function get_sign($data)
{
ksort($data);//排序
//使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串
$str='';
foreach($data as $k=>$v) {
$str.=$k.'='.$v.'&';
}
//拼接API密钥
$str .='key=HGd5lYrmoV8fSwCSms64gwgwqMgNlpkU';
$data['sign'] = md5($str);//加密
return $data;
}
```
####实现提现方法
```
/*
提现方法
*/
public function withdrawal()
{
//支付接口数据
$data = [
'mch_appid' => 'xxxxxxxxx', //商户账号appid
'mchid' => 'xxxxxxx', //商户号
'nonce_str' => md5(time()), //随机字符串,不长于32位
'partner_trade_no' => 'H'.time(),
'openid' => 'xxxxxxxxx', //用户openid (转账用户openid)
'check_name' => 'NO_CHECK', //
'amount' => 100, //付款金额,单位为分
'desc' => '核销', //付款操作说明信息
'spbill_create_ip' => '192.168.1.104'
];
//获取签名
$data = get_sign($data);
//将数组转成xml
$data = array_to_xml($data);
//发送提现请求。
$result = curl_post_ssl('https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers', $data, 30)
//将xml结果转为数组
$result = xml_to_array($result) ;
//返回结果
if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS' ) {
$bean_db->where($where)->setDec('bean', $post['bean']);
$json = ['status' => 1, 'msg' => '提现成功'];
} else {
$json = ['status' => 0, 'msg' => '请求超时'];
}
}
```
####发送提现请求:
发起提现请求之前,需要下载好商户证书。微信支付接口中,涉及资金回滚的接口会使用到商户证书,包括退款、撤销接口。
商家在申请微信支付成功后,收到的相应邮件后,可以按照指引下载API证书,也可以按照以下路径下载:微信商户平台(pay.weixin.qq.com)—>账户设置—>API安全—>证书下载。
证书文件有四个,分别说明如下:

####利用curl模拟post请求提现接口
```
/*
@param $url 微信提现接口
@param $vars xml格式的参数
@param int $second 最大执行时间
@param array $aHeader 标题
@return bool|mixed
*/
function curl_post_ssl($url, $vars, $second = 30, $aHeader = [])
{
$isdir = '/cert/'; //证书位置
$ch = curl_init();//初始化curl
curl_setopt($ch, CURLOPT_TIMEOUT, $second);//设置执行最长秒数
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_URL, $url);//抓取指定网页
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 终止从服务端进行验证
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');//证书类型
curl_setopt($ch, CURLOPT_SSLCERT, $isdir . 'apiclient_cert.pem');//证书位置
curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');//CURLOPT_SSLKEY中规定的私钥的加密类型
curl_setopt($ch, CURLOPT_SSLKEY, $isdir . 'apiclient_key.pem');//证书位置
curl_setopt($ch, CURLOPT_CAINFO, 'PEM');
curl_setopt($ch, CURLOPT_CAINFO, $isdir . 'rootca.pem');
if (count($aHeader) >= 1) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);//设置头部
}
curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);//全部数据使用HTTP协议中的"POST"操作来发送
$data = curl_exec($ch);//执行回话
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
echo "call faild, errorCode:$error\n";
curl_close($ch);
return false;
}
}
```
####数组转xml方法
```
/**
* 数组转xml
* @param $data
* @return string
*/
function array_to_xml($data){
$str='';
foreach($data as $k=>$v) {
$str.=''.$v.''.$k.'>';
}
$str.='';
return $str;
}
```
####xml转数组方法
```
/**
* xml转数组
* @param $xml
* @return mixed
*/
function xml_to_array($xml) {
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
$val = json_decode(json_encode($xmlstring),true);
return $val;
}
```