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中的MVC模式运用技巧
May 03 PHP
防止MySQL注入或HTML表单滥用的PHP程序
Jan 21 PHP
php+mysql 实现身份验证代码
Mar 24 PHP
php邮件发送,php发送邮件的类
Mar 24 PHP
让PHP更快的提供文件下载的代码
Jun 13 PHP
php的POSIX 函数以及进程测试的深入分析
Jun 03 PHP
php中count获取多维数组长度的方法
Nov 03 PHP
CentOS安装php v8js教程
Feb 26 PHP
php动态生成版权所有信息的方法
Mar 24 PHP
在Mac OS上搭建Nginx+PHP+MySQL开发环境的教程
Dec 21 PHP
基于php中echo用逗号和用点号的区别详解
Jan 23 PHP
使用composer安装使用thinkphp6.0框架问题【视频教程】
Oct 01 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
discuz程序的PHP加密函数原理分析
2011/08/05 PHP
PHP封装分页函数实现文本分页和数字分页
2014/10/23 PHP
php字符比较函数similar_text、strnatcmp与strcasecmp用法分析
2014/11/18 PHP
Laravel 登录后清空COOKIE的操作方法
2019/10/14 PHP
PHP的Trait机制原理与用法分析
2019/10/18 PHP
HR vs ForZe BO3 第二场 2.13
2021/03/10 DOTA
javascript事件模型代码
2007/07/01 Javascript
简单常用的幻灯片播放实现代码
2013/09/25 Javascript
FF(火狐)浏览器无法执行window.close()解决方案
2014/11/13 Javascript
jQuery多文件异步上传带进度条实例代码
2016/08/16 Javascript
JS 动态加载js文件和css文件 同步/异步的两种简单方式
2016/09/23 Javascript
Node.js复制文件的方法示例
2016/12/29 Javascript
nodejs制作爬虫实现批量下载图片
2017/05/19 NodeJs
详解vue渲染从后台获取的json数据
2017/07/06 Javascript
Vue.js进行查询操作的实例详解
2017/08/25 Javascript
基于vue+canvas的excel-like组件实例详解
2017/11/28 Javascript
js捆绑TypeScript声明文件的方法教程
2018/04/13 Javascript
详解vue 计算属性与方法跟侦听器区别(面试考点)
2018/04/23 Javascript
jQuery实现ajax回调函数带入参数的方法示例
2018/06/26 jQuery
基于vue框架手写一个notify插件实现通知功能的方法
2019/03/31 Javascript
JS中的算法与数据结构之栈(Stack)实例详解
2019/08/20 Javascript
[01:18]一目了然!DOTA2DotA快捷操作对比第一弹
2014/07/01 DOTA
Python自动化运维和部署项目工具Fabric使用实例
2016/09/18 Python
python里 super类的工作原理详解
2019/06/19 Python
详解numpy.meshgrid()方法使用
2019/08/01 Python
Python中使用threading.Event协调线程的运行详解
2020/05/02 Python
HTML5里autofocus自动聚焦属性使用介绍
2016/06/22 HTML / CSS
美国顶级水上运动专业店:Marine Products
2018/04/15 全球购物
瑜伽国际:Yoga International
2018/04/18 全球购物
馥绿德雅美国官方网站:Rene Furterer头皮护理专家
2019/05/01 全球购物
电厂厂长岗位职责
2014/01/02 职场文书
自荐信的基本格式
2014/02/22 职场文书
促销活动总结模板
2014/07/01 职场文书
小城镇建设汇报材料
2014/08/16 职场文书
2014年行政助理工作总结
2014/11/19 职场文书
Mysql InnoDB 的内存逻辑架构
2022/05/06 MySQL