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跨站刷票的实现代码
Jun 18 PHP
浅析PHP微信支付通知的处理方式
May 25 PHP
php生成随机数的三种方法
Sep 10 PHP
PHP中应该避免使用同名变量(拆分临时变量)
Apr 03 PHP
大家须知简单的php性能优化注意点
Jan 04 PHP
PHP递归遍历多维数组实现无限分类的方法
May 06 PHP
Windows2003下php5.4安装配置教程(IIS)
Jun 30 PHP
PHP请求Socket接口测试实例
Aug 12 PHP
PHP防止图片盗用(盗链)的方法小结
Nov 11 PHP
PHP+ajax实现二级联动菜单功能示例
Aug 10 PHP
php7 图形用户界面GUI 开发示例
Feb 22 PHP
php并发加锁问题分析与设计代码实例讲解
Feb 26 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中通过加号合并数组的一个简单方法分享
2011/01/27 PHP
PHP判断远程图片或文件是否存在的实现代码
2014/02/20 PHP
PHP中遇到BOM、编码导致json_decode函数无法解析问题
2014/07/02 PHP
php实现将字符串按照指定距离进行分割的方法
2015/03/14 PHP
php+ajax实现无刷新文件上传功能(ajaxuploadfile)
2018/02/11 PHP
Laravel核心解读之异常处理的实践过程
2019/02/24 PHP
javascript中的location用法简单介绍
2007/03/07 Javascript
javascript 动态table添加colspan\rowspan 参数的方法
2009/07/25 Javascript
利用jQuery 实现GridView异步排序、分页的代码
2010/02/06 Javascript
推荐11款jQuery开发的复选框和单选框美化插件
2011/08/02 Javascript
js获取浏览器的可视区域尺寸的实现代码
2011/11/30 Javascript
鼠标滚轮改变图片大小的示例代码
2013/11/20 Javascript
可自定义速度的js图片无缝滚动示例分享
2014/01/20 Javascript
jquery动态添加删除一行数据示例
2014/06/12 Javascript
jQuery 浮动导航菜单适合购物商品类型的网站
2014/09/09 Javascript
javascript函数式编程程序员的工具集
2015/10/11 Javascript
js的各种排序算法实现(总结)
2016/07/23 Javascript
jQuery简单实现点击文本框复制内容到剪贴板上的方法
2016/08/01 Javascript
Django+Vue.js搭建前后端分离项目的示例
2017/08/07 Javascript
示例vue 的keep-alive缓存功能的实现
2018/12/13 Javascript
JavaScript实现的滚动公告特效【基于jQuery】
2019/07/10 jQuery
vue滚动tab跟随切换效果
2020/06/29 Javascript
使用Python的内建模块collections的教程
2015/04/28 Python
python解析xml文件实例分析
2015/05/27 Python
Python 安装setuptools和pip工具操作方法(必看)
2017/05/22 Python
Python使用re模块正则提取字符串中括号内的内容示例
2018/06/01 Python
python实现矩阵和array数组之间的转换
2019/11/29 Python
python GUI库图形界面开发之PyQt5表格控件QTableView详细使用方法与实例
2020/03/01 Python
高级护理专业大学生求职信
2013/10/24 职场文书
餐饮主管岗位职责
2013/12/10 职场文书
改革共识倡议书
2014/08/29 职场文书
社区党建工作汇报材料
2014/10/27 职场文书
小学中队活动总结
2015/05/11 职场文书
mybatis调用sqlserver存储过程返回结果集的方法
2021/05/08 SQL Server
WINDOWS 64位 下安装配置mysql8.0.25最详细的教程
2022/03/22 MySQL
zabbix配置nginx监控的实现
2022/05/25 Servers