php实现微信企业号支付个人的方法详解


Posted in PHP onJuly 26, 2017

本文实例讲述了php实现微信企业号支付个人的方法。分享给大家供大家参考,具体如下:

导语:分销商,微商提现怎么提?

直接用微信支付。

实现如下:

微信支付配置

/*微信支付*/
  'PAY_WEIXIN'        => array(
    'appid'         => 'XXXX',
    'appsecret'       => 'XXXXXXX',
    'mchid'         => '1283301801',                        //商户号
    'key'          => 'zhudianbaodiandodozhudianbao0527',             //商户支付秘钥
    'apiclient_cert'    => 'Conf/cert/apiclient_cert.pem',               //商户证书apiclient_cert.pem
    'apiclient_key'     => 'Conf/cert/apiclient_key.pem',                //商户证书apiclient_key.pem
  )

arrayToXml

/**
* array转xml
*/
function arrayToXml($arr)
{
  $xml = "<xml>";
  foreach ($arr as $key=>$val)
  {
    if (is_numeric($val))
    {
        $xml.="<".$key.">".$val."</".$key.">";
    }
    else
    $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
  }
  $xml.="</xml>";
  return $xml;
}

使用证书,以post方式提交xml到对应的接口url

/**
*  作用:使用证书,以post方式提交xml到对应的接口url
*/
function postXmlSSLCurl($xml, $url, $second, $cert, $key)
{
    $ch = curl_init();
    //超时时间
    curl_setopt($ch,CURLOPT_TIMEOUT,$second ? $second : $this->timeout);
    //这里设置代理,如果有的话
    //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);
    //设置证书
    //使用证书:cert 与 key 分别属于两个.pem文件
    //默认格式为PEM,可以注释
    curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
    curl_setopt($ch,CURLOPT_SSLCERT,$cert);
    //默认格式为PEM,可以注释
    curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
    curl_setopt($ch,CURLOPT_SSLKEY, $key);
    //post提交方式
    curl_setopt($ch,CURLOPT_POST, true);
    curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
    $data = curl_exec($ch);
    //返回结果
    if($data){
      curl_close($ch);
      return $this->xmlToArray($data);
    }
    else {
      $error = curl_errno($ch);
      echo "curl出错,错误码:$error"."<br>";
      curl_close($ch);
      return false;
    }
}

企业向个人付款

//企业向个人付款
public function payToUser($params, $key, $apicent_cert, $apiclient_key) {
    $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
    //检测必填参数
    if($params["partner_trade_no"] == null) {  //
      exit("退款申请接口中,缺少必填参数partner_trade_no!"."<br>");
    }elseif($params["openid"] == null){
      exit("退款申请接口中,缺少必填参数openid!"."<br>");
    }elseif($params["check_name"] == null){       //NO_CHECK:不校验真实姓名 FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账)OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功)
      exit("退款申请接口中,缺少必填参数check_name!"."<br>");
    }elseif(($params["check_name"] == 'FORCE_CHECK' or $params["check_name"] == 'OPTION_CHECK') && ($params["re_user_name"] == null)){ //收款用户真实姓名。
      exit("退款申请接口中,缺少必填参数re_user_name!"."<br>");
    }elseif($params["amount"] == null){
      exit("退款申请接口中,缺少必填参数amount!"."<br>");
    }elseif($params["desc"] == null){
      exit("退款申请接口中,缺少必填参数desc!"."<br>");
    }
    $params["mch_appid"] = $this->appid;//公众账号ID
    $params["mchid"] = $this->mchid;//商户号
    $params["nonce_str"] = $this->createNoncestr();//随机字符串
    $params['spbill_create_ip'] = $_SERVER['REMOTE_ADDR'] == '::1' ? '192.127.1.1' : $_SERVER['REMOTE_ADDR'];//获取IP
    $params["sign"] = $this->getSign($params, $key);//签名
    $xml = $this->arrayToXml($params);
    return $this->postXmlSSLCurl($xml, $url, false, $apicent_cert, $apiclient_key);
}

企业付款

private function _enterprisePay($number, $member_id, $amount, $desc)
{
    // 获取openid
    $wxuser_id = M('Member')->where(array('id' => $member_id))->getField('wxuser_id');
    $openid  = M('Wxuser')->where(array('id' => $wxuser_id))->getField('openid');
    $pay = C('PAY_WEIXIN');
    import('@.Action.WxDevelop');
    $enterprise = new WxEnterprise($pay['appid'], $pay['appsecret'], $pay['mchid']);
    $params = array(
      'partner_trade_no' => $number,
      'openid' => $openid,
      'check_name' => 'NO_CHECK',
      'amount' => $amount, // 总计
      'desc' => $desc,
    );
    $result = $enterprise->payToUser($params, $pay['key'], $pay['apiclient_cert'], $pay['apiclient_key']);
    return $result;
}

处理分销商提现

private function _handle($truename, $price) { // 处理分销商提现
    $withdrawid = date("ymdHis") . strval(rand(1000, 9999));
    $data = array('withdrawid' => $withdrawid, 'store_id' => $this->store_id, 'member_id' => $this->member_id, 'truename' => $truename, 'price' => $price, 'addtime' => time());
    //免审核
    if ($price >= C('withdraw_uncheck_value')) {
      $data['need_check'] = 0;
      $data['status'] = 1;
      if ($this->withdrawModel->add($data)) {
        $result = $this->_enterprisePay($withdrawid, $this->member_id, $price * 100, '分销商(' . $truename . ')提现');
        //遇到支付信息出错,转为需审核提现
        if ($result['return_code'] != 'SUCCESS') {
          $this->withdrawModel->where(array('withdrawid' => $withdrawid))->save(array('need_check' => 1, 'status' => 0));
          $this->assign('success', 2);
        }
        else {
          //设置微信交易号
          $this->withdrawModel->where(array('withdrawid' => $withdrawid))->save(array('payment_no' => $result['payment_no']));
          //增加佣金流水,待修复
          $data = array('store_id' => $this->store_id, 'user_type' => 2, 'user_id' => $this->shop_id, 'trade_type' => 2, 'trade_no' => $withdrawid, 'price' => -$price, 'status'=> 1, 'message' => $truename.'提现', 'addtime' => time());
          M('Twitter_log')->add($data);
          //减少相应可提佣金
          M('Member')->where(array('id' => $this->member_id))->setInc('money', -$price);
          $this->assign('success', 1);
          //发送佣金变动消息
          import('@.Action.Tmplmsg');
          $tmplmsg = new Tmplmsg();
          $tmplmsg->send(Tmplmsg::PRICE_CHANGE, $this->member_id, array('token' => $this->token, 'intro' => '分销佣金提现转出', 'price' => $price, 'business' => BUSINESS));
        }
      }
      else {
        $this->error('提现信息错误!');
      }
    }
    //需要审核
    else {
      $this->withdrawModel->add($data);
      $this->assign('success' , 2);
    }
}

提供企业向用户付款的功能,支持企业通过API接口付款,或通过微信支付商户平台网页功能操作付款。

温馨提示:

◆ 给同一个实名用户付款,单笔单日限额2W/2W
◆ 给同一个非实名用户付款,单笔单日限额2000/2000
◆ 一个商户同一日付款总额限额100W
◆ 仅支持商户号已绑定的APPID;
◆ 针对付款的目标用户,已微信支付实名认证的用户可提供校验真实姓名的功能,未实名认证的用户无法校验,企业可根据自身业务的安全级别选择验证类型;
◆ 付款金额必须小于或等于商户当前可用余额的金额;
◆ 已付款的记录,企业可通过企业付款查询查看相应数据。

到账

付款资金将进入目标用户的零钱(微信-我-钱包-零钱)。微信支付将做零钱入账消息通知,零钱收支明细会展示相应记录。

温馨提示:

针对无零钱账户的历史客户端版本,资金将进入用户的红包账户,微信支付无消息通知用户,企业可选择自行触达用户。

接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers

是否需要证书
请求需要双向证书。

数据示例:

<xml>
<mch_appid>wxe062425f740c30d8</mch_appid>
<mchid>10000098</mchid>
<nonce_str>3PG2J4ILTKCH16CQ2502SI8ZNMTM67VS</nonce_str>
<partner_trade_no>100000982014120919616</partner_trade_no>
<openid>ohO4Gt7wVPxIT1A9GjFaMYMiZY1s</openid>
<check_name>OPTION_CHECK</check_name>
<re_user_name>张三</re_user_name>
<amount>100</amount>
<desc>节日快乐!</desc>
<spbill_create_ip>10.2.3.10</spbill_create_ip>
<sign>C97BDBACF37622775366F38B629F45E3</sign>
</xml>

成功示例:

<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[]]></return_msg>
<mch_appid><![CDATA[wxec38b8ff840bd989]]></mch_appid>
<mchid><![CDATA[10013274]]></mchid>
<device_info><![CDATA[]]></device_info>
<nonce_str><![CDATA[lxuDzMnRjpcXzxLx0q]]></nonce_str>
<result_code><![CDATA[SUCCESS]]></result_code>
<partner_trade_no><![CDATA[10013574201505191526582441]]></partner_trade_no>
<payment_no><![CDATA[1000018301201505190181489473]]></payment_no>
<payment_time><![CDATA[2015-05-19 15:26:59]]></payment_time>
</xml>

错误示例:

<xml>
<return_code><![CDATA[FAIL]]></return_code>
<return_msg><![CDATA[系统繁忙,请稍后再试.]]></return_msg>
<result_code><![CDATA[FAIL]]></result_code>
<err_code><![CDATA[SYSTEMERROR]]></err_code>
<err_code_des><![CDATA[系统繁忙,请稍后再试.]]></err_code_des>
</xml>

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP $_SERVER详解
Jan 16 PHP
PHP运行SVN命令显示某用户的文件更新记录的代码
Jan 03 PHP
让CodeIgniter数据库缓存自动过期的处理的方法
Jun 12 PHP
PHP比你想象的好得多
Nov 27 PHP
PHP魔术方法的使用示例
Jun 23 PHP
Linux系统中设置多版本PHP共存配合Nginx服务器使用
Dec 21 PHP
浅谈php和js中json的编码和解码
Oct 24 PHP
PHP之十六个魔术方法详细介绍
Nov 01 PHP
微信支付之JSAPI公众号支付详解
May 15 PHP
PHP defined()函数的使用图文详解
Jul 20 PHP
Laravel框架Blade模板简介及模板继承用法分析
Dec 03 PHP
php自动加载代码实例详解
Feb 26 PHP
PHP编程实现微信企业向用户付款的方法示例
Jul 26 #PHP
浅谈Yii乐观锁的使用及原理
Jul 25 #PHP
PHP异常处理定义与使用方法分析
Jul 25 #PHP
PHP实现防盗链的方法分析
Jul 25 #PHP
浅谈PHP发送HTTP请求的几种方式
Jul 25 #PHP
php 删除指定文件夹的实例讲解
Jul 25 #PHP
Laravel5.* 打印出执行的sql语句的方法
Jul 24 #PHP
You might like
使用PHP和XSL stylesheets转换XML文档
2006/10/09 PHP
利用js调用后台php进行数据处理原码
2006/10/09 PHP
重新封装zend_soap实现http连接安全认证的php代码
2011/01/12 PHP
PHP版本常用的排序算法汇总
2015/12/20 PHP
smarty高级特性之过滤器的使用方法
2015/12/25 PHP
PHP框架自动加载类文件原理详解
2017/06/06 PHP
JS关键字变色实现思路及代码
2013/02/21 Javascript
JQuery中serialize()、serializeArray()和param()方法示例介绍
2014/07/31 Javascript
一个JavaScript函数把URL参数解析成Json对象
2014/09/24 Javascript
jQuery实现防止提交按钮被双击的方法
2015/03/24 Javascript
window.location.reload 刷新使用分析(去对话框)
2015/11/11 Javascript
JavaScript中的闭包
2016/02/24 Javascript
全面解析Angular中$Apply()及$Digest()的区别
2016/08/04 Javascript
Bootstrap导航条学习使用(二)
2017/02/08 Javascript
Vue数组更新及过滤排序功能
2017/08/10 Javascript
js实现数组内数据的上移和下移的实例
2017/11/14 Javascript
详解Vue、element-ui、axios实现省市区三级联动
2019/05/07 Javascript
vue实现短信验证码登录功能(流程详解)
2019/12/10 Javascript
利用JS判断元素是否为数组的方法示例
2021/01/08 Javascript
[05:49]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS 选手采访
2021/03/11 DOTA
python正则表达式之对号入座篇
2018/07/24 Python
pandas中apply和transform方法的性能比较及区别介绍
2018/10/30 Python
PyQt5响应回车事件的方法
2019/06/25 Python
通过 Django Pagination 实现简单分页功能
2019/11/11 Python
django为Form生成的label标签添加class方式
2020/05/20 Python
html通过canvas转成base64的方法
2019/07/18 HTML / CSS
美国高档百货Nordstrom的折扣店:Nordstrom Rack
2017/11/13 全球购物
人力资源管理专业毕业生自荐书
2014/05/25 职场文书
2014乡党委副书记党建工作汇报材料
2014/11/02 职场文书
开展党的群众路线教育实践活动个人对照检查材料
2014/11/05 职场文书
2014年服务员个人工作总结
2014/12/23 职场文书
圣诞晚会主持词
2015/07/01 职场文书
小学教师暑期培训心得体会
2016/01/09 职场文书
五年级作文之劳动作文
2019/11/12 职场文书
python爬取新闻门户网站的示例
2021/04/25 Python
基于Redis实现分布式锁的方法(lua脚本版)
2021/05/12 Redis