first commit
This commit is contained in:
24
vendor/cjango/wechat/composer.json
vendored
Normal file
24
vendor/cjango/wechat/composer.json
vendored
Normal 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/"
|
||||
}
|
||||
}
|
||||
}
|
||||
116
vendor/cjango/wechat/src/Wechat.php
vendored
Normal file
116
vendor/cjango/wechat/src/Wechat.php
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getConfig($key)
|
||||
{
|
||||
return self::$config[$key] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
}
|
||||
50
vendor/cjango/wechat/src/Wechat/Card.php
vendored
Normal file
50
vendor/cjango/wechat/src/Wechat/Card.php
vendored
Normal 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..
|
||||
}
|
||||
}
|
||||
41
vendor/cjango/wechat/src/Wechat/Datacube.php
vendored
Normal file
41
vendor/cjango/wechat/src/Wechat/Datacube.php
vendored
Normal 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',
|
||||
];
|
||||
}
|
||||
100
vendor/cjango/wechat/src/Wechat/Group.php
vendored
Normal file
100
vendor/cjango/wechat/src/Wechat/Group.php
vendored
Normal 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');
|
||||
}
|
||||
}
|
||||
51
vendor/cjango/wechat/src/Wechat/Material.php
vendored
Normal file
51
vendor/cjango/wechat/src/Wechat/Material.php
vendored
Normal 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..
|
||||
}
|
||||
}
|
||||
70
vendor/cjango/wechat/src/Wechat/Menu.php
vendored
Normal file
70
vendor/cjango/wechat/src/Wechat/Menu.php
vendored
Normal 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);
|
||||
}
|
||||
}
|
||||
83
vendor/cjango/wechat/src/Wechat/Oauth.php
vendored
Normal file
83
vendor/cjango/wechat/src/Wechat/Oauth.php
vendored
Normal 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);
|
||||
}
|
||||
}
|
||||
356
vendor/cjango/wechat/src/Wechat/Pay.php
vendored
Normal file
356
vendor/cjango/wechat/src/Wechat/Pay.php
vendored
Normal file
@@ -0,0 +1,356 @@
|
||||
<?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 * 100,
|
||||
'refund_fee' => $refund_fee * 100,
|
||||
'op_user_id' => parent::$config['mch_id'],
|
||||
'nonce_str' => uniqid(),
|
||||
];
|
||||
|
||||
$params['sign'] = self::_getOrderSign($params);
|
||||
|
||||
$data = Utils::array2xml($params);
|
||||
$result = Utils::http(self::$url['refund_order'], $data, 'POST', true);
|
||||
|
||||
if ($result) {
|
||||
$result = self::parsePayResult(Utils::xml2array($result));
|
||||
if ($result) {
|
||||
return $result;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 企业付款
|
||||
* @param [type] $orderId [description]
|
||||
* @param [type] $openid [description]
|
||||
* @param [type] $amount [description]
|
||||
* @param [type] $remark [description]
|
||||
* @return [type] [description]
|
||||
*/
|
||||
public static function transfers($orderId, $openid, $amount, $remark)
|
||||
{
|
||||
$params = [
|
||||
'mch_appid' => parent::$config['appid'],
|
||||
'mchid' => parent::$config['mch_id'],
|
||||
'partner_trade_no' => $orderId,
|
||||
'openid' => $openid,
|
||||
'check_name' => 'NO_CHECK',
|
||||
'amount' => $amount * 100,
|
||||
'desc' => $remark,
|
||||
'spbill_create_ip' => self::_getClientIp(),
|
||||
'nonce_str' => uniqid(),
|
||||
];
|
||||
$params['sign'] = self::_getOrderSign($params);
|
||||
$data = Utils::array2xml($params);
|
||||
$data = Utils::http(self::$url['pay_transfers'], $data, 'POST', true);
|
||||
$result = self::parsePayResult(Utils::xml2array($data));
|
||||
if ($result) {
|
||||
return $result;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [redpack description]
|
||||
* @param [type] $orderId [description]
|
||||
* @param [type] $openid [description]
|
||||
* @param [type] $money [description]
|
||||
* @param [type] $sendName [description]
|
||||
* @param [type] $wishing [description]
|
||||
* @param [type] $remark [description]
|
||||
* @return [type] [description]
|
||||
*/
|
||||
public static function redpack($orderId, $openid, $money, $sendName, $wishing, $actName, $remark)
|
||||
{
|
||||
$params = [
|
||||
'nonce_str' => uniqid(),
|
||||
'mch_id' => parent::$config['mch_id'],
|
||||
'mch_billno' => $orderId,
|
||||
'wxappid' => parent::$config['appid'],
|
||||
'send_name' => $sendName,
|
||||
're_openid' => $openid,
|
||||
'total_amount' => $money * 100,
|
||||
'total_num' => 1,
|
||||
'wishing' => $wishing,
|
||||
'act_name' => $actName,
|
||||
'client_ip' => self::_getClientIp(),
|
||||
'remark' => $remark,
|
||||
];
|
||||
|
||||
$params['sign'] = self::_getOrderSign($params);
|
||||
|
||||
$data = Utils::array2xml($params);
|
||||
$data = Utils::http(self::$url['send_red_pack'], $data, 'POST', true);
|
||||
$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_des']);
|
||||
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))));
|
||||
}
|
||||
}
|
||||
99
vendor/cjango/wechat/src/Wechat/QRcode.php
vendored
Normal file
99
vendor/cjango/wechat/src/Wechat/QRcode.php
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
<?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_STR_SCENE',
|
||||
// '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;
|
||||
}
|
||||
}
|
||||
}
|
||||
170
vendor/cjango/wechat/src/Wechat/Reply.php
vendored
Normal file
170
vendor/cjango/wechat/src/Wechat/Reply.php
vendored
Normal 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);
|
||||
}
|
||||
}
|
||||
30
vendor/cjango/wechat/src/Wechat/Semantic.php
vendored
Normal file
30
vendor/cjango/wechat/src/Wechat/Semantic.php
vendored
Normal 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..
|
||||
}
|
||||
}
|
||||
255
vendor/cjango/wechat/src/Wechat/Service.php
vendored
Normal file
255
vendor/cjango/wechat/src/Wechat/Service.php
vendored
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
vendor/cjango/wechat/src/Wechat/Share.php
vendored
Normal file
41
vendor/cjango/wechat/src/Wechat/Share.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
// +------------------------------------------------+
|
||||
// |http://www.cjango.com |
|
||||
// +------------------------------------------------+
|
||||
// | 修复BUG不是一朝一夕的事情,等我喝醉了再说吧! |
|
||||
// +------------------------------------------------+
|
||||
// | Author: 小陈叔叔 <Jason.Chen> |
|
||||
// +------------------------------------------------+
|
||||
namespace cjango\Wechat;
|
||||
|
||||
use cjango\Wechat;
|
||||
|
||||
/**
|
||||
* 微信分享
|
||||
*/
|
||||
class Share extends Wechat
|
||||
{
|
||||
|
||||
public static function config($ticket, $url = '')
|
||||
{
|
||||
if (empty($url)) {
|
||||
$url = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
|
||||
}
|
||||
$signArr = [
|
||||
'timestamp' => time(),
|
||||
'noncestr' => uniqid(),
|
||||
'jsapi_ticket' => $ticket,
|
||||
'url' => $url,
|
||||
];
|
||||
|
||||
ksort($signArr);
|
||||
$signature = sha1(urldecode(http_build_query($signArr)));
|
||||
|
||||
return [
|
||||
'appId' => parent::$config['appid'],
|
||||
'timestamp' => $signArr['timestamp'],
|
||||
'nonceStr' => $signArr['noncestr'],
|
||||
'signature' => $signature,
|
||||
];
|
||||
}
|
||||
}
|
||||
112
vendor/cjango/wechat/src/Wechat/Template.php
vendored
Normal file
112
vendor/cjango/wechat/src/Wechat/Template.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<?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 = '', $topcolor = '')
|
||||
{
|
||||
$params = [
|
||||
'touser' => $openid,
|
||||
'template_id' => $templateId,
|
||||
'url' => $url,
|
||||
'topcolor' => $topcolor,
|
||||
'data' => $data,
|
||||
];
|
||||
$params = json_encode($params, JSON_UNESCAPED_UNICODE);
|
||||
return Utils::api(self::$url['send_template'] . '?access_token=' . parent::$config['access_token'], $params, 'POST');
|
||||
}
|
||||
}
|
||||
65
vendor/cjango/wechat/src/Wechat/Token.php
vendored
Normal file
65
vendor/cjango/wechat/src/Wechat/Token.php
vendored
Normal 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
135
vendor/cjango/wechat/src/Wechat/User.php
vendored
Normal 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');
|
||||
}
|
||||
}
|
||||
343
vendor/cjango/wechat/src/Wechat/Utils.php
vendored
Normal file
343
vendor/cjango/wechat/src/Wechat/Utils.php
vendored
Normal file
@@ -0,0 +1,343 @@
|
||||
<?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;
|
||||
}
|
||||
if ($ssl) {
|
||||
$pemPath = dirname(__FILE__) . '/cert/';
|
||||
$pemCret = $pemPath . 'apiclient_cert.pem';
|
||||
$pemKey = $pemPath . 'apiclient_key.pem';
|
||||
if (!file_exists($pemCret)) {
|
||||
Wechat::error('证书不存在');
|
||||
return false;
|
||||
}
|
||||
if (!file_exists($pemKey)) {
|
||||
Wechat::error('秘钥不存在');
|
||||
return false;
|
||||
}
|
||||
$opts[CURLOPT_SSLCERTTYPE] = 'PEM';
|
||||
$opts[CURLOPT_SSLCERT] = $pemCret;
|
||||
$opts[CURLOPT_SSLKEYTYPE] = 'PEM';
|
||||
$opts[CURLOPT_SSLKEY] = $pemKey;
|
||||
}
|
||||
|
||||
/* 初始化并执行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) {
|
||||
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']);
|
||||
}
|
||||
}
|
||||
26
vendor/cjango/wechat/src/Wechat/cert/apiclient_cert.pem
vendored
Normal file
26
vendor/cjango/wechat/src/Wechat/cert/apiclient_cert.pem
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEZjCCA8+gAwIBAgIEAV7+MTANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
|
||||
Q04xEjAQBgNVBAgTCUd1YW5nZG9uZzERMA8GA1UEBxMIU2hlbnpoZW4xEDAOBgNV
|
||||
BAoTB1RlbmNlbnQxDDAKBgNVBAsTA1dYRzETMBEGA1UEAxMKTW1wYXltY2hDQTEf
|
||||
MB0GCSqGSIb3DQEJARYQbW1wYXltY2hAdGVuY2VudDAeFw0xNzA3MDMwNTM1Mjda
|
||||
Fw0yNzA3MDEwNTM1MjdaMIGVMQswCQYDVQQGEwJDTjESMBAGA1UECBMJR3Vhbmdk
|
||||
b25nMREwDwYDVQQHEwhTaGVuemhlbjEQMA4GA1UEChMHVGVuY2VudDEOMAwGA1UE
|
||||
CxMFTU1QYXkxKjAoBgNVBAMUIeWTiOWwlOa7qOWmguacl+enkeaKgOaciemZkOWF
|
||||
rOWPuDERMA8GA1UEBBMIMTI1ODc3MTcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||
ggEKAoIBAQDHIiouN3Cx+hiHz7euQms6cUb2EwH7mMS9PjONMoFWHuxM9js/jhse
|
||||
ZZytK6uAlWmV3Q2f/DqdBfjXITrAkQ0aWSLV+CpmOHta04v5cQ36jDD7h/uU9/rl
|
||||
leCtO7tdenHxQqOjVCkYjxKrn/ULvYQniIjsgf1TqP0mYOK/SBdxAad4vSSiPDWT
|
||||
FR1AGGUuYqXdeAONiryH6QEq02SkPp/Pr+uTaT3ks8rIFcDYMQ/lSV4n471pL0uB
|
||||
MFVif6KDRTHyeR6uqx1wpAeamtARYym4Dp29vz4wHWUeBV9vlxICtwJiS0zc1TOZ
|
||||
r5So3wueryrTpF0BUFNcbgHcO0QwBJKrAgMBAAGjggFGMIIBQjAJBgNVHRMEAjAA
|
||||
MCwGCWCGSAGG+EIBDQQfFh0iQ0VTLUNBIEdlbmVyYXRlIENlcnRpZmljYXRlIjAd
|
||||
BgNVHQ4EFgQUlhqRbkz7BenlVU2sUiJvs8jiE1gwgb8GA1UdIwSBtzCBtIAUPgUm
|
||||
9iJitBVbiM1kfrDUYqflhnShgZCkgY0wgYoxCzAJBgNVBAYTAkNOMRIwEAYDVQQI
|
||||
EwlHdWFuZ2RvbmcxETAPBgNVBAcTCFNoZW56aGVuMRAwDgYDVQQKEwdUZW5jZW50
|
||||
MQwwCgYDVQQLEwNXWEcxEzARBgNVBAMTCk1tcGF5bWNoQ0ExHzAdBgkqhkiG9w0B
|
||||
CQEWEG1tcGF5bWNoQHRlbmNlbnSCCQC7VJcrvADoVzAOBgNVHQ8BAf8EBAMCBsAw
|
||||
FgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAhB7qokkF
|
||||
mSEkeW++OzZt3WAHwjDM/6HkyvYkuJCS45Y1CeKUZ65kXpi/eFYVI2T351rr7ZJC
|
||||
W+Rw42UUrx4Q50S9dlTxCkH0ycrAySsJDuYWB6F0TbYqlPDk579BQeUwVJBaycHy
|
||||
idGG/7Enb5yzFiAGujUUmiW5LWNulhGMoig=
|
||||
-----END CERTIFICATE-----
|
||||
28
vendor/cjango/wechat/src/Wechat/cert/apiclient_key.pem
vendored
Normal file
28
vendor/cjango/wechat/src/Wechat/cert/apiclient_key.pem
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDHIiouN3Cx+hiH
|
||||
z7euQms6cUb2EwH7mMS9PjONMoFWHuxM9js/jhseZZytK6uAlWmV3Q2f/DqdBfjX
|
||||
ITrAkQ0aWSLV+CpmOHta04v5cQ36jDD7h/uU9/rlleCtO7tdenHxQqOjVCkYjxKr
|
||||
n/ULvYQniIjsgf1TqP0mYOK/SBdxAad4vSSiPDWTFR1AGGUuYqXdeAONiryH6QEq
|
||||
02SkPp/Pr+uTaT3ks8rIFcDYMQ/lSV4n471pL0uBMFVif6KDRTHyeR6uqx1wpAea
|
||||
mtARYym4Dp29vz4wHWUeBV9vlxICtwJiS0zc1TOZr5So3wueryrTpF0BUFNcbgHc
|
||||
O0QwBJKrAgMBAAECggEBAJcH+In5DoZOM1C+YIfQZFd9Ft8H55cVdRI7HQpYZfQV
|
||||
nA97KdC4TSUu2DgXSQpLSDub3vuaaDI0F1nDIDZxTUjQljVG9ZF2AUkP7bgQ4RNI
|
||||
RNZhepSvyCFdHX0GMsNhXQ4pBseXy1uPGBAHT+nJoXQCgCcxKBvNrcLv9MozOWRB
|
||||
EG/Nt0d7/Pge5kougSUvngUNdihFiAcKshw9in511INXTU9xk+E8f+Gd9tNBax77
|
||||
5cl8bUMXrQibm/JXYyAClwfAwe33ygdu8C1BqDZhE+T6zd+Ed+cZohZ1TlTNfp6L
|
||||
mxR3QgZaSAwGIv+rR8mbVfblzCt/CLkedauxuh1e7sECgYEA4gHNpJX5AjhRS6fM
|
||||
sCFwdFmExjE6vvnah/WFsovbQ/3tzJuQVswNBi9ilz7rJQDGtdCVbKmifOfXRSH9
|
||||
a4ApRBzTL81lqlQEi/vqIB6y5j2GRPvs38KgkJjRj/qwJXqHm6PDznhsMcA0bNSe
|
||||
Ms/hxh0MZUy0mCWktii+rAyn0LECgYEA4Y9gxRtl1s2rHai182QlkQIvr/86U6op
|
||||
vlH4xiaE0fic7Bmg6Y3O4gZMdqvtGqd+sBm9AwMoepYMZLzMeXQzU5o3CfI09V3S
|
||||
EiwGbpSWEV2348WcUIDoFXcFiUH6GKYrQIykUo4VrxKWI0b6xmLGRIMx7LfrPYFO
|
||||
CPknDI9OkBsCgYEAgI7kCg4hIcklPTLK9RlgXV6abx6Luxxm2VWo4oI5jHiB7xRC
|
||||
S40wj2ce3se0fEzvu3ZVuQTZX9GFG1cVTzQMxSjcXGGqxfOazoHSkMjFnMA8gzsG
|
||||
Z9XO/dFfy1WfIwKK5taFyAmqCba6W3mqL18en1HgvjKeu7kV82RD6ZwdTVECgYEA
|
||||
vZEJjD59dWz+nfuXh4moRNmoiGqhc4U0df5gbPAcendOMuNLKF6E+9K9WpMdv2P7
|
||||
hjbrcmeqEnSez98Yng55wI6AKTzFI14JWjpj4XXBNbElBimjOMlNxBR2s6eecC7f
|
||||
dO1+gN9m++9L/TP/ONH0vcnhIIhmDRfqJIJ5PgYGyfcCgYEAxMEqTjc/cVG8S4FF
|
||||
CuQU19hIGccsRu2m+myd3gkMKc6cko15h03lq9P0xjBvB5ZEpKyWx11bDEQ5VNwx
|
||||
LyclQ3qnAmyTKDHpbMyZDMS40JTfd1ehgFtOoopxFt7cnxmncGcGvQsC/7YELtyw
|
||||
Qaufg6qoiPBTdI9yS6DPSOAscQ8=
|
||||
-----END PRIVATE KEY-----
|
||||
Reference in New Issue
Block a user