微信企业付款API接口使用
微信企业支付开发文档:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
企业付款业务是基于微信支付商户平台的资金管理能力,为了协助商户方便地实现企业向个人付款,针对部分有开发能力的商户,提供通过API完成企业付款的功能。
比如目前的保险行业向客户退保、给付、理赔。
企业付款将使用商户的可用余额,需确保可用余额充足。查看可用余额、充值、提现请登录商户平台“资金管理”进行操作。
下面是微信企业付款接口THINKPHP控制器,
C('WX_APPID'),C('WX_MCHID'),C('WX_KEYC') 这三项我已事先写在配置文件中了
<?php
/**
* 微信企业付款接口
*/
namespace Admin\Controller;
use Think\Controller;
class CompayController extends Controller {
protected $payurl = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
//这里的路径很重要 一定要写相对路径
protected $cacab = array(
'api_cert'=>'weixin/cert/apiclient_cert.pem',
'api_key'=>'weixin/cert/apiclient_key.pem',
'api_ca'=>'weixin/cert/rootca.pem',
);
//$data 要传递的参数, $wxchat微信企业支付等信息
/** $data 格式如下
* $data = array(
'userid' //申请退款者ID
'openid' //退款者openid
'refundid' //退款申请ID
'money' //退款金额
'desc' //退款描述
);
*
*/
public function wxbuild($data, $wxchat){
//判断有没有CA证书及支付信息
if(empty($wxchat['api_cert']) || empty($wxchat['api_key']) || empty($wxchat['api_ca']) || empty($wxchat['appid']) || empty($wxchat['mchid'])){
$wxchat['appid'] = C('WX_APPID'); //appid
$wxchat['mchid'] = C('WX_MCHID'); //商户号
$wxchat['api_cert'] = $this->cacab['api_cert'];
$wxchat['api_key'] = $this->cacab['api_key'];
$wxchat['api_ca'] = $this->cacab['api_ca'];
}
$webdata = array(
'mch_appid' => $wxchat['appid'],
'mchid' => $wxchat['mchid'],
'nonce_str' => md5(time()),
//'device_info' => '1000',
'partner_trade_no' => $data['bpno'], //商户订单号,需要唯一
'openid' => $data['openid'],
'check_name'=> 'NO_CHECK', //OPTION_CHECK不强制校验真实姓名, FORCE_CHECK:强制 NO_CHECK:
//'re_user_name' => 'jorsh', //收款人用户姓名
'amount' => $data['money'] * 100, //付款金额单位为分
'desc' => empty($data['desc'])? '微信提现' : $data['desc'],
'spbill_create_ip' => $this->getip(),
);
$sig = $this->makeSign($webdata);
foreach ($webdata as $k => $v) {
$tarr[] =$k.'='.$v;
}
sort($tarr);
$sign = implode($tarr, '&');
$sign .= '&key='.C('WX_KEYC'); //支付密钥
//$webdata['sign']=strtoupper(md5($sign));
$webdata['sign']= $sig;
$wget = $this->array2xml($webdata);
$content = $this->curl_post_ssl($this->payurl, $wget, $wxchat);
if(!$content){
return array('status'=>1, 'msg'=>"Can't connect the server" );
}
return $this->xmlToArray($content);
}
public function getip() {
static $ip = '';
$ip = $_SERVER['REMOTE_ADDR'];
if(isset($_SERVER['HTTP_CDN_SRC_IP'])) {
$ip = $_SERVER['HTTP_CDN_SRC_IP'];
} elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
foreach ($matches[0] AS $xip) {
if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) {
$ip = $xip;
break;
}
}
}
return $ip;
}
/**
* 将一个数组转换为 XML 结构的字符串
* @param array $arr 要转换的数组
* @param int $level 节点层级, 1 为 Root.
* @return string XML 结构的字符串
*/
public function array2xml($arr, $level = 1) {
$s = $level == 1 ? "<xml>" : '';
foreach($arr as $tagname => $value) {
if (is_numeric($tagname)) {
$tagname = $value['TagName'];
unset($value['TagName']);
}
if(!is_array($value)) {
$s .= "<{$tagname}>".(!is_numeric($value) ? '<![CDATA[' : '').$value.(!is_numeric($value) ? ']]>' : '')."</{$tagname}>";
} else {
$s .= "<{$tagname}>" . $this->array2xml($value, $level + 1)."</{$tagname}>";
}
}
$s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s);
return $level == 1 ? $s."</xml>" : $s;
}
/**
* 微信支付发起请求
*/
protected function curl_post_ssl($url, $xmldata,$wxchat, $second=30,$aHeader=array()){
$ch = curl_init();
//超时时间
curl_setopt($ch,CURLOPT_TIMEOUT,$second);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
//这里设置代理,如果有的话
//curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98');
//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,0);
curl_setopt($ch, CURLOPT_SSLVERSION, 1);
//默认格式为PEM,可以注释
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT,$wxchat['api_cert']);
//默认格式为PEM,可以注释
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY,$wxchat['api_key']);
//curl_setopt($ch,CURLOPT_CAINFO,$config['rootca']);
if( count($aHeader) >= 1 ){
curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
}
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$xmldata);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
$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转为array
public function xmlToArray($xml)
{
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $values;
}
/**
* 生成签名
* @return 签名,本函数不覆盖sign成员变量
*/
public function makeSign($data){
//获取微信支付秘钥
vendor('WxPayPubHelper.WxPayJsApiPay');
$key = \WxPayConfig::KEY;
// 去空
$data=array_filter($data);
//签名步骤一:按字典序排序参数
ksort($data);
$string_a=http_build_query($data);
$string_a=urldecode($string_a);
//签名步骤二:在string后加入KEY
//$config=$this->config;
$string_sign_temp=$string_a."&key=".$key;
//签名步骤三:MD5加密
$sign = md5($string_sign_temp);
// 签名步骤四:所有字符转为大写
$result=strtoupper($sign);
return $result;
}
//企业付款测试
public function test(){
$bpid = session('dpid');
//通过bpid查询提现信息
$balance = M('balance')->where('bpid ='.$bpid)->find();
//通过用户ID获取OPENID
$openid = M('userinfo')->where('uid ='.$balance['uid'])->getField('openid');
$username = M('userinfo')->where('uid ='.$balance['uid'])->getField('username');
$data = array(
'userid' => $balance['uid'], //用户ID 做更新状态使用
'openid' => $openid, //收钱的人微信 OPENID
'refundid' => $balance['bpid'], //提现申请IDbpno
'bpno' => $balance['bpno'], //提现申请ID
'money' => $balance['dzprice'], //金额
'desc' => '微信提现',
);
//var_dump($data);die;
$res = $this->wxbuild($data);
if ($res['result_code'] == "SUCCESS") {
//微信提现成功
$time = date("Y-m-d H:i:s");
$cltime = time();
M('balance')->where('bpid='.$bpid)->setField(array('isverified'=>'1','remarks'=>$time." 微信提现成功!",'cltime'=>$cltime));//1是同意
session('bpid',NULL);
$this->ajaxReturn("success");
}else{
$this->ajaxReturn("error");
}
}
}

浙公网安备 33010602011771号