微信支付之企业付款

企业付款业务是基于微信支付商户平台的资金管理能力,为了协助商户方便地实现企业向个人付款,针对部分有开发能力的商户,提供通过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,我根据文档构造方法如下:

[php] view plain copy
  1. /** 
  2.  * 企业支付 
  3.  * @param string $openid    用户openID 
  4.  * @param string $trade_no  单号 
  5.  * @param string $money     金额 
  6.  * @param string $desc      描述 
  7.  * @return string   XML 结构的字符串 
  8.  */  
  9. public function pay($openid,$trade_no,$money,$desc){  
  10.     $data = array(  
  11.         'mch_appid' => WxPayConfig::APPID,  
  12.         'mchid'     => WxPayConfig::MCHID,  
  13.         'nonce_str' => self::getNonceStr(),  
  14.         //'device_info' => '1000',  
  15.         'partner_trade_no' => $trade_no//商户订单号,需要唯一  
  16.         'openid'    => $openid,  
  17.         'check_name'=> 'NO_CHECK'//OPTION_CHECK不强制校验真实姓名, FORCE_CHECK:强制 NO_CHECK:  
  18.         //'re_user_name' => 'jorsh', //收款人用户姓名  
  19.         'amount'    => $money * 100, //付款金额单位为分  
  20.         'desc'      => $desc,  
  21.         'spbill_create_ip' => self::getip()  
  22.     );  
  23.       
  24.     //生成签名  
  25.     $data['sign'] = self::makeSign($data);  
  26.     //构造XML数据  
  27.     $xmldata = self::array2xml($data);  
  28.     $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';  
  29.     //发送post请求  
  30.     $res = self::curl_post_ssl($url$xmldata);  
  31.     if(!$res){  
  32.         return array('status'=>1, 'msg'=>"Can't connect the server" );  
  33.     }  
  34.     // 这句file_put_contents是用来查看服务器返回的结果 测试完可以删除了  
  35.     file_put_contents(APP_ROOT.'/Api/wxpay/logs/log2.txt',$res,FILE_APPEND);  
  36.       
  37.     //付款结果分析  
  38.     $content = self::xml2array($res);  
  39.     if(strval($content['return_code']) == 'FAIL'){  
  40.         return array('status'=>1, 'msg'=>strval($content['return_msg']));  
  41.     }  
  42.     if(strval($content['result_code']) == 'FAIL'){  
  43.         return array('status'=>1, 'msg'=>strval($content['err_code']),':'.strval($content['err_code_des']));  
  44.     }  
  45.     $resdata = array(  
  46.         'return_code'      => strval($content['return_code']),  
  47.         'result_code'      => strval($content['result_code']),  
  48.         'nonce_str'        => strval($content['nonce_str']),  
  49.         'partner_trade_no' => strval($content['partner_trade_no']),  
  50.         'payment_no'       => strval($content['payment_no']),  
  51.         'payment_time'     => strval($content['payment_time']),  
  52.     );  
  53.     return $resdata;  
  54. }  

(2)发送数据请求请求的curl函数,可以去官方下载:https://pay.weixin.qq.com/wiki/doc/api/download/cert.zip。下载完毕将证书改成自己的证书路径就可以了。
[php] view plain copy
  1. /** 
  2.  * 企业付款发起请求 
  3.  * 此函数来自:https://pay.weixin.qq.com/wiki/doc/api/download/cert.zip 
  4.  */  
  5. public function curl_post_ssl($url$xmldata$second=30,$aHeader=array()){  
  6.     $ch = curl_init();  
  7.     //超时时间  
  8.     curl_setopt($ch,CURLOPT_TIMEOUT,$second);  
  9.     curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);  
  10.     //这里设置代理,如果有的话  
  11.     //curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98');  
  12.     //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);  
  13.     curl_setopt($ch,CURLOPT_URL,$url);  
  14.     curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);  
  15.     curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);  
  16.       
  17.     //以下两种方式需选择一种  
  18.       
  19.     //第一种方法,cert 与 key 分别属于两个.pem文件  
  20.     //默认格式为PEM,可以注释  
  21.     curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');  
  22.     curl_setopt($ch,CURLOPT_SSLCERT,WxPayConfig::SSLCERT_PATH);  
  23.     //默认格式为PEM,可以注释  
  24.     curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');  
  25.     curl_setopt($ch,CURLOPT_SSLKEY,WxPayConfig::SSLKEY_PATH);  
  26.       
  27.     //第二种方式,两个文件合成一个.pem文件  
  28.     //curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem');  
  29.    
  30.     ifcount($aHeader) >= 1 ){  
  31.         curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);  
  32.     }  
  33.    
  34.     curl_setopt($ch,CURLOPT_POST, 1);  
  35.     curl_setopt($ch,CURLOPT_POSTFIELDS,$xmldata);  
  36.     $data = curl_exec($ch);  
  37.     if($data){  
  38.         curl_close($ch);  
  39.         return $data;  
  40.     }  
  41.     else {   
  42.         $error = curl_errno($ch);  
  43.         echo "call faild, errorCode:$error\n";   
  44.         curl_close($ch);  
  45.         return false;  
  46.     }  
  47. }  

我将完整的代码封装成了一个类,可以直接引入项目更改一下配置参数就可以使用的,源码下载: http://download.csdn.net/detail/sinat_35861727/9858508

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

[php] view plain copy
  1. //测试支付  
  2. public function test(){  
  3.       
  4.     $openid = 'ovprvtzBZaWXnZUadwgexOLNc93M';  
  5.     $trade_no = date('YmdHis').mt_rand(1000,9999);  
  6.     $res = self::pay($openid,$trade_no,1,'提现');  
  7.     return $res;  
  8. }  
[php] view plain copy
  1. //引入企业付款类  
  2. require_once APP_ROOT.'/Api/merchpay.class.php';  
  3. $merch = new \MerchPay();  
  4. $res =  $merch->test();    
  5. print_r($res);  
支付失败时返回的数据:
[html] view plain copy
  1. <xml>  
  2. <return_code>return_code>  
  3. <return_msg>return_msg>  
  4. <mch_appid>mch_appid>  
  5. <mchid>mchid>  
  6. <result_code>result_code>  
  7. <err_code>err_code>  
  8. <err_code_des>err_code_des>  
  9. xml>  
支付成功返回:
[html] view plain copy
  1. <xml>  
  2. <return_code>return_code>  
  3. <return_msg>return_msg>  
  4. <nonce_str>nonce_str>  
  5. <result_code>result_code>  
  6. <partner_trade_no>partner_trade_no>  
  7. <payment_no>payment_no>  
  8. <payment_time>payment_time>  
  9. xml>  
微信支付之企业付款_第1张图片

你可能感兴趣的:(php)