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 md5下16位和32位的实现代码
Apr 09 PHP
PHP form 表单传参明细研究
Jul 17 PHP
php &amp;&amp; 逻辑与运算符使用说明
Mar 04 PHP
php fsockopen伪造post与get方法的详解
Jun 14 PHP
PHP快速按行读取CSV大文件的封装类分享(也适用于其它超大文本文件)
Apr 10 PHP
通过dbi使用perl连接mysql数据库的方法
Apr 16 PHP
php下Memcached入门实例解析
Jan 05 PHP
php给图片加文字水印
Jul 31 PHP
PHP下载生成的csv文件及问题总结
Aug 06 PHP
Yii中CArrayDataProvider和CActiveDataProvider区别实例分析
Mar 02 PHP
php简单实现批量上传图片的方法
May 09 PHP
thinkPHP5使用Rabc实现权限管理
Aug 28 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网页后退不再出现过期
2007/03/08 PHP
php flush类输出缓冲剖析
2008/10/19 PHP
php 静态变量与自定义常量的使用方法
2010/01/26 PHP
php生成N个不重复的随机数实例
2013/11/12 PHP
php封装的smarty类完整实例
2016/10/19 PHP
PhpStorm连接服务器并实现自动上传功能
2020/12/09 PHP
javascript实现轮显新闻标题链接
2007/08/13 Javascript
IE与Firefox在JavaScript上的7个不同写法小结
2009/09/14 Javascript
Google Dart编程语法和基本类型学习教程
2013/11/27 Javascript
js中判断对象是否为空的三种实现方法
2013/12/23 Javascript
jquery的ajax跨域请求原理和示例
2014/05/08 Javascript
jQuery函数的第二个参数获取指定上下文中的DOM元素
2014/05/19 Javascript
了不起的node.js读书笔记之node的学习总结
2014/12/22 Javascript
JavaScript中关于iframe滚动条的去除和保留
2016/11/17 Javascript
angularjs实现多张图片上传并预览功能
2017/02/24 Javascript
Angular实现响应式表单
2017/08/04 Javascript
浅谈在react中如何实现扫码枪输入
2018/07/04 Javascript
详解Ubuntu安装angular-cli遇到的坑
2018/09/08 Javascript
Nodejs调用Dll模块的方法
2018/09/17 NodeJs
element el-input directive数字进行控制
2018/10/11 Javascript
vue+echarts实现可拖动节点的折线图(支持拖动方向和上下限的设置)
2019/04/12 Javascript
浅谈Vuex注入Vue生命周期的过程
2019/05/20 Javascript
JS实现纵向轮播图(初级版)
2020/01/18 Javascript
12 种使用Vue 的最佳做法
2020/03/30 Javascript
vue项目查看vue版本及cli版本的实现方式
2020/10/24 Javascript
vue实现列表拖拽排序的功能
2020/11/02 Javascript
解决pycharm界面不能显示中文的问题
2018/05/23 Python
python selenium 执行完毕关闭chromedriver进程示例
2019/11/15 Python
详解Python3中的 input() 函数
2020/03/18 Python
python如何快速拼接字符串
2020/10/28 Python
电厂职工自我鉴定
2014/02/20 职场文书
信息与计算科学专业推荐信
2014/02/23 职场文书
村长贪污检举信
2014/04/04 职场文书
负责人任命书范本
2014/06/04 职场文书
教师学习八项规定六项禁令思想汇报
2014/09/27 职场文书
学生会宣传部竞选稿
2015/11/21 职场文书