转载

微信开发 -- 企业付款 PHP代码实现

写这篇文章的目的主要是由于在微信公众平台提供的SDK中并没有提供此功能的SDK实现,

其实最后实现还是借助  微信公众平台开发文档 和 SDK 。

企业付款 的应用场景: 公众号向已关注用户付款,比如处理退款、财务结算等

先说一下实现思路:

在SDK中自带类库的基础上扩展WxMchPay组件, 实现企业付款功能的扩展。

话不多说,上代码, 下面是继承SDK,实现企业付款的组件:

$parameters参数参考: 企业付款API的文档

<?php // 引入SDK import('Common.Util.WxPay'); /**  * 微信企业付款操作类  * Author  :  Max.wen  * DateTime: <15/9/16 11:00>  */ class WxMchPay extends Wxpay_client_pub {  /**   * API 参数   * @var array   * 'mch_appid'   # 公众号APPID   * 'mchid'    # 商户号   * 'device_info'    # 设备号   * 'nonce_str'   # 随机字符串   * 'partner_trade_no'  # 商户订单号   * 'openid'   # 收款用户openid   * 'check_name'  # 校验用户姓名选项 针对实名认证的用户   * 're_user_name'   # 收款用户姓名   * 'amount'   # 付款金额   * 'desc'     # 企业付款描述信息   * 'spbill_create_ip'  # Ip地址   * 'sign'     # 签名   */  public $parameters = [];  public function __construct()  {   $this->url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';   $this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT;  }  /**   * 生成请求xml数据   * @return string   */  public function createXml()  {   $this->parameters['mch_appid'] = WxPayConf_pub::APPID;   $this->parameters['mchid']  = WxPayConf_pub::MCHID;   $this->parameters['nonce_str'] = $this->createNoncestr();   $this->parameters['sign']   = $this->getSign($this->parameters);   return $this->arrayToXml($this->parameters);  }  /**   *  作用:使用证书,以post方式提交xml到对应的接口url   */  function postXmlSSLCurl($xml,$url,$second=30)  {   $ch = curl_init();   //超时时间   curl_setopt($ch,CURLOPT_TIMEOUT,$second);   //这里设置代理,如果有的话   //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');   //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);   //设置header   curl_setopt($ch,CURLOPT_HEADER,FALSE);   //要求结果为字符串且输出到屏幕上   curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);   //设置证书   curl_setopt($ch,CURLOPT_CAINFO, WxPayConf_pub::SSLROOTCA_PATH);   //使用证书:cert 与 key 分别属于两个.pem文件   //默认格式为PEM,可以注释   curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');   curl_setopt($ch,CURLOPT_SSLCERT, WxPayConf_pub::SSLCERT_PATH);   //默认格式为PEM,可以注释   curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');   curl_setopt($ch,CURLOPT_SSLKEY, WxPayConf_pub::SSLKEY_PATH);   //post提交方式   curl_setopt($ch,CURLOPT_POST, true);   curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);   $data = curl_exec($ch);   //返回结果   if($data){    curl_close($ch);    return $data;   }   else {    $error = curl_errno($ch);    echo "curl出错,错误码:$error"."<br>";    echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";    curl_close($ch);    return false;   }  } } 

Controller层功能实现:

<?php /**  * Author  :  Max.wen  * DateTime: <15/9/20 16:47>  */ namespace Home/Controller; class TestController extends CommonController {  /**   * 企业付款测试   */  public function rebate()  {   import('Common.Util.WxMchPay');   $mchPay = new /WxMchPay();   // 用户openid   $mchPay->setParameter('openid', 'oy2lbszXkgvlEKThrzqEziKEBzqU');   // 商户订单号   $mchPay->setParameter('partner_trade_no', 'test-'.time());   // 校验用户姓名选项   $mchPay->setParameter('check_name', 'NO_CHECK');   // 企业付款金额  单位为分   $mchPay->setParameter('amount', 100);   // 企业付款描述信息   $mchPay->setParameter('desc', '开发测试');   // 调用接口的机器IP地址  自定义   $mchPay->setParameter('spbill_create_ip', '127.0.0.1'); # getClientIp()   // 收款用户姓名   // $mchPay->setParameter('re_user_name', 'Max wen');   // 设备信息   // $mchPay->setParameter('device_info', 'dev_server');   $response = $mchPay->postXmlSSL();   if( !empty($response) ) {    $data = simplexml_load_string($response, null, LIBXML_NOCDATA);    echo json_encode($data);   }else{    echo json_encode( array('return_code' => 'FAIL', 'return_msg' => 'transfers_接口出错', 'return_ext' => array()) );   }  } } 

完成上述两部分代码,基本就可以成功调用企业付款API了。

返回结果的数据结构示例:

{  "return_code": "SUCCESS",  "return_msg": { },  "mch_appid": "wx519cae424099ed6b",  "mchid": "1228636402",  "device_info": { },  "nonce_str": "qjupk84q4iqxkb578hb5h2qiatgcwxwg",  "result_code": "SUCCESS",  "partner_trade_no": "test-1442801966",  "payment_no": "1000018301201509210739170397",  "payment_time": "2015-09-21 10:19:26" }

可能遇到的问题:

1、CA证书错误

在WxMchPay中大家可以看到,我重写了SDK中 Wxpay_client_pub 的 postXmlSSLCurl()方法

因为默认在SDK中的这个方法在CURL POST请求的时候没有附带CA证书。

相比之下就多了 

curl_setopt($ch,CURLOPT_CAINFO, WxPayConf_pub::SSLROOTCA_PATH); 这么一行代码。

作用就是请求时附带CA证书。

2、 对同一用户转账操作过于频繁,请稍候重试.

这个错误属于微信服务端的限制,具体限制频率也没有找到那里有说明,不过经过实际测试大概在1分钟左右。

所以在开发的时候还需要多注意。


有任何疑问欢迎共同探讨。



P.S. 搬家至博客园的第一篇随笔, 送给组织的见面礼。希望再次广交猿友。
正文到此结束
Loading...