php实现微信企业转账功能

本文实例为大家分享了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);
 } 

}

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

(0)

相关推荐

  • php微信公众号开发之微信企业付款给个人

    本文实例为大家分享了php微信企业付款给个人的具体代码,供大家参考,具体内容如下 以下有关微信支付中企业付款的介绍及编码参考自微信支付开发文档,网址,如图所示 企业付款,提供企业向用户付款的功能,支持企业通过API接口付款,或通过微信支付商户平台网页功能操作付款. 企业付款业务是基于微信支付商户平台的资金管理能力,为了协助商户方便地实现企业向个人付款,针对部分有开发能力的商户,提供通过API完成企业付款的功能.< 比如目前的保险行业向客户退保.给付.理赔. 以下是PHP用于实现企业付款业务的代码

  • php实现微信公众号企业转账功能

    企业付款提供由商户直接付钱至用户微信零钱的能力,支持平台操作及接口调用两种方式,资金到账速度快,使用及查询方便.主要用来解决合理的商户对用户付款需求,比如:保险理赔.彩票兑换等等. 特点 发起方式灵活,可通过页面或接口发起 微信消息触达,用户及时获知入账详情 支持实名校验,判断收款人真实身份 通过openid即可实现付款,无需用户敏感隐私信息 到账速度快,在发起后,用户可在几分钟内收到付款 企业转账需要到微信商户平台=>产品中心=>企业付款到零钱,开启此功能 下面是程序截图: 第一步:设置配置

  • PHP编程之微信公众平台企业号验证接口示例【回调操作】

    本文实例讲述了PHP微信公众平台企业号验证接口.分享给大家供大家参考,具体如下: 微信公众平台企业号验证接口.回调 PHP版,本人为了解决这个企业号的验证和发送消息的问题,整整研究了几天时间,因为微信企业号刚推出来的时候网上资料比较少!后来在一些朋友的帮助下和本人反复调试完善下,终于整理得到了比较理想的文档,经亲测,实验成功. include_once "WXBizMsgCrypt.php"; // 第三方发送消息给公众平台 $encodingAesKey = "rpJmhC

  • PHP实现微信商户支付企业付款到零钱功能

    本文为大家分享了PHP实现微信商户支付企业付款到零钱的具体代码,供大家参考,具体内容如下 微信支付开发文档 一.开通条件 企业付款为企业提供付款至用户零钱的能力,支持通过API接口付款,或通过微信支付商户平台(pay.weixin.qq.com)网页操作付款. 使用条件 商户号(或同主体其他非服务商商户号)已入驻90日 商户号(或同主体其他非服务商商户号)有30天连续正常交易 登录微信支付商户平台-产品中心,开通企业付款. 具体的可以看微信支付开发文档 二.代码展示 //企业付款到微信零钱,PH

  • php实现微信支付之企业付款

    网上的很多PHP微信支付接入教程都颇为复杂,且需要配置和引入较多的文件,本人通过整理后给出一个单文件版的,希望可以给各位想接入微信支付的带来些许帮助和借鉴意义. 直接运行该文件即可给指定的微信用户转账. 需要注意的事项: 1.微信企业付款到零钱要求必传证书,需要到这里账户中心->账户设置->API安全->下载证书,然后修改代码中的证书路径  2.该文件需放到支付授权目录下,可以在微信支付商户平台->产品中心->开发配置中设置. 3.如提示签名错误可以通过微信支付签名验证工具进

  • PHP实现微信公众号企业号自定义菜单接口示例

    本文实例讲述了PHP实现微信公众号企业号自定义菜单接口.分享给大家供大家参考,具体如下: define(AppId, "wx666cae44xxxxxx2");//定义AppId,需要在微信公众平台申请自定义菜单后会得到 define(AppSecret, "d77026a714d443a01d0229xxxxxxxx");//定义AppSecret,需要在微信公众平台申请自定义菜单后会得到 include("menu.php");//引入微信类

  • Thinkphp 5.0实现微信企业付款到零钱

    本文实例为大家分享了Thinkphp 5.0 微信企业付款到零钱的具体代码,供大家参考,具体内容如下 [微信支付]企业付款到零钱:官方文档 注意:1,证书路径一定要写绝对路径,且使用函数getcwd(). function transfer($data){ //支付信息 $wxchat['appid'] = WxPayConfig::$appid; $wxchat['mchid'] = WxPayConfig::$mchid; $webdata = array( 'mch_appid' => $

  • 微信企业转账之入口类分装php代码

    本文实例为大家分享了php微信企业转账的具体代码,供大家参考,具体内容如下 OK,经过前面的操作,我们已经把底层方法封装完毕,接下来就是实现转账工具类的调用.在这里,封装了一个入口文件类 WxTransfers 该类的定义如下所示: <?php include_once 'WxTransfers.Api.php'; class WxTransfers{ public function index(){ $path = WxTransfersConfig::getRealPath(); // 证书

  • PHP编程实现微信企业向用户付款的方法示例

    本文实例讲述了PHP编程实现微信企业向用户付款的方法.分享给大家供大家参考,具体如下: <?php header('content-type:text/html;charset=utf-8'); $data['mch_appid']='##################';//商户的应用appid $data['mchid']='################';//商户ID $data['nonce_str']='123456';//unicode();//这个据说是唯一的字符串下面有方法

  • PHP微信企业号开发之回调模式开启与用法示例

    本文实例讲述了PHP微信企业号开发之回调模式开启与用法.分享给大家供大家参考,具体如下: 暑假实习,领导安排开发微信企业号.在此对遇到的问题进行记录,分享给遇到同样问题的小伙伴,希望对小伙伴们有帮助.微信企业号注册部分就不用多说了,今天记录微信企业号--回调模式开启php部分. 其实微信开发文档说的确实十分详细了,而且使用官方给的demo,只要做稍稍的改变就可以直接用了.但是为什么总是提示错误呢? 下面我先贴出我验证成功的回调模式开启的代码 <?php //回调开启 include_once &qu

随机推荐