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 相关文章推荐
详解:――如何将图片储存在数据库里
Dec 05 PHP
PHP Array交叉表实现代码
Aug 05 PHP
php代码收集表单内容并写入文件的代码
Jan 29 PHP
有关PHP中MVC的开发经验分享
May 17 PHP
php cli 小技巧
Jun 03 PHP
探讨方法的重写(覆载)详解
Jun 08 PHP
php抓取页面的几种方法详解
Jun 17 PHP
浅析php中抽象类和接口的概念以及区别
Jun 27 PHP
php获取表单中多个同名input元素的值
Mar 20 PHP
CodeIgniter使用smtp服务发送html邮件的方法
Jun 10 PHP
PHP的微信支付接口使用方法讲解
Mar 08 PHP
php使用mysqli和pdo扩展,测试对比连接mysql数据库的效率完整示例
May 09 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
封装一个PDO数据库操作类代码
2009/09/09 PHP
PHP缩略图等比例无损压缩,可填充空白区域补充色
2011/06/10 PHP
php实现的短网址算法分享
2014/06/20 PHP
浅谈php命令行用法
2015/02/04 PHP
php抽象类使用要点与注意事项分析
2015/02/09 PHP
PHP的Yii框架中Model模型的学习教程
2016/03/29 PHP
laravel框架关于搜索功能的实现
2018/03/15 PHP
jQuery的实现原理的模拟代码 -5 Ajax
2010/08/07 Javascript
Javascript 自适应高度的Tab选项卡
2011/04/05 Javascript
js页面跳转的问题(跳转到父页面、最外层页面、本页面)
2013/08/14 Javascript
JavaScript代码简单实现求杨辉三角给定行的最大值
2013/10/29 Javascript
Jquery通过Ajax访问XML数据的小例子
2013/11/18 Javascript
ff chrome和ie下全局动态定位的异同及全局高度的取法
2014/06/30 Javascript
Javascript中的方法和匿名方法实例详解
2015/06/13 Javascript
简单纯js实现点击切换TAB标签实例
2015/08/23 Javascript
jQuery基本筛选选择器实例代码
2017/02/06 Javascript
js中作用域的实例解析
2017/03/16 Javascript
2种在vue项目中使用百度地图的简单方法
2018/09/28 Javascript
浅谈JavaScript面向对象--继承
2019/03/20 Javascript
js删除指定位置超链接中含有百度与360的标题
2021/01/06 Javascript
一起深入理解js中的事件对象
2021/02/06 Javascript
一篇不错的Python入门教程
2007/02/08 Python
tensorflow 加载部分变量的实例讲解
2018/07/27 Python
详解Python做一个名片管理系统
2019/03/14 Python
pyinstaller打包多个py文件和去除cmd黑框的方法
2019/06/21 Python
美国婚礼装饰和活动用品批发供应商:Event Decor Direct
2018/10/12 全球购物
个性化皮包、小袋、生活配件:Mon Purse
2019/03/26 全球购物
澳大利亚波希米亚风时尚品牌:Tree of Life
2019/09/15 全球购物
幼儿园教师岗位职责
2014/03/17 职场文书
小区门卫的岗位职责
2014/09/26 职场文书
买卖合同协议书范本
2014/10/18 职场文书
2014年会计工作总结
2014/11/27 职场文书
写给女朋友的保证书
2015/05/09 职场文书
《槐乡的孩子》教学反思
2016/02/20 职场文书
浅谈Redis的keys命令到底有多慢
2021/10/05 Redis
Linux、ubuntu系统下查看显卡型号、显卡信息详解
2022/04/07 Servers