Commit 1645dbe7 by Administrator

Merge branch 'dev_v1.0.0' into 'master'

v1.0.0

See merge request !1
2 parents df186ffb df28b056
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="1.8" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Kotlin2JsCompilerArguments">
<option name="sourceMapPrefix" value="" />
<option name="sourceMapEmbedSources" value="inlining" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/wechatkit.iml" filepath="$PROJECT_DIR$/.idea/wechatkit.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
Doc
2016-06-19
Wechat Api
INSTALL
php composer require ldy/wechatkit -vvv
Start
`
*******************************************
@param $type
接入类型
O 开放平台
A 普通接入
@param $options 根据自己需求填写
[
'appid'=>null,
'secret'=>null,
'mch_id'=>null,
'key'=>null,
'cert_file'=>null,
'key_file'=>null,
'open'=>[
'appid'=>null,
'secret'=>null
]
]
@param $config 系统配置
[
'cachePath' => '/Tmp/HWeChatApi/%s', //%s 为APPID替代 此公众号下所有凭证都会缓存在此目录下
'cacheTime' => '7000', //缓存有效时间
]
$wechat = (new \wechatkit\Run\Run())->App($type, array $options=[],array $config=[]);
*******************************************
`
ldy/wechatkit ldy/wechatkit
\ No newline at end of file
{
"name": "ldy/wechatkit",
"description": "wechat base api tools",
"keywords": ["wechat", "weixinApi", "api"],
"homepage": "http://www.ledouya.com/",
"type": "library",
"version": "1.0.0",
"authors": [
{
"name": "lvdouya",
"email": "bingge@ledouya.com",
"homepage": "http://www.ledouya.com"
}
],
"require": {
"php": "^5.3.2 || ^7.0",
"nategood/httpful": "0.2.20"
},
"autoload": {
"psr-4": {
"wechatkit\\": "src/"
}
}
}
<?php
namespace wechatkit\AccessToken;
/*
* 不完全是 AccessToken 类
* 初始化时处理所有的预信息
* */
use wechatkit\Config\Config;
use wechatkit\Core\ErrorCode;
use wechatkit\HttpFul\HttpFul;
class AccessToken
{
static $Certificates = [
'AccessToken',
'JsTicket',
];
/**
* @throws \Exception
*/
static function readCertificates()
{
debug('进入初始化微信信息' . PHP_EOL);
if (Config::$type == 'O') {
debug('开放平台流程' . PHP_EOL);
//component_access_token 写入Config
$componentDir = sprintf(Config::$config['cachePath'], Config::$options['open']['appid']);
if (!is_dir($componentDir)) {
if (!mkdir($componentDir, 0777, TRUE)) {
throw new \Exception('DIR "' . $componentDir . '" no write! place create this');
}
}
if (file_exists($componentDir . DIRECTORY_SEPARATOR . 'component_access_token')) {
debug('开放平台流程 - component_access_token' . PHP_EOL);
$fileLastWriteTime = filemtime($componentDir . DIRECTORY_SEPARATOR . 'component_access_token');
if ($fileLastWriteTime && (time() - $fileLastWriteTime < Config::$config['cacheTime'])) { //判断缓存时间
debug('开放平台流程 - component_access_token 读取缓存' . PHP_EOL);
Config::$componentAccessToken = file_get_contents($componentDir . DIRECTORY_SEPARATOR . 'component_access_token');
} else {
self::componentAccessToken($componentDir);
}
} else {
self::componentAccessToken($componentDir);
}
}
//加载公众号基本配置
if (Config::$options['appid']) {
debug('加载公众号基本配置' . PHP_EOL);
$CacheDir = sprintf(Config::$config['cachePath'], Config::$options['appid']);
if (!is_dir($CacheDir)) {
if (!mkdir($CacheDir, 0777, TRUE)) {
throw new \Exception('DIR "' . $CacheDir . '" no write! place create this');
}
}
debug('获取参数' . PHP_EOL);
Config::$accessToken = self::get($CacheDir, 'accessToken', [Config::$options['appid'], Config::$options['secret']]);
Config::$jsApiTicket = self::get($CacheDir, 'jsApiTicket', [Config::$accessToken]);
}
}
/**
*
* 根据公众号的appid获取第三方平台对应的accesstoken
*
*/
static function getAccessToken($appid){
$CacheDir = sprintf(Config::$config['cachePath'], $appid);
debug($CacheDir);
return self::get($CacheDir, 'accessToken', [$appid, Config::$options['secret']]);
}
static function get($CacheDir, $name, $args = [])
{
$file = $CacheDir . DIRECTORY_SEPARATOR . $name;
if (file_exists($file)) {
$fileLastWriteTime = filemtime($file);
if ($fileLastWriteTime && (time() - $fileLastWriteTime < Config::$config['cacheTime'])) { //判断缓存时间
debug('[缓存]获取参数' . $name . '-目录:' . $CacheDir . PHP_EOL);
return file_get_contents($file);
} else { //更新缓存
if (($name == 'accessToken' && Config::$type == 'A') || $name != 'accessToken') {
$resp = (new HttpFul())->handler($name, $args);
if ($resp) {
debug('[微信]获取参数' . $name . '-成功:' . $resp . PHP_EOL);
Config::$$name = $resp;
file_put_contents($file, $resp);
return $resp;
} else {
if (function_exists('debug')) {
debug($name . ' error!');
}
}
} elseif (Config::$type == 'O') {
$authorizerRefreshToken = file_get_contents($CacheDir . DIRECTORY_SEPARATOR . 'authorizer_refresh_token');
if ($authorizerRefreshToken) {
$res = HttpFul::init()->handler('apiAuthorizerToken', [Config::$componentAccessToken], [
'component_appid' => Config::$options['open']['appid'],
'authorizer_appid' => Config::$options['appid'],
'authorizer_refresh_token' => $authorizerRefreshToken,
], 'JSON', 'POST');
if ($res) {
debug('[微信][开放]获取参数' . $name . '-成功:' . $res['authorizer_access_token'] . PHP_EOL);
file_put_contents($file, $res['authorizer_access_token']);
file_put_contents($CacheDir . DIRECTORY_SEPARATOR . 'authorizer_refresh_token', $res['authorizer_refresh_token']);
Config::$$name = $res['authorizer_access_token'];
debug($res['authorizer_access_token']);
debug(Config::$$name);
}
}
}
}
} else { //初次建立
if (($name == 'accessToken' && Config::$type == 'A') || $name != 'accessToken') {
$resp = (new HttpFul())->handler($name, $args);
if ($resp) {
Config::$$name = $resp;
file_put_contents($file, $resp);
return $resp;
} else {
if (function_exists('debug')) {
debug($name . ' error!');
}
}
}
}
}
static protected function componentAccessToken($componentDir)
{
debug('开放平台流程 - component_access_token 微信获取'.$componentDir . PHP_EOL);
if (file_exists($componentDir . DIRECTORY_SEPARATOR . 'component_verify_ticket')) {
$apiPostData = [
'component_appid' => Config::$options['open']['appid'],
'component_appsecret' => Config::$options['open']['secret'],
'component_verify_ticket' => file_get_contents($componentDir . DIRECTORY_SEPARATOR . 'component_verify_ticket'),
];
$res = HttpFul::init()->handler('apiComponentToken', [], $apiPostData, 'JSON', 'POST');
if ($res) {
debug('开放平台流程 - component_access_token 拉取成功' . PHP_EOL);
file_put_contents($componentDir . DIRECTORY_SEPARATOR . 'component_access_token', $res['component_access_token']);
Config::$componentAccessToken = $res['component_access_token'];
} else {
if (function_exists('debug')) {
debug('component_access_token' . ' get fail');
}
return FALSE;
}
} else {
if (function_exists('debug')) {
debug('component_verify_ticket' . '尚未推送');
}
return ErrorCode::$componentVerifyTicketNotFound;
}
}
}
\ No newline at end of file
<?php
namespace wechatkit\Card;
use wechatkit\Config\Config;
use wechatkit\Core\Func;
use wechatkit\HttpFul\HttpFul;
class Card
{
public function logo($body)
{
return HttpFul::init()->handler('uploadimg', [Config::$accessToken], $body, 'JSON', 'FILE');
}
public function create($data)
{
return HttpFul::init()->handler('card', [Config::$accessToken], $data, 'JSON', 'POST');
}
public function apiTicket()
{
$CacheDir = sprintf(Config::$config['cachePath'], Config::$options['appid']);
if (file_exists($CacheDir . DIRECTORY_SEPARATOR . 'CARDJSTICKET')) {
$fileLastWriteTime = filemtime($CacheDir . DIRECTORY_SEPARATOR . 'CARDJSTICKET');
if ($fileLastWriteTime && (time() - $fileLastWriteTime < Config::$config['cacheTime'])) { //判断缓存时间
Config::$CARDJSTICKET = file_get_contents($CacheDir . DIRECTORY_SEPARATOR . 'CARDJSTICKET');
} else {
Config::$CARDJSTICKET = $this->ticket($CacheDir);
}
} else {
Config::$CARDJSTICKET = $this->ticket($CacheDir);
}
}
public function ticket($cacheDir)
{
$res = HttpFul::init()->handler('getticketCard', [Config::$accessToken], [], 'JSON', 'GET');
if ($res) {
file_put_contents($cacheDir . DIRECTORY_SEPARATOR . 'CARDJSTICKET', $res['ticket']);
return $res['ticket'];
} else {
if (function_exists('debug')) {
debug('card tikcet error');
}
}
}
public function jsCardConfig($card_id)
{
$this->apiTicket();
$data = [
'timestamp' => time(),
'card_id' => $card_id,
'nonce_str' => Func::nonceStr(32),
'api_ticket' => Config::$CARDJSTICKET,
];
$data['signature'] = $this->sign($data);
return $data;
}
public function sign($data)
{
sort($data,SORT_STRING);
debug('卡券签名:' . json_encode($data, 256));
$str = '';
foreach ($data as $val) {
$str .= $val;
}
debug('卡券签名String:' . $str);
return sha1($str);
}
}
\ No newline at end of file
<?php
namespace wechatkit\Config;
class Config{
static public $options = [
'appid'=>null,
'secret'=>null,
'mch_id'=>null,
'key'=>null,
'cert_file'=>null,
'key_file'=>null,
'token'=>null,
'encodingAesKey'=>null,
'open'=>[
'appid'=>'',
'secret'=>'',
'token'=>null,
'encodingAesKey'=>null,
],
'webLogin'=>[
'appid'=>'',
'secret'=>''
]
];
static public $typeList = [
'openHandler'=>'O', //开放平台接入
'mpHandler'=>'A' //普通接入
];
static public $type;
static public $config = [
'cachePath' => APP_ROOT.'/cache/file/%s', //%s 为APPID替代 此公众号下所有凭证都会缓存在此目录下
'cacheTime' => '7000', //缓存有效时间
];
static public $accessToken;
static public $jsApiTicket;
static public $oAuthAccessToken;
static public $componentAccessToken;
static public $CARDJSTICKET;
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: chenshuhao
* Date: 16-6-25
* Time: 上午11:45
*/
namespace wechatkit\Core;
class ErrorCode
{
static public $componentVerifyTicketNotFound = -4001;
}
\ No newline at end of file
<?php
namespace wechatkit\Core;
class Func
{
static function nonceStr($len)
{
$str = array_merge(range(0,9),range('a','z'),range('A','Z'));
$nonceStr = '';
for($i=0;$i<$len;$i++){
$nonceStr .= $str[mt_rand(0,count($str)-1)];
}
return $nonceStr;
}
}
\ No newline at end of file
<?php
namespace wechatkit\Core;
interface HttpFul {
public function handler($name,array $args);
}
<?php
namespace wechatkit\Core;
interface Run{
/**
* 初始化
* @param $type 接入类型
* @param array $options 当APPID接入必填
* @return mixed
*/
public function App($type, array $options=[]);
}
<?php
namespace wechatkit\CryptMsg;
/**
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
include_once "sha1.php";
include_once "xmlparse.php";
include_once "pkcs7Encoder.php";
include_once "errorCode.php";
/**
* 1.第三方回复加密消息给公众平台;
* 2.第三方收到公众平台发送的消息,验证消息的安全性,并对消息进行解密。
*/
class CryptMsg
{
private $token;
private $encodingAesKey;
private $appId;
/**
* 构造函数
* @param $token string 公众平台上,开发者设置的token
* @param $encodingAesKey string 公众平台上,开发者设置的EncodingAESKey
* @param $appId string 公众平台的appId
*/
public function WXBizMsgCrypt($token, $encodingAesKey, $appId)
{
$this->token = $token;
$this->encodingAesKey = $encodingAesKey;
$this->appId = $appId;
}
/**
* 将公众平台回复用户的消息加密打包.
* <ol>
* <li>对要发送的消息进行AES-CBC加密</li>
* <li>生成安全签名</li>
* <li>将消息密文和安全签名打包成xml格式</li>
* </ol>
*
* @param $replyMsg string 公众平台待回复用户的消息,xml格式的字符串
* @param $timeStamp string 时间戳,可以自己生成,也可以用URL参数的timestamp
* @param $nonce string 随机串,可以自己生成,也可以用URL参数的nonce
* @param &$encryptMsg string 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串,
* 当return返回0时有效
*
* @return int 成功0,失败返回对应的错误码
*/
public function encryptMsg($replyMsg, $timeStamp, $nonce, &$encryptMsg)
{
$pc = new \Prpcrypt($this->encodingAesKey);
//加密
$array = $pc->encrypt($replyMsg, $this->appId);
$ret = $array[0];
if ($ret != 0) {
return $ret;
}
if ($timeStamp == null) {
$timeStamp = time();
}
$encrypt = $array[1];
//生成安全签名
$sha1 = new \SHA1;
$array = $sha1->getSHA1($this->token, $timeStamp, $nonce, $encrypt);
$ret = $array[0];
if ($ret != 0) {
return $ret;
}
$signature = $array[1];
//生成发送的xml
$xmlparse = new \XMLParse;
$encryptMsg = $xmlparse->generate($encrypt, $signature, $timeStamp, $nonce);
return \ErrorCode::$OK;
}
/**
* 检验消息的真实性,并且获取解密后的明文.
* <ol>
* <li>利用收到的密文生成安全签名,进行签名验证</li>
* <li>若验证通过,则提取xml中的加密消息</li>
* <li>对消息进行解密</li>
* </ol>
*
* @param $msgSignature string 签名串,对应URL参数的msg_signature
* @param $timestamp string 时间戳 对应URL参数的timestamp
* @param $nonce string 随机串,对应URL参数的nonce
* @param $postData string 密文,对应POST请求的数据
* @param &$msg string 解密后的原文,当return返回0时有效
*
* @return int 成功0,失败返回对应的错误码
*/
public function decryptMsg($msgSignature, $timestamp = null, $nonce, $postData, &$msg)
{
if (strlen($this->encodingAesKey) != 43) {
return \ErrorCode::$IllegalAesKey;
}
$pc = new \Prpcrypt($this->encodingAesKey);
//提取密文
$xmlparse = new \XMLParse;
$array = $xmlparse->extract($postData);
$ret = $array[0];
if ($ret != 0) {
return $ret;
}
if ($timestamp == null) {
$timestamp = time();
}
$encrypt = $array[1];
$touser_name = $array[2];
//验证安全签名
$sha1 = new \SHA1;
$array = $sha1->getSHA1($this->token, $timestamp, $nonce, $encrypt);
$ret = $array[0];
if ($ret != 0) {
return $ret;
}
$signature = $array[1];
if ($signature != $msgSignature) {
return \ErrorCode::$ValidateSignatureError;
}
$result = $pc->decrypt($encrypt, $this->appId);
if ($result[0] != 0) {
return $result[0];
}
$msg = $result[1];
return \ErrorCode::$OK;
}
}
<?php
/**
* error code 说明.
* <ul>
* <li>-40001: 签名验证错误</li>
* <li>-40002: xml解析失败</li>
* <li>-40003: sha加密生成签名失败</li>
* <li>-40004: encodingAesKey 非法</li>
* <li>-40005: appid 校验错误</li>
* <li>-40006: aes 加密失败</li>
* <li>-40007: aes 解密失败</li>
* <li>-40008: 解密后得到的buffer非法</li>
* <li>-40009: base64加密失败</li>
* <li>-40010: base64解密失败</li>
* <li>-40011: 生成xml失败</li>
* </ul>
*/
class ErrorCode
{
public static $OK = 0;
public static $ValidateSignatureError = -40001;
public static $ParseXmlError = -40002;
public static $ComputeSignatureError = -40003;
public static $IllegalAesKey = -40004;
public static $ValidateAppidError = -40005;
public static $EncryptAESError = -40006;
public static $DecryptAESError = -40007;
public static $IllegalBuffer = -40008;
public static $EncodeBase64Error = -40009;
public static $DecodeBase64Error = -40010;
public static $GenReturnXmlError = -40011;
}
?>
\ No newline at end of file
<?php
include_once "errorCode.php";
/**
* PKCS7Encoder class
*
* 提供基于PKCS7算法的加解密接口.
*/
class PKCS7Encoder
{
public static $block_size = 32;
/**
* 对需要加密的明文进行填充补位
* @param $text 需要进行填充补位操作的明文
* @return 补齐明文字符串
*/
function encode($text)
{
$block_size = PKCS7Encoder::$block_size;
$text_length = strlen($text);
//计算需要填充的位数
$amount_to_pad = PKCS7Encoder::$block_size - ($text_length % PKCS7Encoder::$block_size);
if ($amount_to_pad == 0) {
$amount_to_pad = PKCS7Encoder::block_size;
}
//获得补位所用的字符
$pad_chr = chr($amount_to_pad);
$tmp = "";
for ($index = 0; $index < $amount_to_pad; $index++) {
$tmp .= $pad_chr;
}
return $text . $tmp;
}
/**
* 对解密后的明文进行补位删除
* @param decrypted 解密后的明文
* @return 删除填充补位后的明文
*/
function decode($text)
{
$pad = ord(substr($text, -1));
if ($pad < 1 || $pad > 32) {
$pad = 0;
}
return substr($text, 0, (strlen($text) - $pad));
}
}
/**
* Prpcrypt class
*
* 提供接收和推送给公众平台消息的加解密接口.
*/
class Prpcrypt
{
public $key;
function Prpcrypt($k)
{
$this->key = base64_decode($k . "=");
}
/**
* 对明文进行加密
* @param string $text 需要加密的明文
* @return string 加密后的密文
*/
public function encrypt($text, $appid)
{
try {
//获得16位随机字符串,填充到明文之前
$random = $this->getRandomStr();
$text = $random . pack("N", strlen($text)) . $text . $appid;
// 网络字节序
$size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
$iv = substr($this->key, 0, 16);
//使用自定义的填充方式对明文进行补位填充
$pkc_encoder = new PKCS7Encoder;
$text = $pkc_encoder->encode($text);
mcrypt_generic_init($module, $this->key, $iv);
//加密
$encrypted = mcrypt_generic($module, $text);
mcrypt_generic_deinit($module);
mcrypt_module_close($module);
//print(base64_encode($encrypted));
//使用BASE64对加密后的字符串进行编码
return array(ErrorCode::$OK, base64_encode($encrypted));
} catch (Exception $e) {
//print $e;
return array(ErrorCode::$EncryptAESError, null);
}
}
/**
* 对密文进行解密
* @param string $encrypted 需要解密的密文
* @return string 解密得到的明文
*/
public function decrypt($encrypted, $appid)
{
try {
//使用BASE64对需要解密的字符串进行解码
$ciphertext_dec = base64_decode($encrypted);
$module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
$iv = substr($this->key, 0, 16);
mcrypt_generic_init($module, $this->key, $iv);
//解密
$decrypted = mdecrypt_generic($module, $ciphertext_dec);
mcrypt_generic_deinit($module);
mcrypt_module_close($module);
} catch (Exception $e) {
return array(ErrorCode::$DecryptAESError, null);
}
try {
//去除补位字符
$pkc_encoder = new PKCS7Encoder;
$result = $pkc_encoder->decode($decrypted);
//去除16位随机字符串,网络字节序和AppId
if (strlen($result) < 16)
return "";
$content = substr($result, 16, strlen($result));
$len_list = unpack("N", substr($content, 0, 4));
$xml_len = $len_list[1];
$xml_content = substr($content, 4, $xml_len);
$from_appid = substr($content, $xml_len + 4);
} catch (Exception $e) {
//print $e;
return array(ErrorCode::$IllegalBuffer, null);
}
if ($from_appid != $appid)
return array(ErrorCode::$ValidateAppidError, null);
return array(0, $xml_content);
}
/**
* 随机生成16位字符串
* @return string 生成的字符串
*/
function getRandomStr()
{
$str = "";
$str_pol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
$max = strlen($str_pol) - 1;
for ($i = 0; $i < 16; $i++) {
$str .= $str_pol[mt_rand(0, $max)];
}
return $str;
}
}
?>
\ No newline at end of file
<?php
include_once "errorCode.php";
/**
* SHA1 class
*
* 计算公众平台的消息签名接口.
*/
class SHA1
{
/**
* 用SHA1算法生成安全签名
* @param string $token 票据
* @param string $timestamp 时间戳
* @param string $nonce 随机字符串
* @param string $encrypt 密文消息
*/
public function getSHA1($token, $timestamp, $nonce, $encrypt_msg)
{
//排序
try {
$array = array($encrypt_msg, $token, $timestamp, $nonce);
sort($array, SORT_STRING);
$str = implode($array);
return array(ErrorCode::$OK, sha1($str));
} catch (Exception $e) {
//print $e . "\n";
return array(ErrorCode::$ComputeSignatureError, null);
}
}
}
?>
\ No newline at end of file
<?php
include_once "errorCode.php";
/**
* XMLParse class
*
* 提供提取消息格式中的密文及生成回复消息格式的接口.
*/
class XMLParse
{
/**
* 提取出xml数据包中的加密消息
* @param string $xmltext 待提取的xml字符串
* @return string 提取出的加密消息字符串
*/
public function extract($xmltext)
{
try {
$xml = new DOMDocument();
$xml->loadXML($xmltext);
$array_e = $xml->getElementsByTagName('Encrypt');
$array_a = $xml->getElementsByTagName('ToUserName');
$encrypt = $array_e->item(0)->nodeValue;
$tousername = $array_a->item(0)->nodeValue;
return array(0, $encrypt, $tousername);
} catch (Exception $e) {
//debug($e);
//print $e . "\n";
return array(ErrorCode::$ParseXmlError, null, null);
}
}
/**
* 生成xml消息
* @param string $encrypt 加密后的消息密文
* @param string $signature 安全签名
* @param string $timestamp 时间戳
* @param string $nonce 随机字符串
*/
public function generate($encrypt, $signature, $timestamp, $nonce)
{
$format = "<xml>
<Encrypt><![CDATA[%s]]></Encrypt>
<MsgSignature><![CDATA[%s]]></MsgSignature>
<TimeStamp>%s</TimeStamp>
<Nonce><![CDATA[%s]]></Nonce>
</xml>";
return sprintf($format, $encrypt, $signature, $timestamp, $nonce);
}
}
?>
\ No newline at end of file
<?php
/**
* error code 说明.
* <ul>
* <li>-41001: encodingAesKey 非法</li>
* <li>-41003: aes 解密失败</li>
* <li>-41004: 解密后得到的buffer非法</li>
* <li>-41005: base64加密失败</li>
* <li>-41016: base64解密失败</li>
* </ul>
*/
class ErrorCode
{
public static $OK = 0;
public static $IllegalAesKey = -41001;
public static $IllegalIv = -41002;
public static $IllegalBuffer = -41003;
public static $DecodeBase64Error = -41004;
}
?>
\ No newline at end of file
<?php
namespace wechatkit\CryptMsgMini;
include_once "wxBizDataCrypt.php";
class miniDecoder{
public function decoder($appid,$sessionKey,$iv,$encryptedData){
if(!$sessionKey || !$iv || !$encryptedData){
return null;
}
$data='';
$pc = new \WXBizDataCrypt($appid, $sessionKey);
$errCode = $pc->decryptData($encryptedData, $iv, $data);
if ($errCode == 0) {
return $data;
} else {
debug($errCode . "\n");
}
}
}
?>
\ No newline at end of file
<?php
include_once "errorCode.php";
/**
* PKCS7Encoder class
*
* 提供基于PKCS7算法的加解密接口.
*/
class PKCS7Encoder
{
public static $block_size = 16;
/**
* 对需要加密的明文进行填充补位
* @param $text 需要进行填充补位操作的明文
* @return 补齐明文字符串
*/
function encode( $text )
{
$block_size = PKCS7Encoder::$block_size;
$text_length = strlen( $text );
//计算需要填充的位数
$amount_to_pad = PKCS7Encoder::$block_size - ( $text_length % PKCS7Encoder::$block_size );
if ( $amount_to_pad == 0 ) {
$amount_to_pad = PKCS7Encoder::block_size;
}
//获得补位所用的字符
$pad_chr = chr( $amount_to_pad );
$tmp = "";
for ( $index = 0; $index < $amount_to_pad; $index++ ) {
$tmp .= $pad_chr;
}
return $text . $tmp;
}
/**
* 对解密后的明文进行补位删除
* @param decrypted 解密后的明文
* @return 删除填充补位后的明文
*/
function decode($text)
{
$pad = ord(substr($text, -1));
if ($pad < 1 || $pad > 32) {
$pad = 0;
}
return substr($text, 0, (strlen($text) - $pad));
}
}
/**
* Prpcrypt class
*
*
*/
class Prpcrypt
{
public $key;
function Prpcrypt( $k )
{
$this->key = $k;
}
/**
* 对密文进行解密
* @param string $aesCipher 需要解密的密文
* @param string $aesIV 解密的初始向量
* @return string 解密得到的明文
*/
public function decrypt( $aesCipher, $aesIV )
{
try {
$module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
mcrypt_generic_init($module, $this->key, $aesIV);
//解密
$decrypted = mdecrypt_generic($module, $aesCipher);
mcrypt_generic_deinit($module);
mcrypt_module_close($module);
} catch (Exception $e) {
return array(ErrorCode::$IllegalBuffer, null);
}
try {
//去除补位字符
$pkc_encoder = new PKCS7Encoder;
$result = $pkc_encoder->decode($decrypted);
} catch (Exception $e) {
//print $e;
return array(ErrorCode::$IllegalBuffer, null);
}
return array(0, $result);
}
}
?>
\ No newline at end of file
<?php
/**
* 对微信小程序用户加密数据的解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
include_once "pkcs7Encoder.php";
include_once "errorCode.php";
class WXBizDataCrypt
{
private $appid;
private $sessionKey;
/**
* 构造函数
* @param $sessionKey string 用户在小程序登录后获取的会话密钥
* @param $appid string 小程序的appid
*/
public function WXBizDataCrypt( $appid, $sessionKey)
{
$this->sessionKey = $sessionKey;
$this->appid = $appid;
}
/**
* 检验数据的真实性,并且获取解密后的明文.
* @param $encryptedData string 加密的用户数据
* @param $iv string 与用户数据一同返回的初始向量
* @param $data string 解密后的原文
*
* @return int 成功0,失败返回对应的错误码
*/
public function decryptData( $encryptedData, $iv, &$data )
{
if (strlen($this->sessionKey) != 24) {
return \ErrorCode::$IllegalAesKey;
}
$aesKey=base64_decode($this->sessionKey);
if (strlen($iv) != 24) {
return \ErrorCode::$IllegalIv;
}
$aesIV=base64_decode($iv);
$aesCipher=base64_decode($encryptedData);
$pc = new \Prpcrypt($aesKey);
$result = $pc->decrypt($aesCipher,$aesIV);
if ($result[0] != 0) {
return $result[0];
}
$dataObj=json_decode( $result[1] );
if( $dataObj == NULL )
{
return \ErrorCode::$IllegalBuffer;
}
if( $dataObj->watermark->appid != $this->appid )
{
return \ErrorCode::$IllegalBuffer;
}
$data = $result[1];
return \ErrorCode::$OK;
}
}
<?php
namespace wechatkit\Device;
use wechatkit\Config\Config;
use wechatkit\HttpFul\HttpFul;
class Device
{
public function applyid($data)
{
//https://api.weixin.qq.com/shakearound/device/applyid?access_token=ACCESS_TOKENPOST
return HttpFul::init()->handler('applyid',[Config::$accessToken],$data,'JSON','POST');
}
public function applystatus($data){
// https://api.weixin.qq.com/shakearound/device/applystatus?access_token=ACCESS_TOKEN
return HttpFul::init()->handler('applystatus',[Config::$accessToken],$data,'JSON','POST');
}
public function search($data){
// https://api.weixin.qq.com/shakearound/device/search?access_token=ACCESS_TOKENPOST
return HttpFul::init()->handler('deviceSearch',[Config::$accessToken],$data,'JSON','POST');
}
public function addPage($data){
// https://api.weixin.qq.com/shakearound/device/bindpage?access_token=ACCESS_TOK
return HttpFul::init()->handler('deviceeBindpage',[Config::$accessToken],$data,'JSON','POST');
}
}
\ No newline at end of file
<?php
namespace wechatkit\HttpFul;
use wechatkit\Config\Config, \Httpful\Request;
class HttpFul implements \wechatkit\Core\HttpFul
{
public $accessToken = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%1%&secret=%2%';
public $jsApiTicket = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%1%&type=jsapi';
public $oAuth2AccessTokenUserInfo = 'https://api.weixin.qq.com/sns/userinfo?access_token=%1%&openid=%2%&lang=zh_CN ';
public $oauth2AccessToken = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=%1%&secret=%2%&code=%3%&grant_type=authorization_code ';
public $openOauth2AccessToken = 'https://api.weixin.qq.com/sns/oauth2/component/access_token?appid=%1%&code=%2%&grant_type=authorization_code&component_appid=%3%&component_access_token=%4%';
public $apiComponentToken = 'https://api.weixin.qq.com/cgi-bin/component/api_component_token';
public $apiAuthorizerToken = 'https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=%1%';
public $preAuthCode = 'https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=%1%';
public $apiQueryAuth = 'https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=%1%';
public $apiGetAuthorizerInfo = 'https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=%1%';
public $uploadimg = 'https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=%1%';
public $shakearoundMaterialAdd = 'https://api.weixin.qq.com/shakearound/material/add?access_token=%1%&type=%2%';
public $card = 'https://api.weixin.qq.com/card/create?access_token=%1%';
public $applyid = 'https://api.weixin.qq.com/shakearound/device/applyid?access_token=%1%';
public $applystatus = 'https://api.weixin.qq.com/shakearound/device/applystatus?access_token=%1%';
public $deviceSearch = 'https://api.weixin.qq.com/shakearound/device/search?access_token=%1%';
public $pageAdd = 'https://api.weixin.qq.com/shakearound/page/add?access_token=%1%';
public $pageUpdate = 'https://api.weixin.qq.com/shakearound/page/update?access_token=%1%';
public $deviceeBindpage = 'https://api.weixin.qq.com/shakearound/device/bindpage?access_token=%1%';
public $getshakeinfo = 'https://api.weixin.qq.com/shakearound/user/getshakeinfo?access_token=%1%';
public $promotion = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';
//公众号红包
public $sendredpack = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack';
public $getticketCard = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%1%&type=wx_card';
public $unifiedorder = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
//小程序获取用户
public $openOauth2JSAccessToken = 'https://api.weixin.qq.com/sns/jscode2session?appid=%1%&secret=%2%&js_code=%3%&grant_type=authorization_code';
static public $self = NULL;
static public function init()
{
if (NULL == self::$self) {
return new HttpFul();
} else {
return self::$self;
}
}
/**
* @param $name
* @param array $args
* @param string $method
* @return bool|mixed
*/
public function handler($name, array $args, $body=[],$bodyType='JSON', $method = 'GET',$ca=[])
{
if ($this->$name) {
switch ($method){
case 'GET':
return $ret = $this->httpGet($name, $args);
break;
case 'POST':
if('JSON' == $bodyType){
$body = json_encode($body,JSON_UNESCAPED_UNICODE);
$body = str_replace(' ','',$body);
}
return $ret = $this->httpPost($name, $args,$body,$bodyType);
break;
case 'FILE':
return $ret = $this->httpFile($name, $args,$body);
break;
case 'CA':
return $ret = $this->httpCa($name,$body,$ca);
break;
}
} else {
return FALSE;
}
}
/**
* @param $urlName
* @param $args
* @return bool|mixed
* @throws \Httpful\Exception\ConnectionErrorException
*/
public function httpGet($urlName, $args)
{
$searchArr = [];
for ($i = 1; $i <= count($args); $i++) {
$searchArr[] = '%' . $i . '%';
}
$url = str_replace($searchArr, $args, $this->$urlName);
$response = Request::get($url)
->withStrictSSL()
->send();
return $this->responseHandler($response, $urlName);
}
public function httpPost($name,$args,$body,$type){
$searchArr = [];
for ($i = 1; $i <= count($args); $i++) {
$searchArr[] = '%' . $i . '%';
}
debug(serialize($body));
$url = str_replace($searchArr, $args, $this->$name);
if($type == 'JSON'){
$response = Request::post($url)
->withStrictSSL()
->expectsJson()
->body($body)
->send();
}elseif($type == 'XML'){
$response = Request::post($url)
->withStrictSSL()
->expectsXml()
->body($body)
->send();
}
return $this->responseHandler($response, $name);
}
public function httpFile($name,$args,$body){
$searchArr = [];
for ($i = 1; $i <= count($args); $i++) {
$searchArr[] = '%' . $i . '%';
}
$url = str_replace($searchArr, $args, $this->$name);
$response = \Httpful\Request::post($url)
->withStrictSSL()
->attach($body)
->send();
debug(json_encode($response));
return $this->responseHandler($response, $name);
}
public function httpCa($name,$body,$ca){
debug('url:'.$this->$name);
debug($body);
//debug(file_get_contents($this->$name));
$response = \Httpful\Request::post(str_replace(' ','',$this->$name))
->authenticateWithCert($ca['cert_file'], $ca['key_file'], $ca['ca_file'])
->withStrictSSL()
->body($body)
->send();
// debug('pay_result==='.$response);
return $this->responseHandler($response, $name);
}
/**
* @param $response
* @param null $name
* @return bool|mixed
*/
public function responseHandler($response, $name = NULL)
{
$body = $response->raw_body;
if($this->is_Json($response->raw_body)){
$body = json_decode($response->raw_body,1);
debug($body);
}else if($this->is_Xml($response->raw_body)){
$body = json_decode(json_encode(simplexml_load_string($response->raw_body, 'SimpleXMLElement', LIBXML_NOCDATA)),1);
debug($body);
}else{
return $body;
}
if (!isset($body['errcode']) || 0 == $body['errcode']) {
if (NULL != $name) {
return $this->filter($name, $body);
} else {
return $body;
}
} else {
if(function_exists('debug')){
debug("[{$name}][{$body['errcode']}]{$body['errmsg']}");
}
return FALSE;
}
}
/**
* @param $obj
* @return mixed
*/
public function objToArray($obj)
{
return json_decode(json_encode($obj), 1);
}
/**
* @param $name
* @param $resp
* @return mixed
*/
public function filter($name, $resp)
{
switch ($name) {
case 'accessToken':
return $resp['access_token'];
break;
case 'jsApiTicket':
return $resp['ticket'];
break;
default:
return $resp;
break;
}
}
public function is_Json($string)
{
json_decode($string);
return (json_last_error() == JSON_ERROR_NONE);
}
public function is_Xml($xml){
$xml_parser = xml_parser_create();
if(!xml_parse($xml_parser,$xml,true)){
xml_parser_free($xml_parser);
return false;
}else {
return true;
}
}
}
<?php
namespace wechatkit\JsSdk;
use wechatkit\Config\Config;
use wechatkit\Core\Func;
class JsSdk
{
public $jsApiList = [
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone',
'startRecord',
'stopRecord',
'onVoiceRecordEnd',
'playVoice',
'pauseVoice',
'stopVoice',
'onVoicePlayEnd',
'uploadVoice',
'downloadVoice',
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage',
'translateVoice',
'getNetworkType',
'openLocation',
'getLocation',
'hideOptionMenu',
'showOptionMenu',
'hideMenuItems',
'showMenuItems',
'hideAllNonBaseMenuItem',
'showAllNonBaseMenuItem',
'closeWindow',
'scanQRCode',
'chooseWXPay',
'openProductSpecificView',
'addCard',
'chooseCard',
'openCard',
];
public function jsConfig($url = null, $jsApiList = NULL, $deBug=false)
{
if (NULL == $url) {
$url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
if (NULL == $jsApiList) {
$jsApiList = $this->jsApiList;
}
$jsConfig = [
'debug' => $deBug,
'appId' => Config::$options['appid'],
'timestamp' => time(),
'nonceStr' => Func::nonceStr(32),
];
$jsConfig['signature'] = $this->signature($url, $jsConfig);
$jsConfig['jsApiList'] = $jsApiList;
return json_encode($jsConfig,256);
}
protected function signature($url, $jsConfig)
{
$url = explode('#', $url);
$crrent = $url[0];
$sign = [
'noncestr' => $jsConfig['nonceStr'],
'jsapi_ticket' => Config::$jsApiTicket,
'timestamp' => $jsConfig['timestamp'],
'url' => $url[0],
];
ksort($sign);
foreach ($sign as $k => $v) {
$arr[] = $k . '=' . $v;
}
return sha1(join('&', $arr));
}
}
\ No newline at end of file
<?php
namespace wechatkit\Message;
class Message {
public function replayText($content,$toUser,$formUser){
$xml = "
<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>".time()."</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>
";
echo sprintf($xml,$toUser,$formUser,$content);
}
}
\ No newline at end of file
<?php
namespace wechatkit\Oauth2;
use wechatkit\Config\Config;
use wechatkit\HttpFul\HttpFul;
class Oauth2
{
/**
*
* 微信小程序登陆
*
* @param $appid
* @param $secret
*
*/
public function jscode2session($appid,$secret,$code){
if ($code){
$result = $this->accessTokenFromJsCode($code,$appid,$secret, new HttpFul());
if($result)
return $result;
else
return null;
}
return null;
}
/**
*
* 通过微信小程序code获取用户openid
*
* @param code
* @param HttpFul $httpFul
*
*
*/
protected function accessTokenFromJsCode($code,$appid,$secret,HttpFul $httpFul){
if(!$code)
return null;
$result = $httpFul->handler('openOauth2JSAccessToken', [$appid,$secret,$code]);
$this->result($result);
return $result;
}
/**
* @param $redirect_uri
* @param string $scope
* @param string $state
* @param bool $auto
* @return bool|mixed
*/
public function mpAuthorize_v2($redirect_uri =null, $scope = 'snsapi_userinfo', $state = '', $auto = TRUE)
{
if(null == $redirect_uri){
$redirect_uri = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
}
if (Config::$type == 'O') { //开放平台授权
if (!$_GET['code']) {
header('location:' . sprintf(
'https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&component_appid=%s#wechat_redirect',
Config::$options['appid'],
urlencode($redirect_uri),
$scope,
$state,
Config::$options['open']['appid']
));
exit(255);
} else {
if ($auto) {
$result = $this->accessTokenFormCode($_GET['code'], new HttpFul());
if ('snsapi_base' == $scope) {
return $result['openid'];
}
// asyncLog('---openid--'.json_encode($result));
$info = $this->oAuth2AccessTokenUserInfo($result['openid'], new HttpFul());
return $info;
}
}
}
}
/**
* @param $redirect_uri
* @param string $scope
* @param string $state
* @param bool $auto
* @return bool|mixed
*/
public function mpAuthorize($redirect_uri =null, $scope = 'snsapi_userinfo', $state = '', $auto = TRUE)
{
if(null == $redirect_uri){
$redirect_uri = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
}
if (Config::$type == 'A') { //普通授权
if (!$_GET['code']) {
header('location:' . sprintf(
'https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect',
Config::$options['appid'],
urlencode($redirect_uri),
$scope,
$state
));
exit(255);
} else {
if ($auto) {
$result = $this->accessTokenFormCode($_GET['code'], new HttpFul());
if ('snsapi_base' == $scope) {
return $result['openid'];
}
return $this->oAuth2AccessTokenUserInfo($result['openid'], new HttpFul());
}
}
} else if (Config::$type == 'O') { //开放平台授权
if (!$_GET['code']) {
header('location:' . sprintf(
'https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&component_appid=%s#wechat_redirect',
Config::$options['appid'],
urlencode($redirect_uri),
$scope,
$state,
Config::$options['open']['appid']
));
exit(255);
} else {
if ($auto) {
$result = $this->accessTokenFormCode($_GET['code'], new HttpFul());
if ('snsapi_base' == $scope) {
return $result['openid'];
}
return $this->oAuth2AccessTokenUserInfo($result['openid'], new HttpFul());
}
}
}
}
/**
* @param $code
* @param HttpFul $httpFul
* @return bool|mixed
*/
protected function accessTokenFormCode($code, HttpFul $httpFul)
{
if(Config::$type == 'A'){
$result = $httpFul->handler('oauth2AccessToken', [$code]);
}else{
$result = $httpFul->handler('openOauth2AccessToken', [Config::$options['appid'],$code,Config::$options['open']['appid'],Config::$componentAccessToken]);
}
$this->result($result);
return $result;
}
/**
* @param $openid
* @param HttpFul $httpFul
* @return bool|mixed
*/
protected function oAuth2AccessTokenUserInfo($openid, HttpFul $httpFul)
{
$result = $httpFul->handler('oAuth2AccessTokenUserInfo', [$this->access_token, $openid]);
$this->result($result);
return $result;
}
/**
* @param array $result
*/
public function result($result)
{
if(!$result && !is_array($result)){
return false;
}
foreach ($result as $key => $value) {
$this->$key = $value;
}
}
}
<?php
namespace wechatkit\Open;
use wechatkit\Config\Config;
use wechatkit\HttpFul\HttpFul;
class Open
{
public function __construct()
{
if (Config::$type != 'O') {
throw new \Exception('this api must open type');
}
}
//网页登入
public function webOAuth2($url = NULL, $type = 'URL', $state = NULL, $wxLoginConfig = ['style' => 'black',
'href' => NULL])
{
if(null == $url){
$url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
}
if ('URL' == $type) {
$locationUrl = 'https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_login&state=%s#wechat_redirect';
header('Location:' . sprintf($locationUrl, Config::$options['webLogin']['appid'], urlencode($url), $state));
exit(255);
} elseif ('JSON' == $type) {
//<script src="http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>
$wxLogin = [
'id' => 'wxLogin',
'appid' => Config::$options['webLogin']['appid'],
'scope' => 'snsapi_login',
'redirect_uri' => $url,
'state' => $state,
'style' => $wxLoginConfig['style'],
'href' => $wxLoginConfig['href'],
];
return json_encode($wxLogin, 256);
}
}
public function codeAccessToken($code)
{
// public $oauth2AccessToken = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=%1%&secret=%2%&code=%3%&grant_type=authorization_code ';
$httpFul = new HttpFul();
return $httpFul->handler('oauth2AccessToken',
[
Config::$options['webLogin']['appid'],
Config::$options['webLogin']['secret'],
$code,
]);
}
public function userInfo($accessToken, $openid)
{
return HttpFul::init()->handler('oAuth2AccessTokenUserInfo', [$accessToken, $openid]);
}
//微信公众号授权e
public function authorizer($url=null){
if(!$_GET['auth_code']){
$preAuthCode = HttpFul::init()->handler('preAuthCode',[Config::$componentAccessToken],['component_appid'=>Config::$options['open']['appid']],'JSON','POST');
if($preAuthCode){
if(null == $url){
$url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
}
header(sprintf('Location:https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s',Config::$options['open']['appid'],$preAuthCode['pre_auth_code'],urlencode($url)));
exit(255);
}
}else{
return $this->authinfo($_GET['auth_code']);
}
}
//拉公众号信息
public function mpInfo($authorizer_appid){
//$apiGetAuthorizerInfo
return HttpFul::init()->handler('apiGetAuthorizerInfo',[Config::$componentAccessToken],['component_appid'=>Config::$options['open']['appid'],'authorizer_appid'=>$authorizer_appid],'JSON','POST');
}
public function authinfo($auth_code){
return HttpFul::init()->handler('apiQueryAuth',[Config::$componentAccessToken],['component_appid'=>Config::$options['open']['appid'],'authorization_code'=>$auth_code],'JSON','POST');
}
}
\ No newline at end of file
<?php
namespace wechatkit\Pay;
use wechatkit\Core\Func;
use wechatkit\HttpFul\HttpFul;
class Pay {
//https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers
public function promotion($data,$key,$cert_file,$key_file,$ca_file,$type=null){
if($type!=null && 'sendredpack' == $type){
return $this->sendredpack($data,$key,$cert_file,$key_file,$ca_file);
}
$data['sign'] = $this->sign($data,$key);
$xml = $this->arrToXml($data);
debug('进入企业付款发钱的流程');
return HttpFul::init()->handler('promotion',[],$xml,'JSON','CA',[
'cert_file'=>$cert_file,
'key_file'=>$key_file,
'ca_file'=>$ca_file,
]);
}
/**
*
* 公众号红包
*
*/
//https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack
public function sendredpack($data,$key,$cert_file,$key_file,$ca_file){
debug('进入公众号发钱的流程');
$data['sign'] = $this->sign($data,$key);
$xml = $this->arrToXml($data);
return HttpFul::init()->handler('sendredpack',[],$xml,'JSON','CA',[
'cert_file'=>$cert_file,
'key_file'=>$key_file,
'ca_file'=>$ca_file,
]);
}
//// https://api.mch.weixin.qq.com/pay/unifiedorder
public function unifiedorder($data,$key){
$data['sign'] = $this->sign($data,$key);
$xml = $this->arrToXml($data);
$res = HttpFul::init()->handler('unifiedorder',[],$xml,'XML','POST',[]);
debug(json_encode($res));
if($res['return_code'] == 'SUCCESS' && $res['result_code'] == 'SUCCESS'){
$payConfig= [
'appId'=>$data['appid'],
'timeStamp'=>(string)time(),
'nonceStr'=>Func::nonceStr(32),
'package'=>'prepay_id='.$res['prepay_id'],
'signType'=>'MD5',
'code_url'=>$res['code_url']
];
$payConfig['paySign'] = $this->sign($payConfig,$key);
return [$res['prepay_id'],$payConfig];
}else{
return false;
}
}
protected function sign($data,$key){
ksort($data);
foreach ($data as $k=>$v){
$arr[] = $k.'='.$v;
}
$arr[] = 'key='.$key;
return strtoupper(md5(join('&',$arr)));
}
public function arrToXml($data){
$xml = '<xml>';
foreach ($data as $k=>$v){
$xml .= "<{$k}>{$v}</{$k}>";
}
$xml .= '</xml>';
return $xml;
}
}
\ No newline at end of file
<?php
namespace wechatkit\Run;
use wechatkit\Config, wechatkit\AccessToken;
class Run implements \wechatkit\Core\Run
{
static $self = NULL;
/**
* @param $type
* @param array $options [ appid secret mch_id key cert_file key_file ]
* @param array $config
* @return bool
*/
public function App($type, array $options = [], array $config = [])
{
if (!in_array($type, Config\Config::$typeList)) {
return FALSE;
} else {
Config\Config::$type = $type;
}
Config\Config::$options = array_merge(Config\Config::$options, $options);
Config\Config::$config = array_merge(Config\Config::$config, $config);
$this->AccessToken()->readCertificates();
return $this;
}
static public function go()
{
if (NULL == self::$self) {
return new \wechatkit\Run\Run();
} else {
return self::$self;
}
}
public function getAccessToken($appid){
return $this->AccessToken()->getAccessToken($appid);
}
/**
* @param array $arr
* @param $value
* @return array
*/
protected function key(array $arr, $value)
{
return array_keys($arr, $value);
}
/**
* @param $name
* @param $arguments
* @return mixed
* @throws \Exception
*/
public function __call($name, $arguments)
{
if (is_dir(__DIR__ . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . $name)) {
$className = '\wechatkit\\' . $name . '\\' . $name;
return new $className();
} else {
throw new \Exception('class ' . $name . ' not found!');
}
}
/*
* O save
* */
public function componentVerifyTicketSave($component_verify_ticket)
{
$componentDir = sprintf(Config\Config::$config['cachePath'], Config\Config::$options['open']['appid']);
if (!is_dir($componentDir)) {
if (!mkdir($componentDir, 0777, TRUE)) {
throw new \Exception('DIR "' . $componentDir . '" no write! place create this');
}
}
$ret = file_put_contents($componentDir . DIRECTORY_SEPARATOR . 'component_verify_ticket', $component_verify_ticket);
if ($ret) {
return TRUE;
}
}
public function certificatesSave($wxappid,$name,$value)
{
$componentDir = sprintf(Config\Config::$config['cachePath'], $wxappid);
if (!is_dir($componentDir)) {
if (!mkdir($componentDir, 0777, TRUE)) {
throw new \Exception('DIR "' . $componentDir . '" no write! place create this');
}
}
$ret = file_put_contents($componentDir . DIRECTORY_SEPARATOR . $name, $value);
if ($ret) {
return TRUE;
}
}
}
\ No newline at end of file
<?php
namespace wechatkit\Service;
use wechatkit\Config\Config;
use wechatkit\CryptMsg\CryptMsg;
class Service {
public $postData;
public $xml;
public $xmlArray;
public function __construct()
{
$this->postData = file_get_contents('php://input');
if(!$this->postData){
exit(255);
}
$cryptmsg = new CryptMsg();
debug('=====================进入service.php');
if(Config::$type == 'A'){
$this->xml = simplexml_load_string($this->postData, 'SimpleXMLElement', LIBXML_NOCDATA);
if($this->xml->Encrypt){
$cryptmsg->WXBizMsgCrypt(Config::$options['token'],Config::$options['encodingAesKey'], Config::$options['appid']);
$ret = $cryptmsg->decryptMsg($_GET['msg_signature'], $_GET['timestamp'], $_GET['nonce'], $this->postData, $this->xml);
$this->xml = simplexml_load_string($this->xml, 'SimpleXMLElement', LIBXML_NOCDATA);
}
$this->xmlArray = json_decode(json_encode($this->xml),1);
}elseif(Config::$type == 'O'){
$cryptmsg->WXBizMsgCrypt(Config::$options['open']['token'],Config::$options['open']['encodingAesKey'], Config::$options['open']['appid']);
$result = $cryptmsg->decryptMsg($_GET['msg_signature'], $_GET['timestamp'], $_GET['nonce'], $this->postData, $this->xml);
if(0 != $result){
#解密失败
if(function_exists('debug')){
debug('微信数据解密失败'.$result);
}
}else{
debug('=====================进入service.php');
$this->xml = simplexml_load_string($this->xml, 'SimpleXMLElement', LIBXML_NOCDATA);
$this->xmlArray = json_decode(json_encode($this->xml),1);
}
}else{
$this->xml = simplexml_load_string($this->postData, 'SimpleXMLElement', LIBXML_NOCDATA);
$xmlArray = $this->xmlArray = json_decode(json_encode($this->xml),1);
debug('================$xml'.$xml.'------------$xmlArray'.$xmlArray);
}
}
public function run(){
return $this->xml;
}
public function runArray(){
return $this->xmlArray;
}
}
\ No newline at end of file
<?php
namespace wechatkit\Shake;
use wechatkit\Config\Config;
use wechatkit\HttpFul\HttpFul;
class Shake {
public function addPage($data){
return HttpFul::init()->handler('pageAdd',[Config::$accessToken],$data,'JSON','POST');
}
public function updatePage($data){
return HttpFul::init()->handler('pageUpdate',[Config::$accessToken],$data,'JSON','POST');
}
public function uploads($data,$type){
return HttpFul::init()->handler('shakearoundMaterialAdd',[Config::$accessToken,$type],$data,'JSON', 'FILE');
}
public function getShakeInfo($data){
return HttpFul::init()->handler('getshakeinfo',[Config::$accessToken],$data,'JSON','POST');
}
}
\ No newline at end of file
<?php
namespace wechatkit\User;
use wechatkit\HttpFul\HttpFul;
class User{
// public function webUserInfo($accessToken,$openid){
// return
// }
}
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!