微信支付之企业付款

企业付款业务是基于微信支付商户平台的资金管理能力,为了协助商户方便地实现企业向个人付款,针对部分有开发能力的商户,提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。

企业付款将使用商户的可用余额,需确保可用余额充足。查看可用余额、充值、提现请登录商户平台“资金管理”进行操作。https://pay.weixin.qq.com/ 
注意: 与商户微信支付收款资金并非同一账户,需要单独充值。企业付款需要证书。

说到代码实现,又不得不吐槽一下官方文档(https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2)和SDK(下载:https://pay.weixin.qq.com/wiki/doc/api/download/cert.zip)了,基本跟没有差不多,全靠程序猿自己摸索然后进行代码实现。

主要步骤:
(1)构造post请求的数据

这个,需要哪些参数可以参照文档:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2,我根据文档构造方法如下:

/**
 * 企业支付
 * @param string $openid 	用户openID
 * @param string $trade_no 	单号
 * @param string $money 	金额
 * @param string $desc 		描述
 * @return string 	XML 结构的字符串
 */
public function pay($openid,$trade_no,$money,$desc){
	$data = array(
		'mch_appid' => WxPayConfig::APPID,
		'mchid'     => WxPayConfig::MCHID,
		'nonce_str' => self::getNonceStr(),
		//'device_info' => '1000',
		'partner_trade_no' => $trade_no, //商户订单号,需要唯一
		'openid'    => $openid,
		'check_name'=> 'NO_CHECK', //OPTION_CHECK不强制校验真实姓名, FORCE_CHECK:强制 NO_CHECK:
		//'re_user_name' => 'jorsh', //收款人用户姓名
		'amount'    => $money * 100, //付款金额单位为分
		'desc'      => $desc,
		'spbill_create_ip' => self::getip()
	);
	
	//生成签名
	$data['sign'] = self::makeSign($data);
	//构造XML数据
	$xmldata = self::array2xml($data);
	$url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
	//发送post请求
	$res = self::curl_post_ssl($url, $xmldata);
	if(!$res){
		return array('status'=>1, 'msg'=>"Can't connect the server" );
	}
	// 这句file_put_contents是用来查看服务器返回的结果 测试完可以删除了
	file_put_contents(APP_ROOT.'/Api/wxpay/logs/log2.txt',$res,FILE_APPEND);
	
	//付款结果分析
	$content = self::xml2array($res);
	if(strval($content['return_code']) == 'FAIL'){
		return array('status'=>1, 'msg'=>strval($content['return_msg']));
	}
	if(strval($content['result_code']) == 'FAIL'){
		return array('status'=>1, 'msg'=>strval($content['err_code']),':'.strval($content['err_code_des']));
	}
	$resdata = array(
		'return_code'      => strval($content['return_code']),
		'result_code'      => strval($content['result_code']),
		'nonce_str'        => strval($content['nonce_str']),
		'partner_trade_no' => strval($content['partner_trade_no']),
		'payment_no'       => strval($content['payment_no']),
		'payment_time'     => strval($content['payment_time']),
	);
	return $resdata;
}

(2)发送数据请求

请求的curl函数,可以去官方下载:https://pay.weixin.qq.com/wiki/doc/api/download/cert.zip。下载完毕将证书改成自己的证书路径就可以了。
/**
 * 企业付款发起请求
 * 此函数来自:https://pay.weixin.qq.com/wiki/doc/api/download/cert.zip
 */
public function curl_post_ssl($url, $xmldata, $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,false);
	
	//以下两种方式需选择一种
	
	//第一种方法,cert 与 key 分别属于两个.pem文件
	//默认格式为PEM,可以注释
	curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
	curl_setopt($ch,CURLOPT_SSLCERT,WxPayConfig::SSLCERT_PATH);
	//默认格式为PEM,可以注释
	curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
	curl_setopt($ch,CURLOPT_SSLKEY,WxPayConfig::SSLKEY_PATH);
	
	//第二种方式,两个文件合成一个.pem文件
	//curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem');
 
	if( count($aHeader) >= 1 ){
		curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
	}
 
	curl_setopt($ch,CURLOPT_POST, 1);
	curl_setopt($ch,CURLOPT_POSTFIELDS,$xmldata);
	$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;
	}
}

我将完整的代码封装成了一个类,可以直接引入项目更改一下配置参数就可以使用的,也可以参看文章 微信支付之公众号发红包和企业付款,源码下载: http://download.csdn.net/detail/sinat_35861727/9858508 或者下载: http://download.csdn.net/download/sinat_35861727/9956485

调用就超级简单了,引入项目之后就直接调用:

//测试支付
public function test(){
	
	$openid = 'ovprvtzBZaWXnZUadwgexOLNc93M';
	$trade_no = date('YmdHis').mt_rand(1000,9999);
	$res = self::pay($openid,$trade_no,1,'提现');
	return $res;
}

//引入企业付款类
require_once APP_ROOT.'/Api/merchpay.class.php';
$merch = new \MerchPay();
$res = 	$merch->test();	
print_r($res);
支付失败时返回的数据:

<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[支付失败]]></return_msg>
<mch_appid><![CDATA[wx09e38d3dcca919a4]]></mch_appid>
<mchid><![CDATA[1314969701]]></mchid>
<result_code><![CDATA[FAIL]]></result_code>
<err_code><![CDATA[AMOUNT_LIMIT]]></err_code>
<err_code_des><![CDATA[付款金额超出限制。低于最小金额1.00元或累计超过20000.00元。]]></err_code_des>
</xml>
支付成功返回:

<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[]]></return_msg>
<nonce_str><![CDATA[kxm3zzlobtmb90rfodfejhug6qfosstl]]></nonce_str>
<result_code><![CDATA[SUCCESS]]></result_code>
<partner_trade_no><![CDATA[201706011750279780]]></partner_trade_no>
<payment_no><![CDATA[1000018301201706017928874552]]></payment_no>
<payment_time><![CDATA[2017-06-01 17:50:28]]></payment_time>
</xml>

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 26
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值