php实现微信企业转账功能


Posted in PHP onOctober 02, 2018

本文实例为大家分享了php实现微信企业转账的具体代码,供大家参考,具体内容如下

<?php 
/** 
* 配置账号信息 
* 配置要和证书在一起!!!! 
*/ 
 
class WxTransfersConfig 
{ 
 //=======【基本信息设置】==============
 // 
 /** 
  * TODO: 修改这里配置为您自己申请的商户信息 
  * 微信公众号信息配置 
  * 
  * APPID:绑定支付的APPID(必须配置,开户邮件中可查看) 
  * 
  * MCHID:商户号(必须配置,开户邮件中可查看) 
  * 
  * KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置) 
  * 设置地址:https://pay.weixin.qq.com/index.php/account/api_cert 
  * 
  */ 
 const APPID = ''; 
 const MCHID = ''; 
 const KEY = ''; 
 //=======【证书路径设置】===================================== 
 /** 
  * TODO:设置商户证书路径 
  * 证书路径,注意应该填写绝对路径,发送红包和查询需要,可登录商户平台下载 
  * API证书下载地址:https://pay.weixin.qq.com/index.php/account/api_cert,下载之前需要安装商户操作证书) 
  * @var path 跟这个文件同一目录下的cert文件夹放置证书!!!! 
  */ 
 const SSLCRET12 = 'cert/apiclient_cert.p12'; 
 const SSLCERT_PATH = 'cert/apiclient_cert.pem'; 
 const SSLKEY_PATH = 'cert/apiclient_key.pem'; 
 const SSLROOTCA = 'cert/rootca.pem'; 
  
 //=======【证书路径设置】===================================== 
 /** 
  * 获取文件的路径,证书需要完整路径 
  * @return string 
  */ 
 public static function getRealPath(){ 
  return __DIR__.'/'; 
 } 
}

微信企业转账工具类:

<?php 
require_once "WxTransfers.Config.php"; 
 
/** 
 * 微信企业转账工具类 
 */ 
class WxTransfers 
{ 
 // 企业转账请求地址 
 const TRANSFERS_URL = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; 
  
 //获取转账信息地址 
 const GETINFO_URL='https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo'; 
  
 // 转账需要的配置 'wxappid','mch_id','key' 
 private $_keys; 
  
 // 转账需要的证书文件 'api_cert', 'api_key', 'rootca',请传入绝对路径!!! 
 private $_cert; 
  
 protected $log_file; 
  
 public $error; 
  
 // 相关配置必备参数 
 protected $_parameters = array(); 
  
 // 最后一次生产的订单号 
 protected $_lastPartnerTradeNo; 
  
 // 记录最后一次发送请求的结果对象 
 protected $_lastResult; 
  
 // 最后一次随机数 
 protected $_lastRandNum; 
  
 public function __construct($config) 
 { 
  $keys = array( 
   'wxappid', 
   'mch_id', 
   'key' 
  ); 
  $files = array( 
   'api_cert', 
   'api_key', 
   'rootca' 
  ); 
  
  foreach ($keys as $key) { 
   try { 
    $this->_keys[$key] = $config[$key]; 
   } catch (Exception $e) { 
    throw new Exception('参数缺失:' . $key); 
   } 
  } 
  
  foreach ($files as $file) { 
   try { 
    $cret_file = $config[$file]; 
    if (is_file($cret_file)) { 
     $this->_cert[$file] = $cret_file; 
    } 
   } catch (Exception $e) { 
    throw new Exception('证书错误'); 
   } 
  } 
 } 
 
 public function transfers($parameters){ 
 
  $this->log($parameters, 'SEND_PARAM'); 
   
  $this->setParameter('mchid', $this->_keys['mch_id']); 
  $this->setParameter('mch_appid', $this->_keys['wxappid']); 
   
  $must = array( 
   'openid', 
   'check_name', 
   're_user_name', 
   'amount', 
   'desc', 
   'spbill_create_ip', 
  ); 
  foreach ($must as $key) { 
   if (isset($parameters[$key]) && $parameters[$key]) { 
    $this->setParameter($key, $parameters[$key]); 
   } else 
    if (! isset($this->_parameters[$key]) || ! $this->_parameters[$key]) { 
     $this->error = '参数缺损:' . $key; 
     return false; 
    } 
  } 
  if (! isset($parameters['partner_trade_no'])) { 
   $parameters['partner_trade_no'] = $this->getPartnerTradeNo(); 
  } 
   
  $this->setParameter('partner_trade_no', $parameters['partner_trade_no']); 
   
  $this->setParameter('nonce_str', $this->getRand(30, 3)); 
   
  $postXml = $this->_createXml(); 
   
  if (! $postXml) { 
   return false; 
  } 
  $this->log($postXml, 'SEND_XML'); 
   
  $result = $this->curl_post_ssl(self::TRANSFERS_URL, $postXml); 
   
  $this->log($result, 'RESULT_XML'); 
   
  if (! $result) { 
   return false; 
  } 
  $resultObj = simplexml_load_string($result, 'SimpleXMLElement', LIBXML_NOCDATA); 
   
  $this->_lastResult = $resultObj; 
   
  if ($resultObj->return_code == 'SUCCESS') { // 成功标识 
     
   if ($resultObj->result_code == 'SUCCESS') { 
   
    return $resultObj->send_listid; 
   } 
     
   if ($resultObj->return_msg) { 
    $this->error = (string) $resultObj->return_msg; 
    return false; 
   } 
     
   $this->error = (string) $resultObj->err_code_des; 
   return false; 
  } 
   
  if ($resultObj->return_code != 'FAIL') { 
   $this->error = '返回信息格式异常'; 
   return false; 
  } 
   
  $this->error = (string) $resultObj->return_msg; 
  return false; 
 } 
  
 /** 
  * 获取转账信息 
  * @param unknown $partner_trade_no 
  * @return boolean|SimpleXMLElement 
  */ 
 public function getInfo($partner_trade_no){ 
  $param = array( 
   'nonce_str' => $this->getRand(30, 3), 
   'partner_trade_no'=> $partner_trade_no , 
   'mch_id' => $this->_keys['mch_id'], 
   'appid'  => $this->_keys['wxappid'], 
  ); 
   
  ksort($param); 
  $unSignParaString = $this->_formatQueryParaMap($param, false); 
  $param['sign'] = $this->_sign($unSignParaString, $this->_keys['key']); 
   
  $xml = $this->arrayToXml($param); 
   
  $this->log($xml, 'GETINFO_XML'); 
   
  $result = $this->curl_post_ssl(self::GETINFO_URL, $xml); 
   
  if(!$result){ 
   return false ; 
  } 
   
  $this->log($result, 'RESULT_XML'); 
   
  $resultObj = simplexml_load_string($result, 'SimpleXMLElement', LIBXML_NOCDATA); 
  $this->_lastResult = $resultObj ; 
  if($resultObj->return_code == 'SUCCESS'){//成功标识 
   
   if($resultObj->result_code == 'SUCCESS'){ 
    return $resultObj ; 
   } 
   
   if($resultObj->return_msg){ 
    $this->error = $resultObj->return_msg ; 
    return false ; 
   } 
   
   $this->error = $resultObj->err_code_des ; 
   return false ; 
  } 
   
  if($resultObj->return_code != 'FAIL'){ 
   $this->error = '返回信息格式异常'; 
   return false ; 
  } 
   
  $this->error = $resultObj->return_msg ; 
  return false ; 
 } 
 /** 
  * 设置所需要的参数 
  * @param $parameter 键值数组/键 
  * @param $value 值 
  * @return WxBonusApi 
  */ 
 public function setParameter($parameter, $value = null) 
 { 
  if (! is_array($parameter)) { 
   return $this->setParameter(array( 
    $parameter => $value 
   )); 
  } 
  
  foreach ($parameter as $key => $value) { 
   $key = trim($key); 
   $value = trim($value); 
   $this->_parameters[$key] = $value; 
  } 
  return $this; 
 } 
  
 /** 
  * 获取参数值 
  * @param $parameter 键名 
  * @return multitype: 
  */ 
 public function getParameter($parameter) 
 { 
  return $this->_parameters[$parameter]; 
 } 
  
 /** 
  * 获取随机数 
  * @param number $len 随机数的位数 
  * @param number $type 取值范围 1表示数字 2小写字母 4大写字母 
  * @return string 
  */ 
 public function getRand($len = 30, $type = 0) 
 { 
  $str = ''; 
  $max = - 1; 
  
  if (! $type) { 
   $type = 3; 
  } 
  
  if ($type & 1) { 
   $str .= '1234567890'; 
   $max += 10; 
  } 
  
  if ($type & 2) { 
   $str .= 'abcdefghijklmnopqrstuvwxyz'; 
   $max += 26; 
  } 
  
  if ($type & 4) { 
   $str .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; 
   $max += 26; 
  } 
  
  $rand = ''; 
  for ($i = 0; $i < $len; $i ++) { 
   $rand .= $str[rand(0, $max)]; 
  } 
  
  return $rand; 
 } 
  
 /** 
  * 生成商户的订单号 
  * @return string 
  */ 
 public function getPartnerTradeNo() 
 { 
  $this->_lastPartnerTradeNo = $this->_parameters['mch_id'] . date('YmdHis') . $this->getRand(4, 1); // $this->getRandNum(); 
  return $this->_lastPartnerTradeNo; 
 } 
  
  
 /** 
  * 获取最后一次创建生成的订单号 
  * @return string 
  */ 
 public function getLastPartnerTradeNo() 
 { 
  return $this->_lastPartnerTradeNo; 
 } 
  
  
  
 /** 
  * 创建XML的方法 
  * @param number $retcode 
  * @param string $reterrmsg 
  * @return boolean|string 
  */ 
 private function _createXml() 
 { 
  try { 
   $sign = $this->_getSign(); 
   if (! $sign) { 
    return false; 
   } 
   $this->setParameter('sign', $sign); 
     
   return $this->arrayToXml($this->_parameters); 
  } catch (Exception $e) { 
   $this->error = $e->getMessage(); 
   return false; 
  } 
 } 
  
  
 /** 
  * 参数转换成XML 
  * @param array $arr 参数数组 
  * @return string 
  */ 
 public 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; 
 } 
  
 /** 
  * 获得签名结果 
  * @return boolean|Ambigous <string, boolean> 
  */ 
 protected function _getSign() 
 { 
  try { 
     
   if ($this->_checkSign() == false) { // 检查生成签名参数 
    $this->error = '生成签名参数缺失!'; 
    $this->log(json_encode($this->_parameters, JSON_UNESCAPED_UNICODE), 'ERROR_Sign_XML'); 
    return false; 
   } 
     
   ksort($this->_parameters); 
   $unSignParaString = $this->_formatQueryParaMap($this->_parameters, false); 
     
   return $this->_sign($unSignParaString, $this->_keys['key']); 
  } catch (Exception $e) { 
   $this->error = $e->getMessage(); 
   return false; 
  } 
 } 
  
 /** 
  * 检查签名所需参数是否齐全 
  * @return boolean 
  */ 
 private function _checkSign() 
 { 
  // return true;  
  if ($this->_parameters["mch_appid"] == null || 
   $this->_parameters["mchid"] == null || 
   //$this->_parameters["device_info"] == null || 设备id 
   $this->_parameters["nonce_str"] == null || 
   $this->_parameters["partner_trade_no"] == null || 
   $this->_parameters["openid"] == null || 
   $this->_parameters["check_name"] == null || 
   $this->_parameters["re_user_name"] == null || 
   $this->_parameters["desc"] == null || 
   $this->_parameters["spbill_create_ip"] == null) { 
    return false; 
   } 
   return true; 
 } 
  
 /** 
  * 
  * @param $paraMap 
  * @param $urlencode 
  * @return string 
  */ 
 private function _formatQueryParaMap($paraMap,$urlencode) 
 { 
  $buff = ""; 
  ksort($paraMap); 
  foreach ($paraMap as $k => $v) { 
   if (null != $v && "null" != $v && "sign" != $k) { 
    if ($urlencode) { 
     $v = urlencode($v); 
    } 
    $buff .= $k . "=" . $v . "&"; 
   } 
  } 
  $reqPar; 
  if (strlen($buff) > 0) { 
   $reqPar = substr($buff, 0, strlen($buff) - 1); 
  } 
  return $reqPar; 
 } 
  
  
 /** 
  * 签名 
  * @param $content 签名的字符串 
  * @param $key 密钥 
  * @throws Exception 
  * @return string|boolean 
  */ 
 private function _sign($content, $key) 
 { 
  try { 
   if (null == $key) { 
    $this->error = '签名key不能为空!'; 
    return false; 
   } 
   if (null == $content) { 
    $this->error = '签名内容不能为空'; 
    return false; 
   } 
   $signStr = $content . "&key=" . $key; 
  
   return strtoupper(md5($signStr)); 
     
  } catch (Exception $e) { 
   $this->error = $e->getMessage(); 
   return false; 
  } 
 } 
  
 /** 
  * cURL抓取 
  * 
  * @param $url 链接地址 
  * @param $vars 参数 
  * @param 
  *   $second 
  * @param 
  *   $aHeader 
  * @return mixed|boolean 
  */ 
 function curl_post_ssl($url, $data, $second = 30, $aHeader = array()) 
 { 
  $ch = curl_init(); 
  // 超时时间 
  curl_setopt($ch, CURLOPT_TIMEOUT, $second); 
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
  // 这里设置代理,如果有的话 
  curl_setopt($ch, CURLOPT_URL, $url); 
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 
  // cert 与 key 分别属于两个.pem文件 
  curl_setopt($ch, CURLOPT_SSLCERT, $this->_cert['api_cert']); 
  curl_setopt($ch, CURLOPT_SSLKEY, $this->_cert['api_key']); 
  curl_setopt($ch, CURLOPT_CAINFO, $this->_cert['rootca']); 
  if (count($aHeader) >= 1) { 
   curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader); 
  } 
  curl_setopt($ch, CURLOPT_POST, 1); 
  curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 
  $data = curl_exec($ch); 
  if ($data) { 
   curl_close($ch); 
   return $data; 
  } else { 
   $this->log(json_encode($this->_cert)); 
   $this->error = 'aa:'.curl_errno($ch); 
   curl_close($ch); 
   return false; 
  } 
 } 
  
 /** 
  * 获取服务器ip 
  * 
  * @return string 
  */ 
 public function getServerIp() 
 { 
  $server_ip = '127.0.0.1'; 
  if (isset($_SERVER)) { 
   if (isset($_SERVER['SERVER_ADDR']) && $_SERVER['SERVER_ADDR']) { 
    $server_ip = $_SERVER['SERVER_ADDR']; 
   } elseif (isset($_SERVER['LOCAL_ADDR']) && $_SERVER['LOCAL_ADDR']) { 
    $server_ip = $_SERVER['LOCAL_ADDR']; 
   } 
  } else { 
   $server_ip = getenv('SERVER_ADDR'); 
  } 
  return $server_ip; 
 } 
  
 /** 
  * 设置日志目录文件 
  * 
  * @param unknown $file 
  */ 
 public function setLogFile($file) 
 { 
  $this->log_file = $file; 
 } 
  
 /** 
  * 写日志 
  * 
  * @param $msg 写入的信息 
  * @param $type 日志类型作为查询标示 
  */ 
 public function log($msg, $type) 
 { 
  if ($this->log_file) { 
   $log = str_replace(array( 
    "\r\n", 
    "\r", 
    "\n" 
   ), array( 
    "", 
    "", 
    "" 
   ), $msg); 
   error_log($type . ' ' . date('Y-m-d H:i:s') . ' ' . json_encode($log,JSON_UNESCAPED_UNICODE) . "\r\n", 3, $this->log_file); 
  } 
 } 
  
}
<?php 

include 'WxTransfers.Api.php'; 
class WxTransfers{ 

/** 
 *调用方法即可测试 
 */ 
 public function index(){ 
   
  $path = WxTransfersConfig::getRealPath(); // 证书文件路径 
  $config['wxappid'] = WxTransfersConfig::APPID; 
  $config['mch_id'] = WxTransfersConfig::MCHID; 
  $config['key'] = WxTransfersConfig::KEY; 
  $config['PARTNERKEY'] = WxTransfersConfig::KEY; 
  $config['api_cert'] = $path . WxTransfersConfig::SSLCERT_PATH; 
  $config['api_key'] = $path . WxTransfersConfig::SSLKEY_PATH; 
  $config['rootca'] = $path . WxTransfersConfig::SSLROOTCA; 
   
  $wxtran=new WxTransfers($config); 
   
  $wxtran->setLogFile('D:\\transfers.log');//日志地址 
   
  //转账 
  $data=array( 
   'openid'=>'',//openid 
   'check_name'=>'NO_CHECK',//是否验证真实姓名参数 
   're_user_name'=>'11',//姓名 
   'amount'=>100,//最小1元 也就是100 
   'desc'=>'企业转账测试',//描述 
   'spbill_create_ip'=>$wxtran->getServerIp(),//服务器IP地址 
  ); 
  var_dump(json_encode($wxtran->transfers($data),JSON_UNESCAPED_UNICODE)); 
  var_dump($wxtran->error); 
 
  //获取转账信息 
  var_dump($wxtran->getInfo('11111111')); 
  var_dump($wxtran->error); 
 } 
  
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PHP中显示格式化的用户输入
Oct 09 PHP
模拟flock实现文件锁定
Feb 14 PHP
PHP 引用是个坏习惯
Mar 12 PHP
PHP连接SQLServer2005方法及代码
Dec 26 PHP
PHP中的按位与和按位或操作示例
Jan 27 PHP
PHP @ at 记号的作用示例介绍
Oct 10 PHP
php利用scws实现mysql全文搜索功能的方法
Dec 25 PHP
php修改上传图片尺寸的方法
Apr 14 PHP
PHP与以太坊交互详解
Aug 24 PHP
PHP实现批量修改文件名的方法示例
Sep 18 PHP
Laravel 框架基于自带的用户系统实现登录注册及错误处理功能分析
Apr 14 PHP
PHP扩展安装方法步骤解析
Nov 24 PHP
PHP实现微信退款功能
Oct 02 #PHP
PHP实现微信申请退款功能
Oct 01 #PHP
微信企业转账之入口类分装php代码
Oct 01 #PHP
PHP实现微信对账单处理
Oct 01 #PHP
php提取微信账单的有效信息
Oct 01 #PHP
YII分模块加载路由的实现方法
Oct 01 #PHP
php实现微信公众号企业转账功能
Oct 01 #PHP
You might like
PHP 和 MySQL 基础教程(三)
2006/10/09 PHP
PHP4引用文件语句的对比
2006/10/09 PHP
如何从一个php文件向另一个地址post数据,不用表单和隐藏的变量的
2007/03/06 PHP
php REMOTE_ADDR之获取访客IP的代码
2008/04/22 PHP
Laravel中的chunk组块结果集处理与注意问题
2018/08/15 PHP
通过遮罩层实现浮层DIV登录的js代码
2014/02/07 Javascript
javascript设计模式之中介者模式Mediator
2014/12/30 Javascript
js数组如何添加json数据及js数组与json的区别
2015/10/27 Javascript
推荐阅读的js快速判断IE浏览器(兼容IE10与IE11)
2015/12/13 Javascript
js实现仿qq消息的弹出窗效果
2016/01/06 Javascript
Javascript的表单与验证-非空验证
2016/03/18 Javascript
使用jQuery制作基础的Web图片轮播效果
2016/04/22 Javascript
node.js插件nodeclipse安装图文教程
2020/10/19 Javascript
深入理解MVC中的时间js格式化
2016/05/19 Javascript
用AngularJS的指令实现tabs切换效果
2016/08/31 Javascript
Vue结合原生js实现自定义组件自动生成示例
2017/01/21 Javascript
详谈js中数组(array)和对象(object)的区别
2017/02/27 Javascript
vue跨域解决方法
2017/10/15 Javascript
使用vue 国际化i18n 实现多实现语言切换功能
2018/10/11 Javascript
electron-vue利用webpack打包实现多页面的入口文件问题
2019/05/12 Javascript
Elementui表格组件+sortablejs实现行拖拽排序的示例代码
2019/08/28 Javascript
Django1.7+python 2.78+pycharm配置mysql数据库教程
2014/11/18 Python
python-opencv在有噪音的情况下提取图像的轮廓实例
2017/08/30 Python
PyQt5每天必学之切换按钮
2020/08/20 Python
Python数据分析:手把手教你用Pandas生成可视化图表的教程
2018/12/15 Python
python时间与Unix时间戳相互转换方法详解
2020/02/13 Python
python爬虫利器之requests库的用法(超全面的爬取网页案例)
2020/12/17 Python
Tarte Cosmetics官网:美国最受欢迎的化妆品公司之一
2017/08/24 全球购物
Stubhub英国:购买体育、演唱会和剧院门票
2018/06/10 全球购物
记帐员岗位责任制
2014/02/08 职场文书
2014年道德讲堂实施方案
2014/03/05 职场文书
创业融资计划书
2014/04/25 职场文书
《放飞蜻蜓》教学反思
2014/04/27 职场文书
涉及车辆房产分割的离婚协议书范文
2014/10/12 职场文书
2015纪念九一八事变84周年演讲稿
2015/03/19 职场文书
Win10加载疑难解答时出错发生意外错误的解决方法
2022/07/07 数码科技