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动态实现表格跨行跨列实现代码
Nov 06 PHP
基于Zend的Config机制的应用分析
May 02 PHP
基于php在各种web服务器的运行模式详解
Jun 03 PHP
ThinkPHP在新浪SAE平台的部署实例
Oct 31 PHP
php画图实例
Nov 05 PHP
php中chdir()函数用法实例
Nov 13 PHP
ecshop后台编辑器替换成ueditor编辑器
Mar 03 PHP
支持中文、字母、数字的PHP验证码
May 04 PHP
PHP 常用时间函数资料整理
Oct 22 PHP
thinkPHP3.2.3结合Laypage实现的分页功能示例
May 28 PHP
php反射学习之不用new方法实例化类操作示例
Jun 14 PHP
Laravel自定义 封装便捷返回Json数据格式的引用方法
Sep 29 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
递归列出所有文件和目录
2006/10/09 PHP
我的论坛源代码(二)
2006/10/09 PHP
dhtmlxTree目录树增加右键菜单以及拖拽排序的实现方法
2013/04/26 PHP
学习php过程中的一些注意点的总结
2013/10/25 PHP
PHP在网页中动态生成PDF文件详细教程
2014/07/05 PHP
PHP获取Exif缩略图的方法
2015/07/13 PHP
Thinkphp3.2.3整合phpqrcode生成带logo的二维码
2016/07/21 PHP
基于php流程控制语句和循环控制语句(讲解)
2017/10/23 PHP
PHP单例模式数据库连接类与页面静态化实现方法
2019/03/20 PHP
laravel框架查询数据集转为数组的两种方法
2019/10/10 PHP
javascript 同时在IE和FireFox获取KeyCode的代码
2010/02/07 Javascript
node.js中的fs.truncate方法使用说明
2014/12/15 Javascript
为什么JavaScript没有块级作用域
2016/05/22 Javascript
Angularjs实现分页和分页算法的示例代码
2016/12/23 Javascript
react实现pure render时bind(this)隐患需注意!
2017/03/09 Javascript
AngularJS 霸道的过滤器小结
2017/04/26 Javascript
jquery+css实现简单的图片轮播效果
2017/08/07 jQuery
js实现下拉框二级联动
2018/12/04 Javascript
JS删除String里某个字符的方法
2021/01/06 Javascript
uni-app从安装到卸载的入门教程
2020/05/15 Javascript
[01:44]《为梦想出发》—联想杯DOTA2完美世界全国高校联赛
2015/09/30 DOTA
使用FastCGI部署Python的Django应用的教程
2015/07/22 Python
Python爬虫天气预报实例详解(小白入门)
2018/01/24 Python
Python反射的用法实例分析
2018/02/11 Python
python实现图书借阅系统
2019/02/20 Python
pyqt5移动鼠标显示坐标的方法
2019/06/21 Python
python并发编程多进程 互斥锁原理解析
2019/08/20 Python
用CSS3实现无限循环的无缝滚动的示例代码
2017/11/01 HTML / CSS
美国购买体育、音乐会和剧院门票网站:SelectATicket
2019/09/08 全球购物
医院实习接收函
2014/01/12 职场文书
大学生优秀团员事迹材料
2014/01/30 职场文书
幼儿园儿童节活动主持词+串词大全
2014/03/21 职场文书
年会搞笑主持词串词
2014/03/24 职场文书
工作保证书怎么写
2015/02/28 职场文书
SpringBoot工程下使用OpenFeign的坑及解决
2021/07/02 Java/Android
MySQL笔记 —SQL运算符
2022/01/18 MySQL