1
0

first commit

This commit is contained in:
2020-08-06 14:58:51 +08:00
commit 17096657dc
780 changed files with 92857 additions and 0 deletions

24
vendor/cjango/wechat/composer.json vendored Normal file
View File

@@ -0,0 +1,24 @@
{
"name": "cjango/wechat",
"description": "wechat sdk",
"keywords": ["cjango", "wechat", "sdk", "code"],
"homepage": "https://github.com/cjango/wechat",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Jason.Chen",
"email": "chenjxlg@163.com",
"homepage": "http://www.cjango.com/"
}
],
"minimum-stability": "dev",
"require": {
"php": ">=5.5.0"
},
"autoload": {
"psr-4": {
"cjango\\": "src/"
}
}
}

111
vendor/cjango/wechat/src/Wechat.php vendored Normal file
View File

@@ -0,0 +1,111 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango;
/**
* 微信公众平台开发SDK,
* 架构问题又凌乱了.
* @author 小陈叔叔 <20511924@qq.com>
*/
class Wechat
{
/**
* 保存错误信息
* @var string
*/
protected static $error = '';
/**
* 默认的配置参数
* @var array
*/
protected static $config = [
'token' => '',
'appid' => '',
'secret' => '',
'access_token' => '',
'encode' => false,
'AESKey' => '',
'mch_id' => '',
'paykey' => '',
'pem' => '',
];
/**
* 传入初始化参数
* 接受消息,如果是加密的需要传入一些参数,否则用不到
*/
public function __construct($config = [])
{
if (!empty($config) && is_array($config)) {
self::$config = array_merge(self::$config, $config);
}
}
/**
* 初始化
* @param array $config
* @param boolean $force 强制初始化
* @return [type]
*/
public static function instance($config = [], $force = false)
{
static $wechat;
if (is_null($wechat) || $force == true) {
$wechat = new Wechat($config);
}
return $wechat;
}
/**
* 验证URL有效性,校验请求签名
* @return string|boolean
*/
public static function valid()
{
$echoStr = isset($_GET["echostr"]) ? $_GET["echostr"] : '';
if ($echoStr) {
self::checkSignature() && exit($echoStr);
} else {
!self::checkSignature() && exit('Access Denied!');
}
}
/**
* 检查请求URL签名
* @return boolean
*/
private static function checkSignature()
{
$signature = isset($_GET['signature']) ? $_GET['signature'] : '';
$timestamp = isset($_GET['timestamp']) ? $_GET['timestamp'] : '';
$nonce = isset($_GET['nonce']) ? $_GET['nonce'] : '';
if (empty($signature) || empty($timestamp) || empty($nonce)) {
return false;
}
$token = self::$config['token'];
$tmpArr = [$token, $timestamp, $nonce];
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
return sha1($tmpStr) == $signature;
}
/**
* 返回错误信息
* @return string
*/
public static function error($msg = null)
{
if (!is_null($msg)) {
self::$error = $msg;
} else {
return self::$error;
}
}
}

View File

@@ -0,0 +1,50 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
* 微信卡券相关部分,太难了 等我喝醉了再说吧!
*/
class Card extends Wechat
{
/**
* 接口名称与URL映射
* @var array
*/
protected static $url = [
'card_create' => 'https://api.weixin.qq.com/card/create',
'card_active' => 'https://api.weixin.qq.com/card/membercard/activate',
];
public static function create()
{
$params = [
'card' => [
'card_type' => 'MEMBER_CARD',
'member_card' => [
'base_info' => [
'logo_url' => '',
'brand_name' => '',
'code_type' => 'CODE_TYPE_TEXT',
'title' => 'Color010',
],
],
],
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
return Utils::api(self::$url['card_create'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
public static function active()
{
#Todo..
}
}

View File

@@ -0,0 +1,41 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
* 数据统计接口
*/
class Datacube extends Wechat
{
/**
* 接口名称与URL映射
* @var array
*/
protected static $url = [
'user_summary' => 'https://api.weixin.qq.com/datacube/getusersummary',
'user_cumulate' => 'https://api.weixin.qq.com/datacube/getusercumulate',
'' => 'https://api.weixin.qq.com/datacube/getarticlesummary',
'' => 'https://api.weixin.qq.com/datacube/getarticletotal',
'' => 'https://api.weixin.qq.com/datacube/getuserread',
'' => 'https://api.weixin.qq.com/datacube/getuserreadhour',
'' => 'https://api.weixin.qq.com/datacube/getusershare',
'' => 'https://api.weixin.qq.com/datacube/getusersharehour',
'' => 'https://api.weixin.qq.com/datacube/getupstreammsg',
'' => 'https://api.weixin.qq.com/datacube/getupstreammsghour',
'' => 'https://api.weixin.qq.com/datacube/getupstreammsgweek',
'' => 'https://api.weixin.qq.com/datacube/getupstreammsgmonth',
'' => 'https://api.weixin.qq.com/datacube/getupstreammsgdist',
'' => 'https://api.weixin.qq.com/datacube/getupstreammsgdistweek',
'' => 'https://api.weixin.qq.com/datacube/getupstreammsgdistmonth',
'' => 'https://api.weixin.qq.com/datacube/getinterfacesummary',
'' => 'https://api.weixin.qq.com/datacube/getinterfacesummaryhour',
];
}

View File

@@ -0,0 +1,100 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
* 分组管理
*/
class Group extends Wechat
{
/**
* 接口名称与URL映射
* @var array
*/
protected static $url = [
'group_get' => 'https://api.weixin.qq.com/cgi-bin/groups/get',
'group_create' => 'https://api.weixin.qq.com/cgi-bin/groups/create',
'group_update' => 'https://api.weixin.qq.com/cgi-bin/groups/update',
'group_delete' => 'https://api.weixin.qq.com/cgi-bin/groups/delete',
];
/**
* 获取全部分组
*/
public static function get()
{
$params = [
'access_token' => parent::$config['access_token'],
];
$result = Utils::api(self::$url['group_get'], $params);
if ($result) {
return $result['groups'];
} else {
return false;
}
}
/**
* 新增分组
* @param string $name
* @return array ['id' => ID, 'name' => NAME]
*/
public static function create($name)
{
$params = [
'group' => [
'name' => $name,
],
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
$result = Utils::api(self::$url['group_create'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
if ($result) {
return $result['group'];
} else {
return false;
}
}
/**
* 修改分组名
* @param [type] $id [description]
* @param [type] $name [description]
* @return [type] [description]
*/
public static function update($id, $name)
{
$params = [
'group' => [
'id' => $id,
'name' => $name,
],
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
return Utils::api(self::$url['group_update'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
/**
* 删除分组
* @param [type] $id [description]
* @return [type] [description]
*/
public static function delete($id)
{
$params = [
'group' => [
'id' => $id,
],
];
$params = json_encode($params);
return Utils::api(self::$url['group_delete'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
}

View File

@@ -0,0 +1,51 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
* 素材管理
*/
class Material extends Wechat
{
/**
* 接口名称与URL映射
* @var array
*/
protected static $url = [
'media_upload' => 'https://api.weixin.qq.com/cgi-bin/media/upload', // 新增临时素材
'media_get' => 'https://api.weixin.qq.com/cgi-bin/media/get', // 获取临时素材
'material_news' => 'https://api.weixin.qq.com/cgi-bin/material/add_news', // 新增永久图文素材
'material_material' => 'https://api.weixin.qq.com/cgi-bin/material/add_material', // 新增永久素材
'material_get' => 'https://api.weixin.qq.com/cgi-bin/material/get_material', // 获取永久素材
'material_del' => 'https://api.weixin.qq.com/cgi-bin/material/del_material', // 删除永久素材
'material_update' => 'https://api.weixin.qq.com/cgi-bin/material/update_news', // 修改永久图文素材
'material_count' => 'https://api.weixin.qq.com/cgi-bin/material/get_materialcount', // 获取永久素材数量
'material_lists' => 'https://api.weixin.qq.com/cgi-bin/material/batchget_material', // 获取永久素材列表
];
/**
* 新增临时素材
* @return [type] [description]
*/
public static function upload()
{
#Todo..
}
/**
* 获取临时素材
* @return [type] [description]
*/
public static function get()
{
#Todo..
}
}

View File

@@ -0,0 +1,70 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
* 自定义菜单
*/
class Menu extends Wechat
{
/**
* 接口名称与URL映射
* @var array
*/
protected static $url = [
'menu_get' => 'https://api.weixin.qq.com/cgi-bin/menu/get', // 获取菜单
'menu_create' => 'https://api.weixin.qq.com/cgi-bin/menu/create', // 创建菜单
'menu_delete' => 'https://api.weixin.qq.com/cgi-bin/menu/delete', // 删除菜单
];
/**
* 获取自定义菜单
* @return [type] [description]
*/
public static function get()
{
$params = [
'access_token' => parent::$config['access_token'],
];
$result = Utils::api(self::$url['menu_get'], $params);
if ($result) {
return $result['menu']['button'];
} else {
return false;
}
}
/**
* 创建菜单
* @param [type] $menu [description]
* @return [type] [description]
*/
public static function create($menu)
{
$params = [
'button' => $menu,
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
return Utils::api(self::$url['menu_create'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
/**
* 删除自定义菜单
* @return [type] [description]
*/
public static function delete()
{
$params = [
'access_token' => parent::$config['access_token'],
];
return Utils::api(self::$url['menu_delete'], $params);
}
}

View File

@@ -0,0 +1,83 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
* ACCESS TOKEN获取
*/
class Oauth extends Wechat
{
/**
* 接口名称与URL映射
* @var array
*/
protected static $url = [
'oauth_authorize' => 'https://open.weixin.qq.com/connect/oauth2/authorize',
'oauth_user_token' => 'https://api.weixin.qq.com/sns/oauth2/access_token',
'oauth_get_userinfo' => 'https://api.weixin.qq.com/sns/userinfo',
];
/**
* OAuth 用户同意授权获取code
* @param [type] $callback 回调URI填写完整地址带http://
* @param string $state 重定向后会带上state参数开发者可以填写a-zA-Z0-9的参数值
* @param string $scope snsapi_userinfo 获取用户授权信息snsapi_base直接返回openid
* @return string
*/
public static function url($callback, $state = 'STATE', $scope = 'snsapi_base')
{
$params = [
'appid' => self::$config['appid'],
'redirect_uri' => $callback,
'response_type' => 'code',
'scope' => $scope,
'state' => $state,
];
return self::$url['oauth_authorize'] . '?' . http_build_query($params) . '#wechat_redirect';
}
/**
* 通过code获取Access Token
* @return array|boolean
*/
public static function token()
{
$code = isset($_GET['code']) ? $_GET['code'] : '';
if (!$code) {
parent::$error = '未获取到CODE信息';
return false;
}
$params = [
'appid' => self::$config['appid'],
'secret' => self::$config['secret'],
'code' => $code,
'grant_type' => 'authorization_code',
];
return Utils::api(self::$url['oauth_user_token'], $params);
}
/**
* 网页获取用户信息
* @param string $access_token 通过getOauthAccessToken方法获取到的token
* @param string $openid 用户的OPENID
* @return array
*/
public static function info($token, $openid)
{
$params = [
'access_token' => $token,
'openid' => $openid,
'lang' => 'zh_CN',
];
return Utils::api(self::$url['oauth_get_userinfo'], $params);
}
}

280
vendor/cjango/wechat/src/Wechat/Pay.php vendored Normal file
View File

@@ -0,0 +1,280 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
* 微信支付相关部分
*/
class Pay extends Wechat
{
/**
* 接口名称与URL映射
* @var array
*/
protected static $url = [
'unified_order' => 'https://api.mch.weixin.qq.com/pay/unifiedorder', // 统一下单地址
'order_query' => 'https://api.mch.weixin.qq.com/pay/orderquery', // 订单状态查询
'close_order' => 'https://api.mch.weixin.qq.com/pay/closeorder', // 关闭订单
'refund_order' => 'https://api.mch.weixin.qq.com/secapi/pay/refund', // 退款地址
'refund_query' => 'https://api.mch.weixin.qq.com/pay/refundquery', // 退款查询
'pay_transfers' => 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers', // 企业付款
'get_pay_transfers' => 'https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo', // 企业付款查询
'download_bill' => 'https://api.mch.weixin.qq.com/pay/downloadbill', // 下载对账单
'send_red_pack' => 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack', // 发放红包高级接口
'send_group_red_pack' => 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack', // 发送裂变红包接口(拼手气)
'get_red_pack_info' => 'https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo', // 红包查询接口
];
/**
* 统一下单支付
* @param string $orderId 系统订单号
* @param string $body 产品描述
* @param string $money 支付金额
* @param string $trade_type (JSAPI NATIVE APP)
* @param string $notify_url 回调URL
* @param string $openid 支付用户
* @param string $attach 附加信息
* @param array $extends 订单扩展数据
* @return boolean|JSON 直接用于H5调用支付的API参数
*/
public static function unified($orderId, $body, $money, $tradeType = 'JSAPI', $notifyUrl = '', $openid = '', $attach = '', $extends = [])
{
$params = [
'appid' => parent::$config['appid'],
'mch_id' => parent::$config['mch_id'],
'nonce_str' => uniqid(),
'body' => $body,
'out_trade_no' => $orderId,
'total_fee' => $money * 100, // 转换成分
'spbill_create_ip' => self::_getClientIp(),
'notify_url' => $notifyUrl,
'trade_type' => $tradeType,
];
if (!empty($openid) && $tradeType == 'JSAPI') {
$params['openid'] = $openid;
}
if (!empty($attach)) {
$params['attach'] = $attach;
}
$params['sign'] = self::_getOrderSign($params);
$data = Utils::array2xml($params);
$data = Utils::http(self::$url['unified_order'], $data, 'POST');
$result = self::parsePayResult(Utils::xml2array($data));
if ($result) {
return self::createPayParams($result['prepay_id']);
} else {
return false;
}
}
/**
* 创建支付参数
* @param [type] $prepay_id [description]
* @return JSON
*/
private static function createPayParams($prepay_id)
{
$params['appId'] = parent::$config['appid'];
$params['timeStamp'] = (string) time();
$params['nonceStr'] = uniqid();
$params['package'] = 'prepay_id=' . $prepay_id;
$params['signType'] = 'MD5';
$params['paySign'] = self::_getOrderSign($params);
return json_encode($params);
}
/**
* 查询订单
* @param [type] $out_trade_no [description]
* @return [type] [description]
*/
public static function query($orderId = '', $type = 'out_trade_no')
{
$params = [
'appid' => parent::$config['appid'],
'mch_id' => parent::$config['mch_id'],
'nonce_str' => uniqid(),
];
if ($type == 'out_trade_no') {
$params['out_trade_no'] = $orderId;
} else {
$params['transaction_id'] = $orderId;
}
$params['sign'] = self::_getOrderSign($params);
$data = Utils::array2xml($params);
$data = Utils::http(self::$url['order_query'], $data, 'POST');
return Utils::xml2array($data);
}
/**
* 关闭订单
* @param string $orderId 商户订单号
* @return boolean
*/
public static function close($orderId)
{
$params = [
'appid' => parent::$config['appid'],
'mch_id' => parent::$config['mch_id'],
'out_trade_no' => $orderId,
'nonce_str' => uniqid(),
];
$params['sign'] = self::_getOrderSign($params);
$data = Utils::array2xml($params);
$data = Utils::http(self::$url['close_order'], $data, 'POST');
$result = self::parsePayResult(Utils::xml2array($data));
if ($result) {
return true;
} else {
return false;
}
}
/**
* 退款申请
* @param [type] $transaction_id [description]
* @param [type] $orderId [description]
* @param [type] $out_refund_no [description]
* @param [type] $total_fee [description]
* @param [type] $refund_fee [description]
* @param [type] $op_user_id [description]
* @return [type] [description]
*/
public static function refund($orderId, $refundId, $total_fee, $refund_fee)
{
$params = [
'appid' => parent::$config['appid'],
'mch_id' => parent::$config['mch_id'],
'out_trade_no' => $orderId,
'out_refund_no' => $refundId,
'total_fee' => $total_fee,
'refund_fee' => $refund_fee,
'op_user_id' => parent::$config['mch_id'],
'nonce_str' => uniqid(),
];
$params['sign'] = self::_getOrderSign($params);
$data = Utils::array2xml($params);
$data = Utils::http(self::$url['close_order'], $data, 'POST');
$result = self::parsePayResult(Utils::xml2array($data));
if ($result) {
return $result;
} else {
return false;
}
}
/**
* 解析支付接口的返回结果
* @param xmlstring $data 接口返回的数据
* @param boolean $checkSign 是否需要签名校验
* @return boolean|array
*/
public static function parsePayRequest($checkSign = true)
{
$post = file_get_contents("php://input");
$data = Utils::xml2array($post);
if (empty($data)) {
Wechat::error('回调结果解析失败');
return false;
}
if ($checkSign) {
$sign = $data['sign'];
unset($data['sign']);
if (self::_getOrderSign($data) != $sign) {
Wechat::error('签名校验失败');
return false;
}
}
return self::parsePayResult($data);
}
/**
* 解析支付借口的返回数据
* @param [type] $data [description]
*/
private static function parsePayResult($data)
{
if ($data['return_code'] == 'SUCCESS') {
if ($data['result_code'] == 'SUCCESS') {
return $data;
} else {
Wechat::error($data['err_code']);
return false;
}
} else {
Wechat::error($data['return_msg']);
return false;
}
}
/**
* 支付结果通知
* @param [type] $code 支付结果
* @param [type] $msg 返回信息
* @return xml
*/
public static function returnNotify($msg = true)
{
if ($msg === true) {
$params = [
'return_code' => 'SUCCESS',
'return_msg' => '',
];
} else {
$params = [
'return_code' => 'FAIL',
'return_msg' => $msg,
];
}
exit(Utils::array2xml($params));
}
/**
* 获取客户端IP地址
* @return string
*/
private static function _getClientIp()
{
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$pos = array_search('unknown', $arr);
if (false !== $pos) {
unset($arr[$pos]);
}
$ip = trim(current($arr));
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}
/**
* 本地MD5签名
* @param array $params 需要签名的数据
* @return string 大写字母与数字签名串32位
*/
private static function _getOrderSign($params)
{
ksort($params);
$params['key'] = parent::$config['paykey'];
return strtoupper(md5(urldecode(http_build_query($params))));
}
}

View File

@@ -0,0 +1,98 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
* 自定义菜单
*/
class QRcode extends Wechat
{
/**
* 接口名称与URL映射
* @var array
*/
protected static $url = [
'qrcode_create' => 'https://api.weixin.qq.com/cgi-bin/qrcode/create',
'qrcode_show' => 'https://mp.weixin.qq.com/cgi-bin/showqrcode',
'short_url' => 'https://api.mch.weixin.qq.com/tools/shorturl', // 转换短链接
];
/**
* 临时二维码
* @param [type] $scene_id [description]
* @param integer $expire [description]
* @return [type] [description]
*/
public static function temp($scene_id, $expire = 604800)
{
$params = [
'expire_seconds' => $expire,
'action_name' => 'QR_SCENE',
'action_info' => [
'scene' => [
'scene_id' => $scene_id,
],
],
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
$result = Utils::api(self::$url['qrcode_create'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
if ($result) {
return self::$url['qrcode_show'] . '?ticket=' . $result['ticket'];
} else {
return false;
}
}
/**
* 永久二维码
* @return [type] [description]
*/
public static function limit($scene_str)
{
$params = [
'action_name' => 'QR_LIMIT_SCENE',
'action_info' => [
'scene' => [
'scene_str' => $scene_str,
],
],
'access_token' => parent::$config['access_token'],
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
$result = Utils::api(self::$url['qrcode_create'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
if ($result) {
return self::$url['qrcode_show'] . '?ticket=' . $result['ticket'];
} else {
return false;
}
}
/**
* 转换短链接
* @param [type] $longUrl
* @return [type]
*/
public static function short($longUrl)
{
$params = [
'action' => 'long2short',
'long_url' => $longUrl,
];
$params = json_encode($params);
$result = Utils::api(self::$url['short_url'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
if ($result) {
return $result;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,170 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
* 被动消息回复
*/
class Reply extends Wechat
{
/**
* 接收到的消息内容
* @var array
*/
private static $request = [];
private static $response = [];
/**
* 接受消息,通用,接受到的消息
* 用户自己处理消息类型就可以
* 暂时不处理加密问题
* @return array|boolean
*/
public static function request()
{
$postStr = file_get_contents("php://input");
if (!empty($postStr)) {
$data = Utils::xml2array($postStr);
return self::$request = $data;
} else {
return false;
}
}
/**
* 回复消息
* @param array|string $content 回复的消息内容
* @param string $type 回复的消息类型
* @return xml
*/
public static function response($content, $type = 'text')
{
self::$response = [
'ToUserName' => self::$request['fromusername'],
'FromUserName' => self::$request['tousername'],
'CreateTime' => time(),
'MsgType' => $type,
];
self::$type($content);
$response = Utils::array2xml(self::$response);
exit($response);
}
/**
* 回复文本类型消息
* @param string $content
*/
private static function text($content)
{
self::$response['Content'] = $content;
}
/**
* 回复图片类型消息
* @param string $mediaId
*/
private static function image($mediaId)
{
self::$response['Image']['MediaId'] = $mediaId;
}
/**
* 回复语音类型消息
* @param string $mediaId
*/
private static function voice($mediaId)
{
self::$response['Voice']['MediaId'] = $mediaId;
}
/**
* 回复视频类型消息
* @param array $media
*/
private static function video($video)
{
list(
$video['MediaId'],
$video['Title'],
$video['Description']
) = $video;
self::$response['Video'] = $video;
}
/**
* 回复音乐信息
* @param string $content 要回复的音乐
*/
private static function music($music)
{
list(
$music['Title'],
$music['Description'],
$music['MusicUrl'],
$music['HQMusicUrl'],
$music['ThumbMediaId']
) = $music;
self::$response['Music'] = $music;
}
/**
* 回复图文列表消息
* @param [type] $content [description]
*/
private static function news($news)
{
$articles = [];
foreach ($news as $key => $value) {
list(
$articles[$key]['Title'],
$articles[$key]['Description'],
$articles[$key]['PicUrl'],
$articles[$key]['Url']
) = $value;
if ($key >= 9) {
break;
}
}
self::$response['ArticleCount'] = count($articles);
self::$response['Articles'] = $articles;
}
/**
* 将消息转发至客服
* @param string $account 指定的客服账号
* @return xml
*/
public static function transfer($account = '')
{
self::$response = [
'ToUserName' => self::$request['fromusername'],
'FromUserName' => self::$request['tousername'],
'CreateTime' => time(),
'MsgType' => 'transfer_customer_service',
];
if (!empty($account)) {
self::$response['TransInfo']['KfAccount'] = $account;
}
$response = Utils::array2xml(self::$response);
exit($response);
}
}

View File

@@ -0,0 +1,30 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
* 语义理解
*/
class Semantic extends Wechat
{
/**
* 接口名称与URL映射
* @var array
*/
protected static $url = [
'semproxy' => 'https://api.weixin.qq.com/semantic/semproxy/search',
];
public static function search()
{
#Todo..
}
}

View File

@@ -0,0 +1,255 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
* 客服相关接口
*/
class Service extends Wechat
{
/**
* 接口名称与URL映射
* @var array
*/
protected static $url = [
'service_list' => 'https://api.weixin.qq.com/cgi-bin/customservice/getkflist',
'online_list' => 'https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist',
'service_add' => 'https://api.weixin.qq.com/customservice/kfaccount/add',
'service_update' => 'https://api.weixin.qq.com/customservice/kfaccount/update',
'service_delete' => 'https://api.weixin.qq.com/customservice/kfaccount/del',
'invite_worker' => 'https://api.weixin.qq.com/customservice/kfaccount/inviteworker',
'upload_avatr' => 'http://api.weixin.qq.com/customservice/kfaccount/uploadheadimg',
'msg_record' => 'https://api.weixin.qq.com/customservice/msgrecord/getrecord',
'custom_send' => 'https://api.weixin.qq.com/cgi-bin/message/custom/send',
'session_create' => 'https://api.weixin.qq.com/customservice/kfsession/create',
'session_close' => 'https://api.weixin.qq.com/customservice/kfsession/close',
'session_get' => 'https://api.weixin.qq.com/customservice/kfsession/getsession',
'session_list' => 'https://api.weixin.qq.com/customservice/kfsession/getsessionlist',
'session_wait' => 'https://api.weixin.qq.com/customservice/kfsession/getwaitcase',
];
/**
* 获取客服列表
* @return array|boolean
*/
public static function get()
{
$result = Utils::api(self::$url['service_list'] . '?access_token=' . parent::$config['access_token']);
if ($result) {
return $result['kf_list'];
} else {
return false;
}
}
/**
* 获取在线客服
* @return array|boolean
*/
public static function online()
{
$result = Utils::api(self::$url['online_list'] . '?access_token=' . parent::$config['access_token']);
if ($result) {
return $result['kf_online_list'];
} else {
return false;
}
}
/**
* 添加客服账号
* @param string $account
* @param string $nickname
*/
public static function add($account, $nickname)
{
$params = [
'kf_account' => $account . '@' . parent::$config['appid'],
'nickname' => $nickname,
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
return Utils::api(self::$url['service_add'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
/**
* 修改客服账号
* @param string $account
* @param string $nickname
* @param string $password
* @return boolean
*/
public static function update($account, $nickname)
{
$params = [
'kf_account' => $account,
'nickname' => $nickname,
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
return Utils::api(self::$url['service_update'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
/**
* 删除客服账号
* @param string $account
* @return boolean
*/
public static function delete($account)
{
$params = [
'kf_account' => $account,
'access_token' => parent::$config['access_token'],
];
return Utils::api(self::$url['service_delete'], $params);
}
/**
* 邀请绑定客服
* @param string $account
* @param string $weixin
* @return boolean
*/
public static function invite($account, $weixin)
{
$params = [
'kf_account' => $account,
'invite_wx' => $weixin,
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
return Utils::api(self::$url['invite_worker'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
/**
* 获取客服聊天记录
* @param integer $starttime
* @param integer $endtime
* @param integer $pageindex
* @param integer $pagesize
* @return array|boolean
*/
public static function record($starttime, $endtime, $pageindex = 1, $pagesize = 50)
{
$params = [
'starttime' => $starttime,
'endtime' => $endtime,
'pageindex' => $pageindex,
'pagesize' => $pagesize,
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
$result = Utils::api(self::$url['msg_record'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
if ($result) {
return $result['recordlist'];
} else {
return false;
}
}
/**
* 发送客服消息
* @param string $openid
* @param string $type
* @param string $content
* @return boolean
*/
public static function send($openid, $type, $content)
{
$params = [
'touser' => $openid,
'msgtype' => $type,
'text' => [
'content' => $content,
],
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
return Utils::api(self::$url['custom_send'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
/**
* 创建会话
* @param string $account 完整客服账号
* @param string $openid 客户openid
* @return boolean
*/
public static function session_create($account, $openid)
{
$params = [
'kf_account' => $account,
'openid' => $openid,
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
return Utils::api(self::$url['session_create'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
/**
* 关闭会话
* @param string $account 完整客服账号
* @param string $openid 客户openid
* @return boolean
*/
public static function session_close($account, $openid)
{
$params = [
'kf_account' => $account,
'openid' => $openid,
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
return Utils::api(self::$url['session_close'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
/**
* 获取客户的会话状态
* @param string $openid 客户openid
* @return array
*/
public static function session_get($openid)
{
$params = [
'openid' => $openid,
'access_token' => parent::$config['access_token'],
];
return Utils::api(self::$url['session_get'], $params);
}
/**
* 获取客服的会话列表
* @param string $account
* @return array
*/
public static function session_list($account)
{
$params = [
'kf_account' => $account,
'access_token' => parent::$config['access_token'],
];
$result = Utils::api(self::$url['session_list'], $params);
if ($result) {
return $result['sessionlist'];
} else {
return false;
}
}
/**
* 获取未接入会话列表
* @return array
*/
public static function session_wait()
{
$params = [
'access_token' => parent::$config['access_token'],
];
$result = Utils::api(self::$url['session_wait'], $params);
if ($result) {
return $result['waitcaselist'];
} else {
return false;
}
}
}

View File

@@ -0,0 +1,111 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
* 模板消息
*/
class Template extends Wechat
{
/**
* 接口名称与URL映射
* @var array
*/
protected static $url = [
'set_industry' => 'https://api.weixin.qq.com/cgi-bin/template/api_set_industry', // 设置所属行业
'get_industry' => 'https://api.weixin.qq.com/cgi-bin/template/get_industry', // 获取设置的行业信息
'add_template' => 'https://api.weixin.qq.com/cgi-bin/template/api_add_template', // 获得模板ID
'get_template' => 'https://api.weixin.qq.com/cgi-bin/template/get_all_private_template', // 获取模板列表
'del_template' => 'https://api.weixin.qq.com/cgi-bin/template/del_private_template', // 删除模板
'send_template' => 'https://api.weixin.qq.com/cgi-bin/message/template/send', // 发送模板消息
];
/**
* 设置所属行业
* @param [type] $industry1 [description]
* @param [type] $industry2 [description]
*/
public static function setIndustry($primary, $secondary)
{
$params = [
'industry_id1' => $primary,
'industry_id2' => $secondary,
];
$params = json_encode($params);
return Utils::api(self::$url['set_industry'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
/**
* 获取设置的行业信息
* @return [type] [description]
*/
public static function getIndustry()
{
return Utils::api(self::$url['get_industry'] . '?access_token=' . parent::$config['access_token'], '', 'GET');
}
/**
* 获得模板ID
* @return [type] [description]
*/
public static function add($shortTemplateId)
{
$params = [
'template_id_short' => $shortTemplateId,
];
$params = json_encode($params);
return Utils::api(self::$url['add_template'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
/**
* 获取模板列表
* @return [type] [description]
*/
public static function get()
{
return Utils::api(self::$url['get_template'] . '?access_token=' . parent::$config['access_token'], '', 'GET');
}
/**
* 删除模板
* @param [type] $templateId 长模板ID 例Dyvp3-Ff0cnail_CDSzk1fIc6-9lOkxsQE7exTJbwUE
* @return boolean
*/
public static function delete($templateId)
{
$params = [
'template_id' => $templateId,
];
$params = json_encode($params);
return Utils::api(self::$url['del_template'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
/**
* 发送模板消息
* @param [type] $openid 接收用户
* @param [type] $templateId 模板ID
* @param array $data 消息体
* @param string $url 连接URL
* @return boolean
*/
public static function send($openid, $templateId, $data = [], $url = '')
{
$params = [
'touser' => $openid,
'template_id' => $templateId,
'url' => $url,
'data' => $data,
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
return Utils::api(self::$url['send_template'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
}

View File

@@ -0,0 +1,65 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
* ACCESS TOKEN获取
*/
class Token extends Wechat
{
/**
* 接口名称与URL映射
* @var array
*/
protected static $url = [
'access_token' => 'https://api.weixin.qq.com/cgi-bin/token', // 获取ACCESS_TOKEN
'jsapi_ticket' => 'https://api.weixin.qq.com/cgi-bin/ticket/getticket', // JSAPI_TICKET获取地址
];
/**
* 获取ACCESS_TOKEN
* @return [type] [description]
*/
public static function get()
{
$params = [
'appid' => parent::$config['appid'],
'secret' => parent::$config['secret'],
'grant_type' => 'client_credential',
];
$result = Utils::api(self::$url['access_token'], $params);
if ($result) {
return $result['access_token'];
} else {
return false;
}
}
/**
* 获取JSAPI_TICKET
* @return [type] [description]
*/
public static function ticket()
{
$params = [
'access_token' => parent::$config['access_token'],
'type' => 'jsapi',
];
$result = Utils::http(self::$url['jsapi_ticket'], $params);
if ($result) {
$result = json_decode($result, true);
return $result['ticket'];
} else {
return false;
}
}
}

135
vendor/cjango/wechat/src/Wechat/User.php vendored Normal file
View File

@@ -0,0 +1,135 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
* 用户管理
*/
class User extends Wechat
{
/**
* 接口名称与URL映射
* @var array
*/
protected static $url = [
'user_get' => 'https://api.weixin.qq.com/cgi-bin/user/get',
'user_info' => 'https://api.weixin.qq.com/cgi-bin/user/info',
'user_info_batch' => 'https://api.weixin.qq.com/cgi-bin/user/info/batchget',
'user_remark' => 'https://api.weixin.qq.com/cgi-bin/user/info/updateremark',
'user_in_group' => 'https://api.weixin.qq.com/cgi-bin/groups/getid',
'user_to_group' => 'https://api.weixin.qq.com/cgi-bin/groups/members/update',
'batch_to_group' => 'https://api.weixin.qq.com/cgi-bin/groups/members/batchupdate',
];
/**
* 获取全部关注用户
* @param [type] $nextOpenid [description]
*/
public static function get($nextOpenid = '')
{
$params = [
'next_openid' => $nextOpenid,
'access_token' => parent::$config['access_token'],
];
$result = Utils::api(self::$url['user_get'], $params);
if ($result) {
return $result['data']['openid'];
} else {
return false;
}
}
/**
* 获取用户信息
* @param [type] $openid [description]
* @param [type] $lang [description]
* @return [type] [description]
*/
public static function info($openid, $lang = 'zh_CN')
{
$params = [
'openid' => $openid,
'access_token' => parent::$config['access_token'],
'lang' => $lang,
];
$result = Utils::api(self::$url['user_info'], $params);
if ($result) {
return $result;
} else {
return false;
}
}
/**
* 设置用户备注名
* @param [type] $openid
* @param [type] $remark
* @return [type]
*/
public static function remark($openid, $remark)
{
$params = [
'openid' => $openid,
'remark' => $remark,
];
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
return Utils::api(self::$url['user_remark'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
/**
* 查询用户所在分组
* @param [type] $openid [description]
* @return [type] [description]
*/
public static function getgroup($openid)
{
$params = [
'openid' => $openid,
];
$params = json_encode($params);
$result = Utils::api(self::$url['user_in_group'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
if ($result) {
return $result['groupid'];
} else {
return false;
}
}
/**
* 移动用户分组
*/
public static function togroup($openid, $groupid)
{
$params = [
'openid' => $openid,
'to_groupid' => $groupid,
];
$params = json_encode($params);
return Utils::api(self::$url['user_to_group'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
/**
* 批量移动用户分组
* @param array $openid_list [description]
* @param [type] $groupid [description]
* @return [type] [description]
*/
public static function batchgroup($openid_list = [], $groupid)
{
$params = [
'openid_list' => $openid_list,
'to_groupid' => $groupid,
];
$params = json_encode($params);
return Utils::api(self::$url['batch_to_group'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
}
}

View File

@@ -0,0 +1,325 @@
<?php
// +------------------------------------------------+
// |http://www.cjango.com |
// +------------------------------------------------+
// | 修复BUG不是一朝一夕的事情等我喝醉了再说吧 |
// +------------------------------------------------+
// | Author: 小陈叔叔 <Jason.Chen> |
// +------------------------------------------------+
namespace cjango\Wechat;
use cjango\Wechat;
/**
*
*/
class Utils
{
/**
* 错误信息
* @var array
*/
private static $errMsg = [
-1 => '系统繁忙,此时请开发者稍候再试',
0 => '请求成功',
40001 => '获取access_token时AppSecret错误或者access_token无效。请开发者认真比对AppSecret的正确性或查看是否正在为恰当的公众号调用接口',
40002 => '不合法的凭证类型',
40003 => '不合法的OpenID请开发者确认OpenID该用户是否已关注公众号或是否是其他公众号的OpenID',
40004 => '不合法的媒体文件类型',
40005 => '不合法的文件类型',
40006 => '不合法的文件大小',
40007 => '不合法的媒体文件id',
40008 => '不合法的消息类型',
40009 => '不合法的图片文件大小',
40010 => '不合法的语音文件大小',
40011 => '不合法的视频文件大小',
40012 => '不合法的缩略图文件大小',
40013 => '不合法的AppID请开发者检查AppID的正确性避免异常字符注意大小写',
40014 => '不合法的access_token请开发者认真比对access_token的有效性如是否过期或查看是否正在为恰当的公众号调用接口',
40015 => '不合法的菜单类型',
40016 => '不合法的按钮个数',
40017 => '不合法的按钮个数',
40018 => '不合法的按钮名字长度',
40019 => '不合法的按钮KEY长度',
40020 => '不合法的按钮URL长度',
40021 => '不合法的菜单版本号',
40022 => '不合法的子菜单级数',
40023 => '不合法的子菜单按钮个数',
40024 => '不合法的子菜单按钮类型',
40025 => '不合法的子菜单按钮名字长度',
40026 => '不合法的子菜单按钮KEY长度',
40027 => '不合法的子菜单按钮URL长度',
40028 => '不合法的自定义菜单使用用户',
40029 => '不合法的oauth_code',
40030 => '不合法的refresh_token',
40031 => '不合法的openid列表',
40032 => '不合法的openid列表长度',
40033 => '不合法的请求字符,不能包含\uxxxx格式的字符',
40035 => '不合法的参数',
40038 => '不合法的请求格式',
40039 => '不合法的URL长度',
40050 => '不合法的分组id',
40051 => '分组名字不合法',
40117 => '分组名字不合法',
40118 => 'media_id大小不合法',
40119 => 'button类型错误',
40120 => 'button类型错误',
40121 => '不合法的media_id类型',
40132 => '微信号不合法',
40137 => '不支持的图片格式',
41001 => '缺少access_token参数',
41002 => '缺少appid参数',
41003 => '缺少refresh_token参数',
41004 => '缺少secret参数',
41005 => '缺少多媒体文件数据',
41006 => '缺少media_id参数',
41007 => '缺少子菜单数据',
41008 => '缺少oauth code',
41009 => '缺少openid',
42001 => 'access_token超时请检查access_token的有效期',
42002 => 'refresh_token超时',
42003 => 'oauth_code超时',
42007 => '用户修改微信密码accesstoken和refreshtoken失效需要重新授权',
43001 => '需要GET请求',
43002 => '需要POST请求',
43003 => '需要HTTPS请求',
43004 => '需要接收者关注',
43005 => '需要好友关系',
44001 => '多媒体文件为空',
44002 => 'POST的数据包为空',
44003 => '图文消息内容为空',
44004 => '文本消息内容为空',
45001 => '多媒体文件大小超过限制',
45002 => '消息内容超过限制',
45003 => '标题字段超过限制',
45004 => '描述字段超过限制',
45005 => '链接字段超过限制',
45006 => '图片链接字段超过限制',
45007 => '语音播放时间超过限制',
45008 => '图文消息超过限制',
45009 => '接口调用超过限制',
45010 => '创建菜单个数超过限制',
45015 => '回复时间超过限制',
45016 => '系统分组,不允许修改',
45017 => '分组名字过长',
45018 => '分组数量超过上限',
45047 => '客服接口下行条数超过上限',
46001 => '不存在媒体数据',
46002 => '不存在的菜单版本',
46003 => '不存在的菜单数据',
46004 => '不存在的用户',
47001 => '解析JSON/XML内容错误',
48001 => 'api功能未授权请确认公众号已获得该接口可以在公众平台官网-开发者中心页中查看接口权限',
48004 => 'api接口被封禁请登录mp.weixin.qq.com查看详情',
48005 => 'api禁止删除被自动回复和自定义菜单引用的素材',
48006 => 'api禁止清零调用次数因为清零次数达到上限',
50001 => '用户未授权该api',
50002 => '用户受限,可能是违规后接口被封禁',
61450 => '客服系统错误',
61451 => '参数错误',
61452 => '无效客服账号',
61453 => '客服帐号已存在',
61454 => '客服帐号名长度超过限制(仅允许10个英文字符不包括@及@后的公众号的微信号)',
61455 => '客服帐号名包含非法字符(仅允许英文+数字)',
61456 => '客服帐号个数超过限制(10个客服账号)',
61457 => '无效头像文件类型',
61458 => '客户正在被其他客服接待',
61459 => '客服不在线',
61500 => '日期格式错误',
65301 => '不存在此menuid对应的个性化菜单',
65302 => '没有相应的用户',
65303 => '没有默认菜单,不能创建个性化菜单',
65304 => 'MatchRule信息为空',
65305 => '个性化菜单数量受限',
65306 => '不支持个性化菜单的帐号',
65307 => '个性化菜单信息为空',
65308 => '包含没有响应类型的button',
65309 => '个性化菜单开关处于关闭状态',
65310 => '填写了省份或城市信息,国家信息不能为空',
65311 => '填写了城市信息,省份信息不能为空',
65312 => '不合法的国家信息',
65313 => '不合法的省份信息',
65314 => '不合法的城市信息',
65316 => '该公众号的菜单设置了过多的域名外跳最多跳转到3个域名的链接',
65317 => '不合法的URL',
65400 => 'API不可用即没有开通/升级到新版客服',
65401 => '无效客服帐号',
65402 => '客服帐号尚未绑定微信号,不能投入使用',
65403 => '客服昵称不合法',
65404 => '客服帐号不合法',
65405 => '帐号数目已达到上限,不能继续添加',
65406 => '已经存在的客服帐号',
65407 => '邀请对象已经是本公众号客服',
65408 => '本公众号已发送邀请给该微信号',
65409 => '无效的微信号',
65410 => '邀请对象绑定公众号客服数量达到上限',
65411 => '该帐号已经有一个等待确认的邀请,不能重复邀请',
65412 => '该帐号已经绑定微信号,不能进行邀请',
65413 => '不存在对应用户的会话信息',
65414 => '粉丝正在被其他客服接待',
65415 => '指定的客服不在线',
9001001 => 'POST数据参数不合法',
9001002 => '远端服务不可用',
9001003 => 'Ticket不合法',
9001004 => '获取摇周边用户信息失败',
9001005 => '获取商户信息失败',
9001006 => '获取OpenID失败',
9001007 => '上传文件缺失',
9001008 => '上传素材的文件类型不合法',
9001009 => '上传素材的文件尺寸不合法',
9001010 => '上传失败',
9001020 => '帐号不合法',
9001021 => '已有设备激活率低于50%,不能新增设备',
9001022 => '设备申请数不合法必须为大于0的数字',
9001023 => '已存在审核中的设备ID申请',
9001024 => '一次查询设备ID数量不能超过50',
9001025 => '设备ID不合法',
9001026 => '页面ID不合法',
9001027 => '页面参数不合法',
9001028 => '一次删除页面ID数量不能超过10',
9001029 => '页面已应用在设备中,请先解除应用关系再删除',
9001030 => '一次查询页面ID数量不能超过50',
9001031 => '时间区间不合法',
9001032 => '保存设备与页面的绑定关系参数错误',
9001033 => '门店ID不合法',
9001034 => '设备备注信息过长',
9001035 => '设备申请参数不合法',
9001036 => '查询起始值begin不合法',
];
/**
* 返回数据结果集
* @var mixed
*/
public static $result;
public static function api($url, $params = [], $method = 'GET')
{
$result = self::http($url, $params, $method);
return self::parseRequestJson($result);
}
/**
* 发送HTTP请求方法目前只支持CURL发送请求
* @param string $url 请求URL
* @param array $params 请求参数
* @param string $method 请求方法GET/POST
* @param boolean $ssl 是否进行SSL双向认证
* @return array $data 响应数据
*/
public static function http($url, $params = [], $method = 'GET', $ssl = false)
{
$opts = [
CURLOPT_TIMEOUT => 30,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
];
/* 根据请求类型设置特定参数 */
switch (strtoupper($method)) {
case 'GET':
$getQuerys = !empty($params) ? '?' . urldecode(http_build_query($params)) : '';
$opts[CURLOPT_URL] = $url . $getQuerys;
break;
case 'POST':
$opts[CURLOPT_URL] = $url;
$opts[CURLOPT_POST] = 1;
$opts[CURLOPT_POSTFIELDS] = $params;
break;
}
/* 初始化并执行curl请求 */
$ch = curl_init();
curl_setopt_array($ch, $opts);
$data = curl_exec($ch);
$err = curl_errno($ch);
$errmsg = curl_error($ch);
curl_close($ch);
if ($err > 0) {
\cjango\Wechat::error('CURL:' . $errmsg);
return false;
} else {
return $data;
}
}
/**
* XML文档解析成数组并将键值转成小写
* @param xml $xml
* @return array
*/
public static function xml2array($xml)
{
$data = (array) simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
return array_change_key_case($data, CASE_LOWER);
}
/**
* 将数组转换成XML
* @param array $array
* @return xml
*/
public static function array2xml($array = [])
{
$xml = new \SimpleXMLElement('<xml></xml>');
self::_data2xml($xml, $array);
return $xml->asXML();
}
/**
* 数据XML编码
* @param xml $xml XML对象
* @param mixed $data 数据
* @param string $item 数字索引时的节点名称
* @return string xml
*/
private static function _data2xml($xml, $data, $item = 'item')
{
foreach ($data as $key => $value) {
is_numeric($key) && $key = $item;
if (is_array($value) || is_object($value)) {
$child = $xml->addChild($key);
self::_data2xml($child, $value, $item);
} else {
if (is_numeric($value)) {
$child = $xml->addChild($key, $value);
} else {
$child = $xml->addChild($key);
$node = dom_import_simplexml($child);
$node->appendChild($node->ownerDocument->createCDATASection($value));
}
}
}
}
/**
* 解析返回的json数据
* @param [type] $json
* @return
*/
private static function parseRequestJson($json)
{
$result = json_decode($json, true);
if (isset($result['errcode'])) {
if ($result['errcode'] == 0) {
self::$result = $result;
return true;
} else {
Wechat::error(self::parseError($result));
return false;
}
} else {
return $result;
}
}
/**
* 解析错误信息
* @param array $result
* @return string
*/
public static function parseError($result)
{
$code = $result['errcode'];
return '[' . $code . '] ' . (isset(self::$errMsg[$code]) ? self::$errMsg[$code] : $result['errmsg']);
}
}