diff --git a/composer.json b/composer.json index 14ad6d0..4d60e05 100644 --- a/composer.json +++ b/composer.json @@ -1,28 +1,31 @@ { - "name": "wchat/wchat", - "description": "一个参数效验扩展", - "keywords": [ - "validate" - ], - "license": "MIT", - "authors": [ - { - "name": "xianglin", - "email": "xianglin@163.com" - } - ], - "autoload": { - "psr-4": { - "wchat\\": "./wchat/" - }, - "files": [ - "Container.php" - ] - }, - "require": { - "php": ">= 7.0" - }, - "require-dev": { - "swoole/ide-helper": "@dev" - } + "name": "wchat/wchat", + "description": "一个参数效验扩展", + "keywords": [ + "validate" + ], + "license": "MIT", + "authors": [ + { + "name": "xianglin", + "email": "xianglin@163.com" + } + ], + "autoload": { + "psr-4": { + "wchat\\": "./wchat/" + }, + "files": [ + "Container.php" + ] + }, + "require": { + "php": ">= 8.1", + "game-worker/kiri-container": "*", + "game-worker/kiri-psr-message": "*", + "game-worker/kiri-client": "*" + }, + "require-dev": { + "swoole/ide-helper": "@dev" + } } diff --git a/wchat/.phpstorm.meta.php b/wchat/.phpstorm.meta.php new file mode 100644 index 0000000..f6dce9e --- /dev/null +++ b/wchat/.phpstorm.meta.php @@ -0,0 +1,22 @@ +oac_appid; + } + + /** + * @param string $oac_appid + */ + public function setOacAppid(string $oac_appid): void + { + $this->oac_appid = $oac_appid; + } + + /** + * @return string + */ + public function getUseRobot(): string + { + return $this->use_robot; + } + + /** + * @param string $use_robot + */ + public function setUseRobot(string $use_robot): void + { + $this->use_robot = $use_robot; + } + + /** * @return Result * @throws \Exception */ - public function sendTemplate() + public function sendTemplate(): Result { - $url = $this->getUrl() . '?access_token=' . $this->config->getAccessToken(); + $access_token = $this->config->getAccessToken(); + if (empty($access_token)) { + throw new \Exception('request access_token con\'t null.'); + } $params = [ "touser" => $this->openId, "template_id" => $this->templateId, "page" => $this->page, "data" => $this->keywords, ]; - if (!empty($this->emphasis_keyword)) { $params['emphasis_keyword'] = $this->emphasis_keyword; } + if (!empty($this->oac_appid)) { + $params['oac_appid'] = $this->oac_appid; + } + if (!empty($this->use_robot)) { + $params['use_robot'] = $this->use_robot; + } + $this->reset($result); - $params = json_encode($params, JSON_UNESCAPED_UNICODE); + $client = new Client($this->getHost(), 443, true); + $client->withHeader(['Content-Type' => 'application/json; charset=utf-8']); + $client->post($this->getUrl() . '?access_token=' . $access_token, $params); + $client->close(); - $this->request->setIsSSL(true); - $this->request->addHeader('Content-Type', 'application/json'); - - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $result = $this->request->post($url, $params); - $result->append('postBody', $params); - - return $this->reset($result); + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errcode']) && $body['errcode'] != 0) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } else { + return new Result(code: 0, data: $body); + } } /** diff --git a/wchat/base/Template.php b/wchat/base/Template.php index 6095d7d..d8158f0 100644 --- a/wchat/base/Template.php +++ b/wchat/base/Template.php @@ -2,22 +2,23 @@ namespace wchat\base; -use wchat\common\Miniprogarampage; +use Kiri\Client; +use wchat\common\Multiprogramming; use wchat\common\Result; /** * Class Template */ -abstract class Template extends Miniprogarampage +abstract class Template extends Multiprogramming { - private $keywords = []; - private $templateId = ''; - private $formId = ''; - private $openId = ''; - private $page = 'pages/index/index'; - private $emphasis_keyword = ''; + private array $keywords = []; + private string $templateId = ''; + private string $formId = ''; + private string $openId = ''; + private string $page = 'pages/index/index'; + private string $emphasis_keyword = ''; /** * @param array $keywords @@ -72,7 +73,7 @@ abstract class Template extends Miniprogarampage * @param $context * @param $color */ - public function replaceKeyword($index, $context, $color = '') + public function replaceKeyword($index, $context, string $color = '') { if (empty($color)) { $color = '#000'; @@ -101,20 +102,21 @@ abstract class Template extends Miniprogarampage abstract public function getUrl(); + abstract public function getHost(); + /** * @return Result * @throws \Exception * * 奴隶交易通知 */ - public function sendTemplate() + public function sendTemplate(): Result { $access_token = $this->config->getAccessToken(); if (empty($access_token)) { throw new \Exception('request access_token con\'t null.'); } - $url = $this->getUrl() . '?access_token=' . $access_token; $params = [ "touser" => $this->openId, "template_id" => $this->templateId, @@ -126,30 +128,35 @@ abstract class Template extends Miniprogarampage if (!empty($this->emphasis_keyword)) { $params['emphasis_keyword'] = $this->emphasis_keyword; } - $params = json_encode($params, JSON_UNESCAPED_UNICODE); - $this->request->setIsSSL(true); - $this->request->addHeader('Content-Type', 'application/json; charset=utf-8'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $result = $this->request->post($url, $params); - $result->append('postBody', $params); - return $this->reset($result); + $this->reset($result); + + $client = new Client($this->getHost(), 443, true); + $client->withHeader(['Content-Type' => 'application/json; charset=utf-8']); + $client->post($this->getUrl() . '?access_token=' . $access_token, $params); + $client->close(); + + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errcode']) && $body['errcode'] != 0) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } + return new Result(code: 0, data: $body); } /** * @param $result - * @return mixed + * @return void */ - private function reset($result) + private function reset($result): void { $this->openId = ''; $this->keywords = []; $this->formId = ''; $this->templateId = ''; $this->page = ''; - - return $result; } } diff --git a/wchat/common/Config.php b/wchat/common/Config.php index c4243c8..3023aa9 100644 --- a/wchat/common/Config.php +++ b/wchat/common/Config.php @@ -12,7 +12,7 @@ class Config * * 小程序ID */ - private $appid = ''; + private string $appid = ''; /** @@ -20,357 +20,470 @@ class Config * * 商户号ID */ - private $mch_id = ''; + private string $mch_id = ''; /** * @var string * * 设备号 */ - private $device_info = 'WEB'; + private string $device_info = 'WEB'; + + private string $token; + private string $encodingAesKey; + + private string $schema = 'WECHATPAY2-SHA256-RSA2048'; + + private string $serial_no = '33F00000E4248E2EB3C61FC8384E1E155ECBB1B2'; - private $token; - private $encodingAesKey; /** * @var string * * 随机字符串 */ - private $nonce_str = ''; + private string $nonce_str = ''; /** * @var string * * 商品简单描述 */ - private $body = '好友默契Pk充值!'; + private string $body = '好友默契Pk充值!'; /** * @var string * * 商户订单号 */ - private $out_trade_no = ""; + private string $out_trade_no = ""; /** - * @var int + * @var int|float * * 金额 */ - private $total_fee = 0; + private float|int $total_fee = 0; /** * @var string * * 终端IP */ - private $spbill_create_ip = ""; + private string $spbill_create_ip = ""; /** * @var string * * 异步回调地址 */ - private $notify_url = ""; + private string $notify_url = ""; /** * @var string * * 交易类型 */ - private $trade_type = 'JSAPI'; + private string $trade_type = 'JSAPI'; /** * @var string * * 签名方式 */ - private $sign_type = 'MD5'; + private string $sign_type = 'MD5'; /** * @var string * * 商户接口地址 */ - private $mch_host = 'https://api.mch.weixin.qq.com'; + private string $mch_host = 'https://api.mch.weixin.qq.com'; /** * @var string */ - private $appsecret = ''; + private string $appsecret = ''; - private $remote_addr = '127.0.0.1'; + private string $remote_addr = '127.0.0.1'; - private $ssl_cert = ''; - private $ssl_key = ''; - private $ssl_ca = ''; - private $port = ''; + private string $ssl_cert = ''; + private string $ssl_key = ''; + private string $ssl_ca = ''; + private int $port = 443; /** * @var string */ - private $key = ''; - private $access_token = ''; - private $agent = ''; - private $usrSwoole = false; + private string $key = ''; + private string $access_token = ''; + private string $agent = ''; + private bool $usrSwoole = false; /** * @return string */ - public function getSslCa() + public function getSchema(): string { - return $this->ssl_ca; + return $this->schema; } /** - * @param $ssl_ca - * @return Config + * @param string $schema */ - public function setSslCa($ssl_ca): Config + public function setSchema(string $schema): void { - $this->ssl_ca = $ssl_ca; - return $this; + $this->schema = $schema; } /** * @return string */ - public function getPort() + public function getSerialNo(): string { - return $this->port; + return $this->serial_no; } /** - * @param $port - * @return Config + * @param string $serial_no */ - public function setPort($port): Config + public function setSerialNo(string $serial_no): void { - $this->port = $port; - return $this; - } - - /** - * @return bool - */ - public function isUsrSwoole() - { - return $this->usrSwoole; - } - - /** - * @param bool $usrSwoole - * @return Config - */ - public function setUsrSwoole(bool $usrSwoole): Config - { - $this->usrSwoole = $usrSwoole; - return $this; + $this->serial_no = $serial_no; } /** * @return string */ - public function getAgent() + public function getAppid(): string { - return $this->agent; + return $this->appid; } /** - * @param $agent - * @return Config + * @param string $appid */ - public function setAgent($agent): Config - { - $this->agent = $agent; - return $this; - } - - /** - * @return mixed - */ - public function getToken() - { - return $this->token; - } - - /** - * @param mixed $token - * @return Config - */ - public function setToken($token) - { - $this->token = $token; - return $this; - } - - /** - * @return mixed - */ - public function getEncodingAesKey() - { - return $this->encodingAesKey; - } - - /** - * @param mixed $encodingAesKey - * @return Config - */ - public function setEncodingAesKey($encodingAesKey) - { - $this->encodingAesKey = $encodingAesKey; - return $this; - } - - /** - * @return string - */ - public function getAccessToken() - { - return $this->access_token; - } - - /** - * @param $access_token - */ - public function setAccessToken($access_token) - { - $this->access_token = $access_token; - } - - /** - * @param $remote_addr - */ - public function setRemoteAddr($remote_addr) - { - $this->remote_addr = $remote_addr; - } - - /** - * @param $appid - */ - public function setAppid($appid) + public function setAppid(string $appid): void { $this->appid = $appid; } /** - * @param $mch_id + * @return string */ - public function setMchId($mch_id) + public function getMchId(): string + { + return $this->mch_id; + } + + /** + * @param string $mch_id + */ + public function setMchId(string $mch_id): void { $this->mch_id = $mch_id; } /** - * @param $device_info + * @return string */ - public function setDeviceInfo($device_info) + public function getDeviceInfo(): string + { + return $this->device_info; + } + + /** + * @param string $device_info + */ + public function setDeviceInfo(string $device_info): void { $this->device_info = $device_info; } /** - * @param $nonce_str + * @return string */ - public function setNonceStr($nonce_str) + public function getToken(): string + { + return $this->token; + } + + /** + * @param string $token + */ + public function setToken(string $token): void + { + $this->token = $token; + } + + /** + * @return string + */ + public function getEncodingAesKey(): string + { + return $this->encodingAesKey; + } + + /** + * @param string $encodingAesKey + */ + public function setEncodingAesKey(string $encodingAesKey): void + { + $this->encodingAesKey = $encodingAesKey; + } + + /** + * @return string + */ + public function getNonceStr(): string + { + return $this->nonce_str; + } + + /** + * @param string $nonce_str + */ + public function setNonceStr(string $nonce_str): void { $this->nonce_str = $nonce_str; } /** - * @param $body + * @return string */ - public function setBody($body) + public function getBody(): string + { + return $this->body; + } + + /** + * @param string $body + */ + public function setBody(string $body): void { $this->body = $body; } /** - * @param $out_trade_no + * @return string */ - public function setOutTradeNo($out_trade_no) + public function getOutTradeNo(): string + { + return $this->out_trade_no; + } + + /** + * @param string $out_trade_no + */ + public function setOutTradeNo(string $out_trade_no): void { $this->out_trade_no = $out_trade_no; } + /** + * @return int + */ + public function getTotalFee(): int|string + { + return $this->total_fee; + } + /** * @param int $total_fee */ - public function setTotalFee(int $total_fee) + public function setTotalFee(int|string $total_fee): void { $this->total_fee = $total_fee; } /** - * @param $spbill_create_ip + * @return string */ - public function setSpbillCreateIp($spbill_create_ip) + public function getSpbillCreateIp(): string + { + return $this->spbill_create_ip; + } + + /** + * @param string $spbill_create_ip + */ + public function setSpbillCreateIp(string $spbill_create_ip): void { $this->spbill_create_ip = $spbill_create_ip; } /** - * @param $notify_url + * @return string */ - public function setNotifyUrl($notify_url) + public function getNotifyUrl(): string + { + return $this->notify_url; + } + + /** + * @param string $notify_url + */ + public function setNotifyUrl(string $notify_url): void { $this->notify_url = $notify_url; } /** - * @param $trade_type + * @return string */ - public function setTradeType($trade_type) + public function getTradeType(): string + { + return $this->trade_type; + } + + /** + * @param string $trade_type + */ + public function setTradeType(string $trade_type): void { $this->trade_type = $trade_type; } /** - * @param $sign_type + * @return string */ - public function setSignType($sign_type) + public function getSignType(): string + { + return $this->sign_type; + } + + /** + * @param string $sign_type + */ + public function setSignType(string $sign_type): void { $this->sign_type = $sign_type; } /** - * @param $mch_host + * @return string */ - public function setMchHost($mch_host) + public function getMchHost(): string + { + return $this->mch_host; + } + + /** + * @param string $mch_host + */ + public function setMchHost(string $mch_host): void { $this->mch_host = $mch_host; } /** - * @param $appsecret + * @return string */ - public function setAppsecret($appsecret) + public function getAppsecret(): string + { + return $this->appsecret; + } + + /** + * @param string $appsecret + */ + public function setAppsecret(string $appsecret): void { $this->appsecret = $appsecret; } /** - * @param $ssl_cert + * @return string */ - public function setSslCert($ssl_cert) + public function getRemoteAddr(): string + { + return $this->remote_addr; + } + + /** + * @param string $remote_addr + */ + public function setRemoteAddr(string $remote_addr): void + { + $this->remote_addr = $remote_addr; + } + + /** + * @return string + */ + public function getSslCert(): string + { + return $this->ssl_cert; + } + + /** + * @param string $ssl_cert + */ + public function setSslCert(string $ssl_cert): void { $this->ssl_cert = $ssl_cert; } /** - * @param $ssl_key + * @return string */ - public function setSslKey($ssl_key) + public function getSslKey(): string + { + return $this->ssl_key; + } + + /** + * @param string $ssl_key + */ + public function setSslKey(string $ssl_key): void { $this->ssl_key = $ssl_key; } /** - * @param $key + * @return string */ - public function setKey($key) + public function getSslCa(): string + { + return $this->ssl_ca; + } + + /** + * @param string $ssl_ca + */ + public function setSslCa(string $ssl_ca): void + { + $this->ssl_ca = $ssl_ca; + } + + /** + * @return string + */ + public function getPort(): string + { + return $this->port; + } + + /** + * @param string $port + */ + public function setPort(string $port): void + { + $this->port = $port; + } + + /** + * @return string + */ + public function getKey(): string + { + return $this->key; + } + + /** + * @param string $key + */ + public function setKey(string $key): void { $this->key = $key; } @@ -378,145 +491,56 @@ class Config /** * @return string */ - public function getAppid() + public function getAccessToken(): string { - return $this->appid; + return $this->access_token; + } + + /** + * @param string $access_token + */ + public function setAccessToken(string $access_token): void + { + $this->access_token = $access_token; } /** * @return string */ - public function getMchId() + public function getAgent(): string { - return $this->mch_id; + return $this->agent; } /** - * @return string + * @param string $agent */ - public function getDeviceInfo() + public function setAgent(string $agent): void { - return $this->device_info; + $this->agent = $agent; } /** - * @return string + * @return bool */ - public function getNonceStr() + public function isUsrSwoole(): bool { - return $this->nonce_str; + return $this->usrSwoole; } /** - * @return string + * @param bool $usrSwoole */ - public function getBody() + public function setUsrSwoole(bool $usrSwoole): void { - return $this->body; + $this->usrSwoole = $usrSwoole; } - /** - * @return string - */ - public function getOutTradeNo() - { - return $this->out_trade_no; - } - - /** - * @return int - */ - public function getTotalFee() - { - return $this->total_fee; - } - - /** - * @return string - */ - public function getSpbillCreateIp() - { - return $this->spbill_create_ip; - } - - /** - * @return string - */ - public function getNotifyUrl() - { - return $this->notify_url; - } - - /** - * @return string - */ - public function getTradeType() - { - return $this->trade_type; - } - - /** - * @return string - */ - public function getSignType() - { - return $this->sign_type; - } - - /** - * @return string - */ - public function getMchHost() - { - return $this->mch_host; - } - - /** - * @return string - */ - public function getAppsecret() - { - return $this->appsecret; - } - - /** - * @return string - */ - public function getRemoteAddr() - { - return $this->remote_addr; - } - - /** - * @return string - */ - public function getSslCert() - { - return $this->ssl_cert; - } - - /** - * @return string - */ - public function getSslKey() - { - return $this->ssl_key; - } - - /** - * @return string - */ - public function getKey() - { - return $this->key; - } - - /** * @param array $configs * @return $this */ - public function setConfigs(array $configs) + public function setConfigs(array $configs): static { if (empty($configs)) { return $this; diff --git a/wchat/common/Decode.php b/wchat/common/Decode.php index 969e031..a0499f1 100644 --- a/wchat/common/Decode.php +++ b/wchat/common/Decode.php @@ -7,56 +7,80 @@ namespace wchat\common; class Decode { - private $sessionKey; - private $iv; - private $encryptedData; - private $appId; + private string $sessionKey; + private string $iv; + private string $encryptedData; + private string $appId; - private $OK = 0; - private $IllegalAesKey = -41001; - private $IllegalIv = -41002; - private $IllegalBuffer = -41003; - private $DecodeBase64Error = -41004; + private int $OK = 0; + private int $IllegalAesKey = -41001; + private int $IllegalIv = -41002; + private int $IllegalBuffer = -41003; + private int $DecodeBase64Error = -41004; /** - * @param mixed $sessionKey - * @return Decode + * @return string */ - public function setSessionKey($sessionKey) + public function getSessionKey(): string + { + return $this->sessionKey; + } + + /** + * @param string $sessionKey + */ + public function setSessionKey(string $sessionKey): void { $this->sessionKey = $sessionKey; - return $this; } /** - * @param mixed $iv - * @return Decode + * @return string */ - public function setIv($iv) + public function getIv(): string + { + return $this->iv; + } + + /** + * @param string $iv + */ + public function setIv(string $iv): void { $this->iv = $iv; - return $this; } /** - * @param mixed $encryptedData - * @return Decode + * @return string */ - public function setEncryptedData($encryptedData) + public function getEncryptedData(): string + { + return $this->encryptedData; + } + + /** + * @param string $encryptedData + */ + public function setEncryptedData(string $encryptedData): void { $this->encryptedData = $encryptedData; - return $this; } /** - * @param mixed $appId - * @return Decode + * @return string */ - public function setAppId($appId) + public function getAppId(): string + { + return $this->appId; + } + + /** + * @param string $appId + */ + public function setAppId(string $appId): void { $this->appId = $appId; - return $this; } @@ -65,7 +89,7 @@ class Decode * @return array|mixed * @throws \Exception */ - public function decode($asArray) + public function decode($asArray): object|array { if (strlen($this->sessionKey) != 24) { throw new \Exception('encodingAesKey 非法', $this->IllegalAesKey); @@ -87,13 +111,7 @@ class Decode if ($dataObj->watermark->appid != $this->appId) { throw new \Exception('aes 解密失败', $this->IllegalBuffer); } - - if ($asArray) { - return get_object_vars($dataObj); - } - - return $dataObj; - + return $asArray ? get_object_vars($dataObj) : $dataObj; } } diff --git a/wchat/common/Help.php b/wchat/common/Help.php index ff09378..f2d7bcb 100644 --- a/wchat/common/Help.php +++ b/wchat/common/Help.php @@ -4,14 +4,14 @@ namespace wchat\common; -class Help extends Miniprogarampage +class Help extends Multiprogramming { /** * @param array $data * @return string */ - public static function toXml(array $data) + public static function toXml(array $data): string { $xml = ""; foreach ($data as $key => $val) { @@ -34,7 +34,7 @@ class Help extends Miniprogarampage * @param array $array * @return string */ - private static function xmlChild(array $array) + private static function xmlChild(array $array): string { $string = ''; foreach ($array as $key => $value) { @@ -55,67 +55,45 @@ class Help extends Miniprogarampage /** * @param $xml - * @return mixed + * @return array|null */ - public static function toArray($xml) + public static function toArray($xml): ?array { - if (is_array($xml)) { - return $xml; - } -/* $matchQoute = '/(<\?xml.*?\?>)?<([a-zA-Z_]+)>(<([a-zA-Z_]+)><\/\4>)+<\/\2>/';*/ -// if (!preg_match($matchQoute, $xml)) { -// return self::jsonToArray($xml); -// } - if (!is_null($data = json_decode($xml, true))) { - return $data; - } - try { - $data = @simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); - if ($data !== false) { - $data = json_decode(json_encode($data), TRUE); - } else { - $data = $xml; - } - } catch (\Exception $exception) { - $data = $xml; - } finally { - return $data; + if (is_array($xml)) return $xml; + if (str_starts_with('<', $xml) && str_ends_with('>', $xml)) { + return self::xmlToArray($xml); + } else { + return self::jsonToArray($xml); } } - public static function jsonToArray($xml) + /** + * @param string $xml + * @return array|null + */ + public static function jsonToArray(string $xml): ?array { - $_xml = json_decode($xml, true); - if (is_null($_xml)) { - return $xml; - } - return $_xml; + return json_decode($xml, true); } /** - * @param $xml - * @return mixed + * @param string $xml + * @return array|null */ - public static function xmlToArray($xml) + public static function xmlToArray(string $xml): ?array { - if (is_array($xml)) { - return $xml; - } if (($data = @simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)) !== false) { return json_decode(json_encode($data), TRUE); } - if (!is_null($json = json_decode($xml, TRUE))) { - return $json; - } - return $xml; + return null; } /** * @param mixed $json - * @return false|mixed|string + * @return string */ - public static function toJson($json) + public static function toJson(mixed $json): string { if (is_object($json)) { $json = get_object_vars($json); @@ -141,7 +119,7 @@ class Help extends Miniprogarampage * * 随机字符串 */ - public static function random($length = 20) + public static function random(int $length = 20): string { $res = []; $str = 'abcdefghijklmnopqrstuvwxyz'; @@ -151,7 +129,7 @@ class Help extends Miniprogarampage if (empty($rand)) { $rand = substr($str, strlen($str) - 3, 1); } - array_push($res, $rand); + $res[] = $rand; } return implode($res); @@ -163,7 +141,7 @@ class Help extends Miniprogarampage * @param $type * @return string */ - public static function sign(array $array, $key, $type) + public static function sign(array $array, $key, $type): string { ksort($array); $buff = ""; diff --git a/wchat/common/HttpClient.php b/wchat/common/HttpClient.php deleted file mode 100644 index 9eb1c9f..0000000 --- a/wchat/common/HttpClient.php +++ /dev/null @@ -1,1023 +0,0 @@ -connect_timeout; - } - - /** - * @param $connect_timeout - */ - public function setConnectTimeout($connect_timeout) - { - $this->connect_timeout = $connect_timeout; - } - - - /** - * @return string - */ - public function getCa() - { - return $this->ca; - } - - /** - * @param $ca - */ - public function setCa($ca) - { - $this->ca = $ca; - } - - - /** - * @return int - */ - public function getPort() - { - return $this->port; - } - - /** - * @param $port - */ - public function setPort($port) - { - $this->port = $port; - } - - - /** - * @param $data - */ - public function setData($data) - { - $this->_data = $data; - } - - /** - * @return string - */ - public function getSslCertFile() - { - return $this->ssl_cert_file; - } - - /** - * @return bool - */ - public function hasSslCertFile() - { - return !empty($this->ssl_cert_file) && file_exists($this->ssl_cert_file); - } - - /** - * @return bool - */ - public function hasSslKeyFile() - { - return !empty($this->ssl_key_file) && file_exists($this->ssl_key_file); - } - - /** - * @param $ssl_cert_file - */ - public function setSslCertFile($ssl_cert_file) - { - $this->ssl_cert_file = $ssl_cert_file; - } - - /** - * @return string - */ - public function getSslKeyFile() - { - return $this->ssl_key_file; - } - - /** - * @param $ssl_key_file - */ - public function setSslKeyFile($ssl_key_file) - { - $this->ssl_key_file = $ssl_key_file; - } - - /** - */ - public static function NewRequest() - { - return new HttpClient(); - } - - /** - * @param $name - * @return $this - */ - public function setErrorField($name) - { - $this->errorCodeField = $name; - return $this; - } - - /** - * @param $bool - * @return $this - */ - public function setUseSwoole($bool) - { - $this->use_swoole = $bool; - if ($this->use_swoole) { - function_exists('setCli') && setCli(true); - } - return $this; - } - - /** - * @param $name - * @return $this - */ - public function setErrorMsgField($name) - { - $this->errorMsgField = $name; - return $this; - } - - /** - * @param $host - */ - public function setHost($host) - { - $this->host = $this->replaceHost($host); - $match_quest = '/^[a-zA-Z\-]+(\.[a-zA-Z\-])+/'; - if (preg_match($match_quest, $this->host)) { - $this->addHeader('Host', $this->host); - } - } - - - /** - * @param $path - * @param array $data - * @param $type - * @return Result - */ - public function sendTo($path, array $data, $type = SWOOLE_TCP) - { - $client = new Client($type); - if (empty($this->host) || empty($this->port)) { - return new Result(['code' => 500, 'message' => 'Host and port is null']); - } - if (!$client->connect($this->host, $this->port, $this->connect_timeout)) { - return new Result(['code' => 500, 'message' => $client->errMsg]); - } - $params['body'] = $data; - $params['path'] = '/' . $this->port . '/' . ltrim($path, '/'); - $params['header']['request_uri'] = $params['path']; - $params['header']['request_method'] = 'receive'; - if ($client->send(serialize($params))) { - $recv = $this->timeout > 0 ? $client->recv($this->timeout) : $client->recv(); - $param = $this->structure(Help::toArray($recv), $data, null, 200); - } else { - $param = new Result(['code' => 500, 'message' => $client->errMsg]); - } - $client->close(); - return $param; - } - - /** - * @param $sec - * 设置超时时间 - */ - public function setTimeout($sec) - { - $this->timeout = $sec; - } - - - /** - * @param $key - * @param $value - */ - public function setHeader($key, $value) - { - $this->header[$key] = $value; - } - - /** - * @param $key - * @param $value - */ - public function addHeader($key, $value) - { - $this->header[$key] = $value; - } - - /** - * @param null $callback - */ - public function setCallback($callback) - { - $this->callback = $callback; - } - - /** - * @param $method - */ - public function setMethod($method) - { - $this->method = $method; - } - - /** - * @param $agent - */ - public function setAgent($agent) - { - $this->agent = $agent; - } - - /** - * @param bool $isSSL - */ - public function setIsSSL(bool $isSSL) - { - $this->isSSL = $isSSL; - if ($this->isSSL) { - $this->port = 443; - } - } - - /** - * @return bool - */ - public function getIsSSL() - { - return $this->isSSL; - } - - /** - * @param $url - * @param array $data - * @return array|mixed|Result - * @throws Exception - */ - private function request($url, $data = []) - { - $data = $this->paramEncode($data); - if ($this->use_swoole) { - return $this->coroutine($this->matchHost($url), $data); - } else { - return $this->useCurl($url, $data); - } - } - - /** - * @return bool - */ - private function isCli() - { - return function_exists('getIsCli') && getIsCli(); - } - - /** - * @param $_string - * @return bool|string - * @throws Exception - */ - private function matchHost($_string = '') - { - if (empty($_string)) { - return false; - } - - if ($this->isHttp($_string)) { - $_ = str_replace('http://', '', $_string); - $hostAndUrls = explode('/', $_string); - - $this->host = array_shift($hostAndUrls); - $_ = implode('/', $hostAndUrls); - } else if ($this->isHttps($_string)) { - $_ = str_replace('https://', '', $_string); - $this->setIsSSL(true); - - $hostAndUrls = explode('/', $_string); - - $this->host = array_shift($hostAndUrls); - $_ = implode('/', $hostAndUrls); - } else if (empty($this->host)) { - $hostAndUrls = explode('/', $_string); - $this->host = array_shift($hostAndUrls); - - $_ = implode('/', $hostAndUrls); - } - - if (strpos($this->host, ':') !== false) { - [$this->host, $this->port] = explode(':', $this->host); - } - - if ($this->use_swoole) { - if (!$this->checkIsIp($this->host) && Coroutine::getuid() > 0) { - $this->host = System::gethostbyname($this->host); - } - } - - if (!$this->checkIsIp($this->host) && !$this->isDomainName($this->host)) { - throw new Exception('Client Host error.'); - } - - return $_string; - } - - /** - * @param $name - * @return bool|mixed - */ - private function isDomainName($name) - { - if (!preg_match('/^[a-zA-Z\-0-9]+(\.[a-zA-Z\-0-9]+)+[^\/]?/', $name, $out)) { - return false; - } - return $out[0]; - } - - /** - * @param $url - * @param $data - * @return array|Result|mixed - * @throws - */ - private function useCurl($url, $data) - { - if ($this->isHttp($url) || $this->isHttps($url)) { - return $this->curl($url, $data); - } - $url = $this->matchHost(ltrim($url, '/')); - if (!empty($this->port) && $this->checkIsIp($this->host)) { - $this->host .= ':' . $this->port; - } - if ($this->isSSL) { - return $this->curl('https://' . $this->host . '/' . $url, $data); - } else { - return $this->curl('http://' . $this->host . '/' . $url, $data); - } - } - - /** - * @param $host - * @return string|string[] - */ - private function replaceHost($host) - { - if ($this->isHttp($host)) { - return str_replace('http://', '', $host); - } - if ($this->isHttps($host)) { - return str_replace('https://', '', $host); - } - return $host; - } - - /** - * @param $url - * @return false|int - */ - private function checkIsIp($url) - { - return preg_match('/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/', $url); - } - - /** - * @param $url - * @return bool - */ - private function isHttp($url) - { - return strpos($url, 'http://') === 0; - } - - /** - * @param $url - * @return bool - */ - private function isHttps($url) - { - return strpos($url, 'https://') === 0; - } - - - /** - * @param $url - * @param array $data - * @return array|mixed|Result - * @throws Exception - * 使用swoole协程方式请求 - */ - private function coroutine($url, $data = []) - { - try { - $client = $this->generate_client($this->host, $url, $data); - if ($client->statusCode < 0) { - throw new Exception($client->errMsg); - } - unset($this->_data); - - $body = $this->resolve($client->getHeaders(), $client->body); - if (!in_array($client->getStatusCode(), [200, 201])) { - if (is_string($body)) { - $message = 'Request error code ' . $client->getStatusCode(); - } else { - $message = $this->searchMessageByData($body); - } - $response['code'] = $client->getStatusCode(); - $response['message'] = $message; - $response['data'] = $body; - $response['header'] = $client->getHeaders(); - - $response = new Result($response); - } else { - $response = $this->structure($body, $data, $client->getHeaders()); - } - } catch (\Throwable $exception) { - $response['code'] = 500; - $response['message'] = $exception->getMessage(); - $response['data'] = array_slice($exception->getTrace(), 0, 6); - $response['header'] = []; - - $response = new Result($response); - } - return $response; - } - - /** - * @return int - */ - private function getHostPort() - { - if (!empty($this->port)) { - return $this->port; - } - $port = 80; - if ($this->isSSL) $port = 443; - return $port; - } - - /** - * @param $host - * @param $url - * @param $data - * @return SClient - */ - private function generate_client($host, $url, $data = []) - { - $client = new SClient($host, $this->getHostPort(), $this->isSSL); - if (strpos($url, '/') !== 0) { - $url = '/' . $url; - } - - $client->set($this->settings()); - if (!empty($this->agent)) { - $this->header['User-Agent'] = $this->agent; - } - if (!empty($this->header)) { - $client->setHeaders($this->header); - } - $client->setMethod(strtoupper($this->method)); - if (strtolower($this->method) == self::GET && !empty($data)) { - $url .= '?' . $data; - } else { - $this->_data = $this->mergeParams($data); - } - - if (!empty($this->_data)) { - $client->setData($this->_data); - } - $client->execute($url); - $client->close(); - return $client; - } - - /** - * @param $newData - * @return mixed - */ - private function mergeParams($newData) - { - if (empty($this->_data)) { - return $this->toRequest($newData); - } else if (empty($newData)) { - return $this->toRequest($this->_data); - } - - $newData = Help::toArray($newData); - $array = Help::toArray($this->_data); - - $params = array_merge($array, $newData); - - return $this->toRequest($params); - } - - - /** - * @param $data - * @return false|mixed|string - */ - private function toRequest($data) - { - if (is_string($data)) { - return $data; - } - - $contentType = 'application/x-www-form-urlencoded'; - if (isset($this->header['Content-Type'])) { - $contentType = $this->header['Content-Type']; - } else if (isset($this->header['content-type'])) { - $contentType = $this->header['content-type']; - } - if ($contentType == 'multipart/form-data') { - return $data; - } - - if (strpos($contentType, 'json') !== false) { - return Help::toJson($data); - } else if (strpos($contentType, 'xml') !== false) { - return Help::toXml($data); - } else { - return http_build_query($data); - } - } - - /** - * @return array - */ - private function settings() - { - $sslCert = $this->getSslCertFile(); - $sslKey = $this->getSslKeyFile(); - $sslCa = $this->getCa(); - - $params = []; - if ($this->connect_timeout > 0) { - $params['timeout'] = $this->connect_timeout; - } - if (empty($sslCert) || empty($sslKey) || empty($sslCa)) { - return $params; - } - - $params['ssl_host_name'] = $this->host; - $params['ssl_cert_file'] = $this->getSslCertFile(); - $params['ssl_key_file'] = $this->getSslKeyFile(); - $params['ssl_verify_peer'] = true; - $params['ssl_cafile'] = $sslCa; - - return $params; - } - - /** - * @param $url - * @param array $data - * @return array|mixed|Result - */ - private function curl($url, $data = []) - { - try { - $output = $this->curlParse($url, $data); - if ($output === FALSE) { - return new Result(['code' => 500, 'message' => $output]); - } - [$header, $body, $status] = $this->explode($output); - if (!in_array($status, [200, 201])) { - $data = new Result(['code' => $status, 'message' => $body, 'header' => $header]); - } else { - $data = $this->structure($body, $data, $header); - } - return $data; - } catch (\Throwable $exception) { - $response['code'] = 500; - $response['message'] = $exception->getMessage(); - $response['data'] = array_slice($exception->getTrace(), 0, 6); - $response['header'] = []; - return new Result($response); - } - } - - /** - * @param $url - * @param $data - * @return bool|string - * @throws Exception - */ - private function curlParse($url, $data) - { - $ch = curl_init(); - - $url = $this->createRequestUrl($url, $data); - curl_setopt($ch, CURLOPT_URL, $url); - if ($this->timeout > 0) { - curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); // 超时设置 - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout); // 超时设置 - } - - curl_setopt($ch, CURLOPT_HEADER, true); - - $headers = $this->parseHeaderMat(); - if (!empty($headers) && is_array($headers)) { - curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - } - curl_setopt($ch, CURLOPT_USERAGENT, $this->agent); - - if (file_exists($cert = $this->getSslCertFile())) { - curl_setopt($ch, CURLOPT_SSLCERT, $cert); - } - if (file_exists($key = $this->getSslKeyFile())) { - curl_setopt($ch, CURLOPT_SSLKEY, $key); - } - - curl_setopt($ch, CURLOPT_NOBODY, FALSE); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);//返回内容 - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);// 跟踪重定向 - curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate'); - - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($this->method)); - if ($this->method === self::GET && !empty($this->_data)) { - curl_setopt($ch, CURLOPT_POSTFIELDS, $this->toRequest($this->_data)); - } - if ($this->method === self::POST) { - curl_setopt($ch, CURLOPT_POST, 1); - if (!is_string($data)) { - curl_setopt($ch, CURLOPT_POSTFIELDS, $this->mergeParams($data)); - } else { - curl_setopt($ch, CURLOPT_POSTFIELDS, $data); - } - } - - $output = curl_exec($ch); - if ($output === false) { - throw new Exception(curl_error($ch)); - } - curl_close($ch); - return $output; - } - - - /** - * @param $url - * @param $params - * @return array|mixed|Result - * 上传文件 - */ - public function upload($url, $params) - { - try { - $this->method = self::POST; - $output = $this->curlParse($url, $params); - if ($output === FALSE) { - return new Result(['code' => 500, 'message' => $output]); - } - [$header, $body, $status] = $this->explode($output); - if ($status != 200 && $status != 201) { - $data = new Result(['code' => $status, 'message' => $body, 'header' => $header]); - } else { - $data = $this->structure($body, $params, $header); - } - return $data; - } catch (\Throwable $exception) { - $response['code'] = 500; - $response['message'] = $exception->getMessage(); - $response['data'] = array_slice($exception->getTrace(), 0, 6); - $response['header'] = []; - return new Result($response); - } - } - - - /** - * @param $output - * @return array - */ - private function explode($output) - { - [$header, $body] = explode("\r\n\r\n", $output, 2); - if ($header == 'HTTP/1.1 100 Continue') { - [$header, $body] = explode("\r\n\r\n", $body, 2); - } else if (strpos($body, "\r\n\r\n") !== false) { - [$header, $body] = explode("\r\n\r\n", $body, 2); - } - $header = explode("\r\n", $header); - - unset($output); - - $status = (int)explode(' ', trim($header[0]))[1]; - $header = $this->headerFormat($header); - - return [$header, $this->resolve($header, $body), $status]; - } - - /** - * @param $url - * @param $data - * @return string - */ - private function createRequestUrl($url, $data) - { - if ($this->isGet()) { - return $url . '?' . $data; - } - return $url; - } - - /** - * @param $data - * @param $body - * @return mixed - */ - private function resolve($data, $body) - { - if (is_array($body)) { - return $body; - } - $type = isset($data['content-type']) ? $data['content-type'] : (isset($data['Content-Type']) ? $data['Content-Type'] : 'text/html'); - if (strpos($type, 'text/html') !== false) { - return $body; - } else if (strpos($type, 'json') !== false) { - return json_decode($body, true); - } else if (strpos($type, 'xml') !== false) { - return Help::xmlToArray($body); - } else if (strpos($type, 'plain') !== false) { - return Help::toArray($body); - } - return $body; - } - - /** - * @param $headers - * @return array - */ - private function headerFormat($headers) - { - $_tmp = []; - foreach ($headers as $key => $val) { - $trim = explode(': ', trim($val)); - - $_tmp[strtolower($trim[0])] = $trim[1] ?? ''; - } - return $_tmp; - } - - /** - * @param $body - * @param $_data - * @param $header - * @param $statusCode - * @return array|mixed|Result - * 构建返回体 - */ - private function structure($body, $_data, $header = [], $statusCode = 200) - { - $this->setIsSSL(false); - $this->setHeaders([]); - - if ($this->callback !== NULL) { - $result = call_user_func($this->callback, $body, $_data, $header); - $this->setCallback(null); - - return $result; - } - if (is_string($body)) { - $result['code'] = 0; - $result['message'] = ''; - } else { - $result['code'] = $body[$this->errorCodeField] ?? 0; - $result['message'] = $this->searchMessageByData($body); - } - $result['data'] = $body; - $result['header'] = $header; - $result['httpStatus'] = $statusCode; - - return new Result($result); - } - - /** - * @param $body - * @return array|mixed|string - */ - private function searchMessageByData($body) - { - $parent = []; - if (empty($this->errorMsgField)) { - return 'system success.'; - } - $explode = explode('.', $this->errorMsgField); - if (!isset($body[$explode[0]])) { - return 'system success.'; - } - foreach ($explode as $item) { - if (empty($item)) { - continue; - } - if (empty($parent)) { - $parent = $body[$item]; - continue; - } - if (is_string($parent) || !isset($parent[$item])) { - break; - } - $parent = $parent[$item]; - } - return !empty($parent) ? $parent : 'system success.'; - } - - - /** - * @return bool - * check isPost Request - */ - public function isPost() - { - return strtolower($this->method) === self::POST; - } - - /** - * @return bool - * - * check isGet Request - */ - public function isGet() - { - return strtolower($this->method) === self::GET; - } - - /** - * @param $arr - * - * @return array|string - * 将请求参数进行编码 - */ - private function paramEncode($arr) - { - if (!is_array($arr)) { - return $arr; - } - $_tmp = []; - foreach ($arr as $Key => $val) { - $_tmp[$Key] = $val; - } - if ($this->isGet()) { - return http_build_query($_tmp); - } - return $_tmp; - } - - /** - * @param $url - * @param array $data - * @return array|mixed|Result - * @throws - */ - public function post($url, $data = []) - { - $this->setMethod(self::POST); - return $this->request($url, $data); - } - - - /** - * @param $url - * @param array $data - * @return array|mixed|Result - * @throws - */ - public function put($url, $data = []) - { - $this->setMethod(self::PUT); - return $this->request($url, $data); - } - - /** - * @param $url - * @param array $data - * @return array|mixed|Result - * @throws - */ - public function get($url, $data = []) - { - $this->setMethod(self::GET); - return $this->request($url, $data); - } - - /** - * @param $url - * @param array $data - * @return array|mixed|Result - * @throws Exception - */ - public function option($url, $data = []) - { - $this->setMethod(self::OPTIONS); - return $this->request($url, $data); - } - - /** - * @param $url - * @param array $data - * @return array|mixed|Result - * @throws Exception - */ - public function delete($url, $data = []) - { - $this->setMethod(self::DELETE); - return $this->request($url, $data); - } - - /** - * @param $url - * @param array $data - * @return array|mixed|Result - * @throws Exception - */ - public function send($url, $data = []) - { - return $this->request($url, $data); - } - - /** - * @return array - */ - private function parseHeaderMat() - { - if ($this->use_swoole) { - return $this->header; - } - $headers = []; - foreach ($this->header as $key => $val) { - $header = $key . ': ' . $val; - if (in_array($header, $headers)) { - continue; - } - $headers[] = $header; - } - return $headers; - } - - /** - * @param array $headers - * @return array - */ - public function setHeaders(array $headers) - { - if (empty($headers)) { - return []; - } - foreach ($headers as $key => $val) { - $this->header[$key] = $val; - } - return $this->header; - } -} diff --git a/wchat/common/Miniprogarampage.php b/wchat/common/Miniprogarampage.php deleted file mode 100644 index 5549ef4..0000000 --- a/wchat/common/Miniprogarampage.php +++ /dev/null @@ -1,221 +0,0 @@ - $code, 'message' => $message]); - } - - /** - * @param $code - */ - public function setErrorCode($code) - { - $this->errorCode = $code; - } - - /** - * @param $message - */ - public function setErrorMessage($message) - { - $this->errorMsg = $message; - } - - /** - * @return int - */ - public function getErrorCode() - { - return $this->errorCode; - } - - /** - * @return string - */ - public function getErrorMessage() - { - return $this->errorMsg; - } - - /** - * Miniprogarampage constructor. - */ - public function __construct() - { - } - - /** - * @param Config $config - * @return mixed - */ - public static function getInstance(Config $config) - { - if (static::$instance === null) { - static::$instance = new static(); - } - static::$instance->config = $config; - static::$instance->request = HttpClient::NewRequest(); - static::$instance->request->setAgent($config->getAgent()); - static::$instance->request->setUseSwoole($config->isUsrSwoole()); - - $request = static::$instance->request; - if ($request->getIsSSL()) { - $request->addHeader('ssl_cert_file', $config->getSslCert()); - $request->addHeader('ssl_key_file', $config->getSslKey()); - } - return static::$instance; - } - - /** - * @param Config $config - * @return $this - */ - public function initConfig($config) - { - $this->config = $config; - $this->request = HttpClient::NewRequest(); - $this->request->setIsSSL(true); - $this->request->setData(null); - $this->request->setUseSwoole($config->isUsrSwoole()); - if (!empty($config->getAgent())) { - $this->request->setAgent($config->getAgent()); - } - if (!empty($config->getSslCert())) { - $this->request->setSslCertFile($config->getSslCert()); - } - if (!empty($config->getSslKey())) { - $this->request->setSslKeyFile($config->getSslKey()); - } - if (!empty($config->getSslCa())) { - $this->request->setCa($config->getSslCa()); - } - return $this; - } - - /** - * @return \wchat\common\Config - */ - public function getConfig() - { - return $this->config; - } - - /** - * @return bool|mixed|string - * @throws \Exception - */ - protected function getAccessToken() - { - $access = $this->config->getAccessToken(); - if (!empty($access)) { - return $access; - } - $this->request->setMethod(HttpClient::GET); - $data = $this->request->get('/cgi-bin/token', [ - 'grant_type' => 'client_credential', - 'appid' => $this->config->getAppid(), - 'secret' => $this->config->getAppsecret(), - ]); - if (!$data->isResultsOK()) { - throw new \Exception($data->getMessage()); - } - $access = $data->getData('access_token'); - $this->config->setAccessToken($access); - return $access; - } - - /** - * @param $data - * @param $body - * @return mixed - * @throws \Exception - */ - protected function buildResult($data, $body = NULL) - { - $data = $this->checkSign($data); - if (!$data) { - $return['code'] = -1; - $return['message'] = '签名错误.'; - } else { - if (isset($data['return_code'])) { - if ($data['return_code'] == 'FAIL') { - $return['code'] = -1; - $return['message'] = $data['return_msg']; - } else { - $return['code'] = 0; - $return['data'] = $data; - $return['data']['postBody'] = $body; - } - } else { - if ($data['errcode'] == 'FAIL') { - $return['code'] = -1; - $return['message'] = $data['errmsg']; - } else { - $return['code'] = 0; - $return['data'] = $data; - $return['data']['postBody'] = $body; - } - } - } - return $return; - } - - /** - * @param $result - * @return mixed - * @throws \Exception - */ - protected function checkSign($result) - { - $data = Help::toArray($result); - - if (!isset($data['sign'])) { - return $data; - } - - $sign = $data['sign']; - - unset($data['sign']); - - $key = $this->config->getKey(); - $sign_type = $this->config->getSignType(); - - $_sign = Help::sign($data, $key, $sign_type); - if ($sign != $_sign) { - return FALSE; - } - return $data; - } - -} diff --git a/wchat/common/Multiprogramming.php b/wchat/common/Multiprogramming.php new file mode 100644 index 0000000..acd384b --- /dev/null +++ b/wchat/common/Multiprogramming.php @@ -0,0 +1,115 @@ +errorCode = $code; + } + + /** + * @param $message + */ + public function setErrorMessage($message) + { + $this->errorMsg = $message; + } + + /** + * @return int + */ + public function getErrorCode(): int + { + return $this->errorCode; + } + + /** + * @return string + */ + public function getErrorMessage(): string + { + return $this->errorMsg; + } + + + /** + * @param \wchat\common\Config $config + * @return void + */ + public function setConfig(Config $config): void + { + $this->config = $config; + } + + + /** + * @return \wchat\common\Config + */ + public function getConfig(): \wchat\common\Config + { + return $this->config; + } + + /** + * @param $result + * @return array|bool + * @throws \Exception + */ + protected function checkSign($result): array|bool + { + $data = Help::toArray($result); + + if (!isset($data['sign'])) { + return $data; + } + + $sign = $data['sign']; + + unset($data['sign']); + + $key = $this->config->getKey(); + $sign_type = $this->config->getSignType(); + + $_sign = Help::sign($data, $key, $sign_type); + if ($sign != $_sign) { + return FALSE; + } + return $data; + } + +} diff --git a/wchat/common/Result.php b/wchat/common/Result.php index dd3fbc0..cf5e106 100644 --- a/wchat/common/Result.php +++ b/wchat/common/Result.php @@ -2,6 +2,8 @@ namespace wchat\common; +use JetBrains\PhpStorm\ArrayShape; + /** * Class Result * @@ -14,55 +16,38 @@ namespace wchat\common; */ class Result { - public $code; - public $message; - public $count = 0; - public $data; - public $header; - private $startTime; - private $requestTime; - private $runTime; - public function __construct(array $data) + private ?int $startTime; + private ?int $requestTime; + private ?int $runTime; + + /** + * @param int $code + * @param string $message + * @param int $count + * @param mixed $data + * @param array $header + */ + public function __construct(public int $code, public string $message = '', public int $count = 0, public mixed $data = [], public array $header = [],) { - foreach ($data as $key => $val) { - $this->$key = $val; - } - - $this->header = $this->reloadResponse($this->header); } /** - * @param $header - * - * @return array + * @param $name + * @return mixed */ - private function reloadResponse($header) - { - $data = []; - if (is_array($header)) { - return $header; - } - $load = explode("\n", $header); - if (!empty($load) && is_array($load)) { - foreach ($load as $key => $val) { - if (empty($val)) continue; - $ex = explode(': ', $val); - if (!empty($ex[0]) && !empty($ex[1])) { - $data[trim($ex[0])] = trim($ex[1]); - } - } - } - return $data; - } - public function __get($name) { return $this->$name; } + /** + * @param $name + * @param $value + * @return $this + */ public function __set($name, $value) { $this->$name = $value; @@ -73,7 +58,8 @@ class Result /** * @return array */ - public function getTime() + #[ArrayShape(['startTime' => "int|null", 'requestTime' => "int|null", 'runTime' => "int|null"])] + public function getTime(): array { return [ 'startTime' => $this->startTime, @@ -88,7 +74,7 @@ class Result * @return $this * @throws \Exception */ - public function setAttr($key, $data) + public function setAttr($key, $data): static { if (!property_exists($this, $key)) { throw new \Exception('未查找到相应对象属性'); @@ -100,7 +86,7 @@ class Result /** * @return bool */ - public function isResultsOK() + public function isResultsOK(): bool { if (!is_numeric($this->code)) { return false; @@ -108,32 +94,12 @@ class Result return $this->code == 0; } - /** - * @param array $headers - * 批量设置返回头 - */ - public function setHeaders(array $headers) - { - foreach ($headers as $key => $val) { - $this->setHeader($key, $val); - } - } /** - * @param $key - * @param $val - * 设置返回头 - */ - public function setHeader($key, $val) - { - header($key . ':' . $val); - } - - /** - * @param $name + * @param string $name * @return mixed */ - public function getData($name = '') + public function getData(string $name = ''): mixed { if (!$this->isResultsOK()) { return $this->data; @@ -149,7 +115,7 @@ class Result * @param $data * @return $this */ - public function append($key, $data) + public function append($key, $data): static { if (!is_array($this->data)) { $this->data = ['origin' => $this->data]; @@ -159,17 +125,17 @@ class Result } /** - * @return mixed + * @return string */ - public function getMessage() + public function getMessage(): string { return $this->message; } /** - * @return mixed + * @return int */ - public function getCode() + public function getCode(): int { return $this->code; } diff --git a/wchat/officialaccount/AccessToken.php b/wchat/officialaccount/AccessToken.php deleted file mode 100644 index 2c95eb4..0000000 --- a/wchat/officialaccount/AccessToken.php +++ /dev/null @@ -1,25 +0,0 @@ -config->getToken())) { - return $this->config->getToken(); - } - $requestParam['grant_type'] = 'client_credential'; - $requestParam['appid'] = $this->config->getAppid(); - $requestParam['secret'] = $this->config->getAppsecret(); - - $result = HttpClient::NewRequest()->get($this->url, $requestParam); - if (!$result->isResultsOK()) { - throw new \Exception($result->getMessage(), $result->getCode()); - } - - if ($get_token) { - return $result->getData('access_token'); - } - - return $result->getData(); - } - -} diff --git a/wchat/officialaccount/Authorization.php b/wchat/officialaccount/Authorization.php deleted file mode 100644 index 90899df..0000000 --- a/wchat/officialaccount/Authorization.php +++ /dev/null @@ -1,112 +0,0 @@ -GetAccessTokenByCode($code); - if (!$param->isResultsOK()) { - throw new Exception($param->getMessage()); - } - - $requestParam['access_token'] = $param->getData('access_token'); - $requestParam['openid'] = $param->getData('openid'); - $requestParam['lang'] = 'zh_CN'; - - $client = HttpClient::NewRequest(); - $client->setUseSwoole($this->getConfig()->isUsrSwoole()); - $result = $client->get($this->snsUserInfo, $requestParam); - if ($result->isResultsOK()) { - return $result; - } - - $userInfo = SnsInfo::instance($result->getData()); - $result->append('instance', $userInfo); - - return $result; - } - - /** - * @param $code - * @return array|mixed|Result - */ - private function GetAccessTokenByCode($code) - { - $requestParam['appid'] = $this->config->getAppid(); - $requestParam['secret'] = $this->config->getAppsecret(); - $requestParam['code'] = $code; - $requestParam['grant_type'] = 'authorization_code'; - - $client = HttpClient::NewRequest(); - $client->setUseSwoole($this->getConfig()->isUsrSwoole()); - return $client->get($this->oauth2, $requestParam); - } - - /** - * @param $openid - * @return DAuth - * @throws Exception - * 获取用户信息 - */ - public function To_grant_authorization($openid) - { - $requestParam['access_token'] = $this->config->getAccessToken(); - $requestParam['openid'] = $openid; - $requestParam['lang'] = 'zh_CN'; - - $authorization = $this->request->get($this->url, $requestParam); - if (!$authorization) { - throw new Exception($authorization->getMessage()); - } - - return DAuth::instance($authorization->getData()); - } - - - /** - * @param $long_url - * @return string - * @throws Exception - */ - public function Turn_to_short_chain($long_url) - { - $token = $this->config->getAccessToken(); - $requestParam['action'] = 'long2short'; - $requestParam['long_url'] = $long_url; - - $result = $this->request->post($this->turn . $token, $requestParam); - if (!$result->isResultsOK()) { - throw new Exception($result->getMessage()); - } - return $result->getData('short_url'); - } - -} diff --git a/wchat/officialaccount/Material.php b/wchat/officialaccount/Material.php deleted file mode 100644 index 709bc8c..0000000 --- a/wchat/officialaccount/Material.php +++ /dev/null @@ -1,250 +0,0 @@ - $curlFile, - 'form-data[filename]' => $curlFile->getFilename(), - 'form-data[content-type]' => $curlFile->getMimeType() - ]; - $this->request->setHost('api.weixin.qq.com'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $this->request->addHeader('Content-Type', 'application/json'); - $data = $this->request->upload('/cgi-bin/media/upload?access_token=' . $this->config->getAccessToken() . '&type=' . $type, $data); - if (!$data->isResultsOK()) { - throw new Exception($data->getMessage()); - } - return $data->getData(); - } - - - /** - * @param $filePath - * @param $type - * @return mixed - * @throws Exception - */ - public function addMaterial($filePath, $type) - { - $curlFile = new \CURLFile(realpath($filePath)); - $data = [ - "media" => $curlFile, - 'form-data[filename]' => $curlFile->getFilename(), - 'form-data[content-type]' => $curlFile->getMimeType() - ]; - $this->request->setHost('api.weixin.qq.com'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $this->request->addHeader('Content-Type', 'application/json'); - $data = $this->request->upload('/cgi-bin/material/add_material?access_token=' . $this->config->getAccessToken() . '&type=' . $type, $data); - if (!$data->isResultsOK()) { - throw new Exception($data->getMessage()); - } - return $data->getData(); - } - - - /** - * @param array $articles - * @return mixed - * @throws Exception - */ - public function addNewsMaterial(array $articles) - { - $array['articles'] = []; - foreach ($articles as $article) { - $array['articles'][] = [ - 'title' => $article['title'], - 'thumb_media_id' => $article['thumb_media_id'], - 'author' => $article['author'], - 'digest' => $article['digest'], - 'show_cover_pic' => $article['show_cover_pic'], - 'content' => $article['content'], - 'content_source_url' => $article['content_source_url'], - 'need_open_comment' => $article['need_open_comment'], - 'only_fans_can_comment' => $article['only_fans_can_comment'] - - ]; - } - $this->request->setHost('api.weixin.qq.com'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $this->request->addHeader('Content-Type', 'application/json'); - $data = $this->request->post('/cgi-bin/material/add_news?access_token=' . $this->config->getAccessToken(), $array); - if (!$data->isResultsOK()) { - throw new Exception($data->getMessage()); - } - return $data->getData(); - } - - - /** - * @param $filePath - * @param $type - * @return mixed - * @throws Exception - */ - public function addNewsMaterialImage($filePath, $type) - { - $curlFile = new \CURLFile(realpath($filePath)); - $data = [ - "media" => $curlFile, - 'form-data[filename]' => $curlFile->getFilename(), - 'form-data[content-type]' => $curlFile->getMimeType() - ]; - $this->request->setHost('api.weixin.qq.com'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $this->request->addHeader('Content-Type', 'application/json'); - $data = $this->request->upload('/cgi-bin/material/add_material?access_token=' . $this->config->getAccessToken() . '&type=' . $type, $data); - if (!$data->isResultsOK()) { - throw new Exception($data->getMessage()); - } - return $data->getData(); - } - - - /** - * declare - * @param $media_id - * @return mixed - * @throws Exception - */ - public function getMaterial($media_id) - { - $this->request->setHost('api.weixin.qq.com'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $this->request->addHeader('Content-Type', 'application/json'); - $data = $this->request->post('/cgi-bin/material/get_material?access_token=' . $this->config->getAccessToken(), [ - 'media_id' => $media_id - ]); - if (!$data->isResultsOK()) { - throw new Exception($data->getMessage()); - } - return $data->getData(); - } - - - /** - * declare - * @param $media_id - * @return mixed - * @throws Exception - */ - public function delMaterial($media_id) - { - $this->request->setHost('api.weixin.qq.com'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $this->request->addHeader('Content-Type', 'application/json'); - $data = $this->request->post('/cgi-bin/material/del_material?access_token=' . $this->config->getAccessToken(), [ - 'media_id' => $media_id - ]); - if (!$data->isResultsOK()) { - throw new Exception($data->getMessage()); - } - return $data->getData(); - } - - - /** - * declare - * @param $media_id - * @param int $index - * @param array $articles - * @return mixed - * @throws Exception - */ - public function modifyNewsMaterial($media_id, int $index, array $articles) - { - $this->request->setHost('api.weixin.qq.com'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $this->request->addHeader('Content-Type', 'application/json'); - $data = $this->request->post('/cgi-bin/material/del_material?access_token=' . $this->config->getAccessToken(), [ - 'media_id' => $media_id, - 'index' => $index, - 'articles' => [ - 'title' => $articles['title'], - 'thumb_media_id' => $articles['thumb_media_id'], - 'author' => $articles['author'], - 'digest' => $articles['digest'], - 'show_cover_pic' => $articles['show_cover_pic'], - 'content' => $articles['content'], - 'content_source_url' => $articles['content_source_url'] - ] - ]); - if (!$data->isResultsOK()) { - throw new Exception($data->getMessage()); - } - return $data->getData(); - } - - - /** - * declare - * @return mixed - * @throws Exception - */ - public function getMaterialCount() - { - $this->request->setHost('api.weixin.qq.com'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $this->request->addHeader('Content-Type', 'application/json'); - $data = $this->request->get('/cgi-bin/material/get_materialcount?access_token=' . $this->config->getAccessToken()); - if (!$data->isResultsOK()) { - throw new Exception($data->getMessage()); - } - return $data->getData(); - } - - - /** - * declare - * @param int $offset - * @param int $size - * @param $type - * @return mixed - * @throws Exception - */ - public function getMaterialList(int $offset, int $size, $type) - { - $this->request->setHost('api.weixin.qq.com'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $this->request->addHeader('Content-Type', 'application/json'); - $data = $this->request->post('/cgi-bin/material/batchget_material?access_token=' . $this->config->getAccessToken(), [ - 'type' => $type, - 'offset' => $offset, - 'count' => $size - ]); - if (!$data->isResultsOK()) { - throw new Exception($data->getMessage()); - } - return $data->getData(); - } -} diff --git a/wchat/officialaccount/NewsManager.php b/wchat/officialaccount/NewsManager.php deleted file mode 100644 index 084daae..0000000 --- a/wchat/officialaccount/NewsManager.php +++ /dev/null @@ -1,178 +0,0 @@ - '签名验证错误', - self::ParseXmlError => 'xml解析失败', - self::ComputeSignatureError => 'sha加密生成签名失败', - self::IllegalAesKey => 'encodingAesKey 非法', - self::ValidateAppidError => 'appid 校验错误', - self::EncryptAESError => 'aes 加密失败', - self::DecryptAESError => 'aes 解密失败', - self::IllegalBuffer => '解密后得到的buffer非法', - self::EncodeBase64Error => 'base64加密失败', - self::DecodeBase64Error => 'base64解密失败', - self::GenReturnXmlError => '生成xml失败', - ]; - return $messages[$code] ?? 'OK'; - } - - /** - * 将公众平台回复用户的消息加密打包. - *
    - *
  1. 对要发送的消息进行AES-CBC加密
  2. - *
  3. 生成安全签名
  4. - *
  5. 将消息密文和安全签名打包成xml格式
  6. - *
- * - * @param $replyMsg 公众平台待回复用户的消息,xml格式的字符串 - * @param $timeStamp 时间戳,可以自己生成,也可以用URL参数的timestamp - * @param $nonce 随机串,可以自己生成,也可以用URL参数的nonce - * @param &$encryptMsg 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串, - * 当return返回0时有效 - * - * @return int 成功0,失败返回对应的错误码 - */ - public function encryptMsg($replyMsg, $timeStamp, $nonce, &$encryptMsg) - { - $pc = new Prpcrypt($this->config->getEncodingAesKey()); - - //加密 - $array = $pc->encrypt($replyMsg, $this->config->getAppid()); - $ret = $array[0]; - if ($ret != 0) { - return $ret; - } - - if ($timeStamp == null) { - $timeStamp = time(); - } - $encrypt = $array[1]; - - //生成安全签名 - $array = $this->getSHA1($this->config->getToken(), $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 self::OK; - } - - - /** - * 检验消息的真实性,并且获取解密后的明文. - *
    - *
  1. 利用收到的密文生成安全签名,进行签名验证
  2. - *
  3. 若验证通过,则提取xml中的加密消息
  4. - *
  5. 对消息进行解密
  6. - *
- * - * @param $msgSignature 签名串,对应URL参数的msg_signature - * @param $timestamp 时间戳 对应URL参数的timestamp - * @param $nonce 随机串,对应URL参数的nonce - * @param $postData 密文,对应POST请求的数据 - * @param &$msg 解密后的原文,当return返回0时有效 - * - * @return int 成功0,失败返回对应的错误码 - */ - public function decryptMsg($msgSignature, $timestamp, $nonce, $postData, &$msg) - { - if (strlen($this->config->getEncodingAesKey()) != 43) { - return self::IllegalAesKey; - } - - $pc = new Prpcrypt($this->config->getEncodingAesKey()); - - //提取密文 - $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]; - - //验证安全签名 - $array = $this->getSHA1($this->config->getToken(), $timestamp, $nonce, $encrypt); - $ret = $array[0]; - - if ($ret != 0) { - return $ret; - } - - $signature = $array[1]; - if ($signature != $msgSignature) { - return self::ValidateSignatureError; - } - - $result = $pc->decrypt($encrypt, $this->config->getAppid()); - if ($result[0] != 0) { - return $result[0]; - } - $msg = $result[1]; - - return self::OK; - } - - /** - * @param $token - * @param $timestamp - * @param $nonce - * @param $encrypt_msg - * @return array - */ - private function getSHA1($token, $timestamp, $nonce, $encrypt_msg) - { - //排序 - try { - $array = array($encrypt_msg, $token, $timestamp, $nonce); - sort($array, SORT_STRING); - $str = implode($array); - return array(self::OK, sha1($str)); - } catch (\Exception $e) { - //print $e . "\n"; - return array(self::ComputeSignatureError, null); - } - } - -} diff --git a/wchat/officialaccount/QrCode.php b/wchat/officialaccount/QrCode.php deleted file mode 100644 index caee85b..0000000 --- a/wchat/officialaccount/QrCode.php +++ /dev/null @@ -1,75 +0,0 @@ -get_tick($requestParam); - - $client = HttpClient::NewRequest(); - return $client->get($this->temporary_url, ['ticket' => $tick]); - } - - - /** - * @param $scene_id - * @return array|mixed|\common\Result - * @throws \Exception - */ - public function permanent_qr_code($scene_id) - { - $requestParam['action_name'] = 'QR_LIMIT_SCENE'; - $requestParam['action_info[scene][scene_id]'] = $scene_id; - - $tick = $this->get_tick($requestParam); - - $client = HttpClient::NewRequest(); - return $client->get($this->permanent_qr_code_url, ['ticket' => $tick]); - } - - - /** - * @param $requestParam - * @return mixed - * @throws \Exception - * tick - */ - private function get_tick($requestParam) - { - $request = HttpClient::NewRequest(); - $request->setCallback(function ($body) { - if (is_array($body)) { - $param = ['code' => $body['errcode'], 'message' => $body['errmsg'], 'data' => $body]; - } else { - $param = ['code' => 0, 'data' => json_decode($body, true)]; - } - return new Result($param); - }); - $data = $request->post($this->tick_url . $this->config->getAccessToken(), json_encode($requestParam)); - if (!$data->isResultsOK()) { - throw new \Exception($data->getMessage()); - } - return $data->getData('ticket'); - } - -} diff --git a/wchat/officialaccount/SourceMaterial.php b/wchat/officialaccount/SourceMaterial.php deleted file mode 100644 index d82b882..0000000 --- a/wchat/officialaccount/SourceMaterial.php +++ /dev/null @@ -1,100 +0,0 @@ -sendError('文件不存在.', 404); - } - return $this->upload($file, 'image'); - } - - /** - * @param $file - * @return bool|mixed|Result - */ - public function VoiceUpload($file) - { - if (!file_exists($file)) { - return $this->sendError('文件不存在.', 404); - } - return $this->upload($file, 'voice'); - } - - /** - * @param $file - * @return bool|mixed|Result - */ - public function VideoUpload($file) - { - if (!file_exists($file)) { - return $this->sendError('文件不存在.', 404); - } - return $this->upload($file, 'video'); - } - - /** - * @param $file - * @return bool|mixed|Result - */ - public function ThumbUpload($file) - { - if (!file_exists($file)) { - return $this->sendError('文件不存在.', 404); - } - return $this->upload($file, 'thumb'); - } - - - /** - * @param $media_id - * @return array|mixed|Result - */ - public function MediaGet($media_id) - { - $client = HttpClient::NewRequest(); - - $accessToken = $this->config->getAccessToken(); - - return $client->get($this->getUploadUrl, ['access_token' => $accessToken, 'media_id' => $media_id]); - } - - /** - * @param $file - * @param $type - * @return bool|mixed - */ - private function upload($file, $type) - { - $uploadInfo['media'] = new \CURLFile($file); - $uploadInfo['form-data[filename]'] = $uploadInfo['media']->getFilename(); - $uploadInfo['form-data[Content-Type]'] = $uploadInfo['media']->getMimeType(); - - $accessToken = $this->config->getAccessToken(); - - $url = $this->uploadUrl . 'access_token=' . $accessToken . '&type=' . $type; - $result = $this->request->post($url, $uploadInfo); - if (!$result->isResultsOK()) { - return false; - } - return $result->getData(); - } - -} diff --git a/wchat/officialaccount/Subscribe.php b/wchat/officialaccount/Subscribe.php deleted file mode 100644 index 7030d4f..0000000 --- a/wchat/officialaccount/Subscribe.php +++ /dev/null @@ -1,118 +0,0 @@ -openid = $openid; - return $this; - } - - /** - * @param $template_id - * @return Subscribe - */ - public function setTemplateId($template_id): Subscribe - { - $this->template_id = $template_id; - return $this; - } - - /** - * @param $url - * @return Subscribe - */ - public function setUrl($url): Subscribe - { - $this->url = $url; - return $this; - } - - /** - * @param $appid - * @param $path - * @return Subscribe - */ - public function setMiniprogram($appid, $path): Subscribe - { - $this->miniprogram['appid'] = $appid; - $this->miniprogram['pagepath'] = $path; - return $this; - } - - /** - * @param $scene - * @return Subscribe - */ - public function setScene($scene): Subscribe - { - $this->scene = $scene; - return $this; - } - - /** - * @param $title - * @return Subscribe - */ - public function setTitle($title): Subscribe - { - $this->title = $title; - return $this; - } - - - /** - * @param $keyword - * @param $content - * @param null $color - */ - public function addContent($keyword, $content, $color = null) - { - $param['value'] = $content; - if (!empty($color)) { - $param['color'] = $color; - } - $this->keywords[$keyword] = $param; - } - - /** - * @return array|mixed|\wchat\common\Result - */ - public function sendSubscribeMessage() - { - $requestParam['touser'] = $this->openid; - $requestParam['template_id'] = $this->template_id; - $requestParam['url'] = $this->url; - $requestParam['miniprogram'] = $this->miniprogram; - $requestParam['scene'] = $this->scene; - $requestParam['title'] = $this->title; - $requestParam['data'] = $this->keywords; - - $requestUrl = $this->pushUrl . $this->config->getAccessToken(); - - $client = HttpClient::NewRequest(); - return $client->post($requestUrl, $requestParam); - } - -} diff --git a/wchat/officialaccount/Tag.php b/wchat/officialaccount/Tag.php deleted file mode 100644 index 2320185..0000000 --- a/wchat/officialaccount/Tag.php +++ /dev/null @@ -1,157 +0,0 @@ - $tagName]; - - $config = $this->config->getAccessToken(); - - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - - $this->request->setData(json_encode($params, JSON_UNESCAPED_UNICODE)); - return $this->request->post($this->generate_url . $config); - } - - /** - * @param $id - * @param $tagName - * @return Result - * @throws \Exception - */ - public function tag_edit($id, $tagName) - { - $url['tag[id]'] = $id; - $url['tag[name]'] = $tagName; - - $config = $this->config->getAccessToken(); - - - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - - return $this->request->post($this->tag_edit . $config, $url); - } - - - /** - * @param $id - * @return Result - * @throws \Exception - */ - public function tag_delete($id) - { - $url['tag[id]'] = $id; - - $config = $this->config->getAccessToken(); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - return $this->request->post($this->tag_delete . $config, $url); - } - - - /** - * @param $id - * @param string[] $openid_list - * @return Result - * @throws \Exception - */ - public function user_batch_add_tag($id, array $openid_list) - { - $url['tagid'] = $id; - $url['openid_list'] = $openid_list; - - $config = $this->config->getAccessToken(); - - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $this->request->setData(json_encode($url, JSON_UNESCAPED_UNICODE)); - return $this->request->post($this->user_batch_add_tag . $config); - } - - - /** - * @param $id - * @param string[] $openid_list - * @return Result - * @throws \Exception - */ - public function user_batch_remove_tag($id, array $openid_list) - { - $url['tagid'] = $id; - $url['openid_list'] = $openid_list; - - $config = $this->config->getAccessToken(); - - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - return $this->request->post($this->user_batch_remove_tag . $config, $url); - } - - - /** - * @return Result - * @throws \Exception - */ - public function tagList() - { - $config = $this->config->getAccessToken(); - - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - return $this->request->get($this->tag_lists . $config, []); - } - - - /** - * @return Result - * @throws \Exception - */ - public function tag_fans_list() - { - $config = $this->config->getAccessToken(); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - return $this->request->get($this->tag_fans_list . $config); - } - - - /** - * @param $openid - * @return Result - * @throws \Exception - */ - public function user_tag($openid) - { - $config = $this->config->getAccessToken(); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - return $this->request->post($this->user_tag . $config, [ - 'openid' => $openid - ]); - } - -} diff --git a/wchat/officialaccount/WxSDK.php b/wchat/officialaccount/WxSDK.php deleted file mode 100644 index 1fe7573..0000000 --- a/wchat/officialaccount/WxSDK.php +++ /dev/null @@ -1,41 +0,0 @@ -setSubscribe($object['subscribe'] ?? null); - $class->setOpenid($object['openid'] ?? null); - $class->setNickname($object['nickname'] ?? null); - $class->setSex($object['sex'] ?? null); - $class->setLanguage($object['language'] ?? null); - $class->setCity($object['city'] ?? null); - $class->setProvince($object['province'] ?? null); - $class->setCountry($object['country'] ?? null); - $class->setHeadimgurl($object['headimgurl'] ?? null); - $class->setSubscribeTime($object['subscribe_time'] ?? null); - $class->setUnionid($object['unionid'] ?? null); - $class->setRemark($object['remark'] ?? null); - $class->setGroupid($object['groupid'] ?? null); - $class->setTagidList($object['tagid_list'] ?? null); - $class->setSubscribeScene($object['subscribe_scene'] ?? null); - $class->setQrScene($object['qr_scene'] ?? null); - $class->setQrSceneStr($object['qr_scene_str'] ?? null); - return $class; - } - - /** - * @return mixed - */ - public function getSubscribe() - { - return $this->subscribe; - } - - /** - * @param mixed $subscribe - * @return Authorization - */ - public function setSubscribe($subscribe) - { - $this->subscribe = $subscribe; - return $this; - } - - /** - * @return mixed - */ - public function getOpenid() - { - return $this->openid; - } - - /** - * @param mixed $openid - * @return Authorization - */ - public function setOpenid($openid) - { - $this->openid = $openid; - return $this; - } - - /** - * @return mixed - */ - public function getNickname() - { - return $this->nickname; - } - - /** - * @param mixed $nickname - * @return Authorization - */ - public function setNickname($nickname) - { - $this->nickname = $nickname; - return $this; - } - - /** - * @return mixed - */ - public function getSex() - { - return $this->sex; - } - - /** - * @param mixed $sex - * @return Authorization - */ - public function setSex($sex) - { - $this->sex = $sex; - return $this; - } - - /** - * @return mixed - */ - public function getLanguage() - { - return $this->language; - } - - /** - * @param mixed $language - * @return Authorization - */ - public function setLanguage($language) - { - $this->language = $language; - return $this; - } - - /** - * @return mixed - */ - public function getCity() - { - return $this->city; - } - - /** - * @param mixed $city - * @return Authorization - */ - public function setCity($city) - { - $this->city = $city; - return $this; - } - - /** - * @return mixed - */ - public function getProvince() - { - return $this->province; - } - - /** - * @param mixed $province - * @return Authorization - */ - public function setProvince($province) - { - $this->province = $province; - return $this; - } - - /** - * @return mixed - */ - public function getCountry() - { - return $this->country; - } - - /** - * @param mixed $country - * @return Authorization - */ - public function setCountry($country) - { - $this->country = $country; - return $this; - } - - /** - * @return mixed - */ - public function getHeadimgurl() - { - return $this->headimgurl; - } - - /** - * @param mixed $headimgurl - * @return Authorization - */ - public function setHeadimgurl($headimgurl) - { - $this->headimgurl = $headimgurl; - return $this; - } - - /** - * @return mixed - */ - public function getSubscribeTime() - { - return $this->subscribe_time; - } - - /** - * @param mixed $subscribe_time - * @return Authorization - */ - public function setSubscribeTime($subscribe_time) - { - $this->subscribe_time = $subscribe_time; - return $this; - } - - /** - * @return mixed - */ - public function getUnionid() - { - return $this->unionid; - } - - /** - * @param mixed $unionid - * @return Authorization - */ - public function setUnionid($unionid) - { - $this->unionid = $unionid; - return $this; - } - - /** - * @return mixed - */ - public function getRemark() - { - return $this->remark; - } - - /** - * @param mixed $remark - * @return Authorization - */ - public function setRemark($remark) - { - $this->remark = $remark; - return $this; - } - - /** - * @return mixed - */ - public function getGroupid() - { - return $this->groupid; - } - - /** - * @param mixed $groupid - * @return Authorization - */ - public function setGroupid($groupid) - { - $this->groupid = $groupid; - return $this; - } - - /** - * @return mixed - */ - public function getTagidList() - { - return $this->tagid_list; - } - - /** - * @param mixed $tagid_list - * @return Authorization - */ - public function setTagidList($tagid_list) - { - $this->tagid_list = $tagid_list; - return $this; - } - - /** - * @return mixed - */ - public function getSubscribeScene() - { - return $this->subscribe_scene; - } - - /** - * @param mixed $subscribe_scene - * @return Authorization - */ - public function setSubscribeScene($subscribe_scene) - { - $this->subscribe_scene = $subscribe_scene; - return $this; - } - - /** - * @return mixed - */ - public function getQrScene() - { - return $this->qr_scene; - } - - /** - * @param mixed $qr_scene - * @return Authorization - */ - public function setQrScene($qr_scene) - { - $this->qr_scene = $qr_scene; - return $this; - } - - /** - * @return mixed - */ - public function getQrSceneStr() - { - return $this->qr_scene_str; - } - - /** - * @param mixed $qr_scene_str - * @return Authorization - */ - public function setQrSceneStr($qr_scene_str) - { - $this->qr_scene_str = $qr_scene_str; - return $this; - } - - -} diff --git a/wchat/officialaccount/dcaler/PKCS7Encoder.php b/wchat/officialaccount/dcaler/PKCS7Encoder.php deleted file mode 100644 index 19dfb58..0000000 --- a/wchat/officialaccount/dcaler/PKCS7Encoder.php +++ /dev/null @@ -1,46 +0,0 @@ - 32) { - $pad = 0; - } - return substr($text, 0, (strlen($text) - $pad)); - } -} diff --git a/wchat/officialaccount/dcaler/Prpcrypt.php b/wchat/officialaccount/dcaler/Prpcrypt.php deleted file mode 100644 index d19d984..0000000 --- a/wchat/officialaccount/dcaler/Prpcrypt.php +++ /dev/null @@ -1,119 +0,0 @@ -key = base64_decode($k . "="); - } - - /** - * @param $text - * @param $appid - * @return array - */ - 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(NewsManager::OK, base64_encode($encrypted)); - } catch (\Exception $e) { - //print $e; - return array(NewsManager::EncryptAESError, null); - } - } - - /** - * @param $encrypted - * @param $appid - * @return array|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(NewsManager::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(NewsManager::IllegalBuffer, null); - } - if ($from_appid != $appid) - return array(NewsManager::ValidateAppidError, null); - return array(0, $xml_content); - - } - - - /** - * 随机生成16位字符串 - * @return 生成的字符串 - */ - 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; - } - -} diff --git a/wchat/officialaccount/dcaler/SnsInfo.php b/wchat/officialaccount/dcaler/SnsInfo.php deleted file mode 100644 index caec518..0000000 --- a/wchat/officialaccount/dcaler/SnsInfo.php +++ /dev/null @@ -1,204 +0,0 @@ -openid; - } - - /** - * @param mixed $openid - * @return SnsInfo - */ - public function setOpenid($openid) - { - $this->openid = $openid; - return $this; - } - - /** - * @return mixed - */ - public function getNickname() - { - return $this->nickname; - } - - /** - * @param mixed $nickname - * @return SnsInfo - */ - public function setNickname($nickname) - { - $this->nickname = $nickname; - return $this; - } - - /** - * @return mixed - */ - public function getSex() - { - return $this->sex; - } - - /** - * @param mixed $sex - * @return SnsInfo - */ - public function setSex($sex) - { - $this->sex = $sex; - return $this; - } - - /** - * @return mixed - */ - public function getProvince() - { - return $this->province; - } - - /** - * @param mixed $province - * @return SnsInfo - */ - public function setProvince($province) - { - $this->province = $province; - return $this; - } - - /** - * @return mixed - */ - public function getCity() - { - return $this->city; - } - - /** - * @param mixed $city - * @return SnsInfo - */ - public function setCity($city) - { - $this->city = $city; - return $this; - } - - /** - * @return mixed - */ - public function getCountry() - { - return $this->country; - } - - /** - * @param mixed $country - * @return SnsInfo - */ - public function setCountry($country) - { - $this->country = $country; - return $this; - } - - /** - * @return mixed - */ - public function getHeadimgurl() - { - return $this->headimgurl; - } - - /** - * @param mixed $headimgurl - * @return SnsInfo - */ - public function setHeadimgurl($headimgurl) - { - $this->headimgurl = $headimgurl; - return $this; - } - - /** - * @return mixed - */ - public function getPrivilege() - { - return $this->privilege; - } - - /** - * @param mixed $privilege - * @return SnsInfo - */ - public function setPrivilege($privilege) - { - $this->privilege = $privilege; - return $this; - } - - /** - * @return mixed - */ - public function getUnionid() - { - return $this->unionid; - } - - /** - * @param mixed $unionid - * @return SnsInfo - */ - public function setUnionid($unionid) - { - $this->unionid = $unionid; - return $this; - } - - - - /** - * @param $object - * @return SnsInfo - */ - public static function instance($object) - { - $class = new SnsInfo(); - $class->setOpenid($object['openid']); - $class->setNickname($object['nickname']); - $class->setSex($object['sex']); - $class->setCity($object['city']); - $class->setProvince($object['province']); - $class->setCountry($object['country']); - $class->setHeadimgurl($object['headimgurl']); - $class->setUnionid($object['unionid']); - $class->setPrivilege($object['privilege']); - return $class; - } - - -} diff --git a/wchat/officialaccount/dcaler/XMLParse.php b/wchat/officialaccount/dcaler/XMLParse.php deleted file mode 100644 index 0cee4b8..0000000 --- a/wchat/officialaccount/dcaler/XMLParse.php +++ /dev/null @@ -1,49 +0,0 @@ -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 [0, $encrypt, $tousername]; - } catch (\Exception $e) { - return [NewsManager::ParseXmlError, null, null]; - } - } - - /** - * @param $encrypt - * @param $signature - * @param $timestamp - * @param $nonce - * @return string - */ - public function generate($encrypt, $signature, $timestamp, $nonce) - { - $format = " - - -%s - -"; - return sprintf($format, $encrypt, $signature, $timestamp, $nonce); - } - -} diff --git a/wchat/qq/Account.php b/wchat/qq/Account.php index e5ac295..c23f269 100644 --- a/wchat/qq/Account.php +++ b/wchat/qq/Account.php @@ -8,58 +8,39 @@ namespace wchat\qq; +use Kiri\Client; use wchat\common\Decode; use wchat\common\HttpClient; use wchat\common\Result; class Account extends SmallProgram { + /** - * @param $code + * @param string $code * @return Result */ - public function login($code) + public function login(string $code): Result { $param['appid'] = $this->config->getAppid(); $param['secret'] = $this->config->getAppsecret(); $param['js_code'] = $code; $param['grant_type'] = 'authorization_code'; - if (empty($code)) { - return new Result(['code' => 404, 'message' => '临时登录凭证不能为空.']); + $client = new Client('api.q.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->get('sns/jscode2session', $param); + $client->close(); + + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errcode']) && $body['errcode'] != 0) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } else { + return new Result(code: 0, data: $body); } - - $this->request->setHost('api.q.qq.com'); - $this->request->addHeader('Host', 'api.q.qq.com'); - $this->request->setMethod(HttpClient::GET); - $this->request->setIsSSL(true); - $this->request->setUseSwoole($this->config->isUsrSwoole()); - - return $this->request->get('sns/jscode2session', $param); - } - - /** - * @param $encryptedData - * @param $iv - * @param $sessionKey - * @param $asArray - * @return object|array - * @throws - * - * *
  • -41001: encodingAesKey 非法
  • - *
  • -41003: aes 解密失败
  • - *
  • -41004: 解密后得到的buffer非法
  • - *
  • -41005: base64加密失败
  • - *
  • -41016: base64解密失败
  • - */ - public function decode($encryptedData, $iv, $sessionKey, $asArray = false) - { - $decode = new Decode(); - $decode->setAppId($this->config->getAppid()); - $decode->setIv($iv); - $decode->setEncryptedData($encryptedData); - $decode->setSessionKey($sessionKey); - return $decode->decode($asArray); } } diff --git a/wchat/qq/GamePrePay.php b/wchat/qq/GamePrePay.php deleted file mode 100644 index 4d053a5..0000000 --- a/wchat/qq/GamePrePay.php +++ /dev/null @@ -1,13 +0,0 @@ -getTradeState() === 'SUCCESS'; + return $this->trade_state === 'SUCCESS'; } /** @@ -44,26 +44,31 @@ class Notify extends SmallProgram * @return $this * @throws Exception */ - public function setPayNotifyData(array $params) + public function setPayNotifyData(array $params): static { if (!$this->validation($params)) { throw new Exception('签名错误!'); } foreach ($params as $key => $val) { - if (!property_exists($this, $key)) { - continue; - } $this->$key = $val; } return $this; } + public function __set(string $name, $value): void + { + if (property_exists($this, $name)) { + $this->{$name} = $value; + } + } + + /** * @param array $params * @return bool */ - public function validation(array $params) + public function validation(array $params): bool { $sign = $params['sign']; unset($params['sign']); @@ -85,303 +90,5 @@ class Notify extends SmallProgram return $this->appid; } - /** - * @param null $appid - * @return Notify - */ - public function setAppid($appid) - { - $this->appid = $appid; - return $this; - } - - /** - * @return null - */ - public function getMchId() - { - return $this->mch_id; - } - - /** - * @param null $mch_id - * @return Notify - */ - public function setMchId($mch_id) - { - $this->mch_id = $mch_id; - return $this; - } - - /** - * @return null - */ - public function getNonceStr() - { - return $this->nonce_str; - } - - /** - * @param null $nonce_str - * @return Notify - */ - public function setNonceStr($nonce_str) - { - $this->nonce_str = $nonce_str; - return $this; - } - - /** - * @return null - */ - public function getSign() - { - return $this->sign; - } - - /** - * @param null $sign - * @return Notify - */ - public function setSign($sign) - { - $this->sign = $sign; - return $this; - } - - /** - * @return null - */ - public function getDeviceInfo() - { - return $this->device_info; - } - - /** - * @param null $device_info - * @return Notify - */ - public function setDeviceInfo($device_info) - { - $this->device_info = $device_info; - return $this; - } - - /** - * @return null - */ - public function getTradeType() - { - return $this->trade_type; - } - - /** - * @param null $trade_type - * @return Notify - */ - public function setTradeType($trade_type) - { - $this->trade_type = $trade_type; - return $this; - } - - /** - * @return null - */ - public function getTradeState() - { - return $this->trade_state; - } - - /** - * @param null $trade_state - * @return Notify - */ - public function setTradeState($trade_state) - { - $this->trade_state = $trade_state; - return $this; - } - - /** - * @return null - */ - public function getBankType() - { - return $this->bank_type; - } - - /** - * @param null $bank_type - * @return Notify - */ - public function setBankType($bank_type) - { - $this->bank_type = $bank_type; - return $this; - } - - /** - * @return null - */ - public function getFeeType() - { - return $this->fee_type; - } - - /** - * @param null $fee_type - * @return Notify - */ - public function setFeeType($fee_type) - { - $this->fee_type = $fee_type; - return $this; - } - - /** - * @return null - */ - public function getTotalFee() - { - return $this->total_fee; - } - - /** - * @param null $total_fee - * @return Notify - */ - public function setTotalFee($total_fee) - { - $this->total_fee = $total_fee; - return $this; - } - - /** - * @return null - */ - public function getCashFee() - { - return $this->cash_fee; - } - - /** - * @param null $cash_fee - * @return Notify - */ - public function setCashFee($cash_fee) - { - $this->cash_fee = $cash_fee; - return $this; - } - - /** - * @return null - */ - public function getCouponFee() - { - return $this->coupon_fee; - } - - /** - * @param null $coupon_fee - * @return Notify - */ - public function setCouponFee($coupon_fee) - { - $this->coupon_fee = $coupon_fee; - return $this; - } - - /** - * @return null - */ - public function getTransactionId() - { - return $this->transaction_id; - } - - /** - * @param null $transaction_id - * @return Notify - */ - public function setTransactionId($transaction_id) - { - $this->transaction_id = $transaction_id; - return $this; - } - - /** - * @return null - */ - public function getOutTradeNo() - { - return $this->out_trade_no; - } - - /** - * @param null $out_trade_no - * @return Notify - */ - public function setOutTradeNo($out_trade_no) - { - $this->out_trade_no = $out_trade_no; - return $this; - } - - /** - * @return null - */ - public function getAttach() - { - return $this->attach; - } - - /** - * @param null $attach - * @return Notify - */ - public function setAttach($attach) - { - $this->attach = $attach; - return $this; - } - - /** - * @return null - */ - public function getTimeEnd() - { - return $this->time_end; - } - - /** - * @param null $time_end - * @return Notify - */ - public function setTimeEnd($time_end) - { - $this->time_end = $time_end; - return $this; - } - - /** - * @return null - */ - public function getOpenid() - { - return $this->openid; - } - - /** - * @param null $openid - * @return Notify - */ - public function setOpenid($openid) - { - $this->openid = $openid; - return $this; - } - } diff --git a/wchat/qq/QqFactory.php b/wchat/qq/QqFactory.php new file mode 100644 index 0000000..7ab1a91 --- /dev/null +++ b/wchat/qq/QqFactory.php @@ -0,0 +1,26 @@ +get($class); + $object->setConfig($config); + return $object; + } + + +} diff --git a/wchat/qq/Recharge.php b/wchat/qq/Recharge.php index 8179e9d..e777e8e 100644 --- a/wchat/qq/Recharge.php +++ b/wchat/qq/Recharge.php @@ -9,6 +9,7 @@ namespace wchat\qq; use Exception; +use Kiri\Client; use wchat\common\HttpClient; use wchat\common\Result; use wchat\common\Help; @@ -35,47 +36,60 @@ class Recharge extends SmallProgram /** * @param int $money - * @param $orderNo - * @param $openId - * @return array|mixed|Result + * @param string $orderNo + * @param string $openId + * @return Result * @throws */ - public function recharge(int $money, $orderNo, $openId = '') + public function recharge(int $money, string $orderNo, string $openId = ''): Result { if ($money < 0) { - return new Result(['code' => 500, 'message' => '充值金额不能小于0.']); + return new Result(code: 500, message: '充值金额不能小于0.'); } $this->money = $money; $this->orderNo = $orderNo; $this->data['openid'] = $openId; - $this->request->setCallback(function ($result, $body) { - $data = Help::toArray($result); - if (isset($data['sign'])) { - $sign = $data['sign']; - unset($data['sign']); - } - if (!isset($sign)) { - $return['code'] = -1; - $return['message'] = '返回数据签名验证失败'; - } else { - $return['code'] = 0; - $return['data'] = $data; - $return['data']['postBody'] = $body; - if ($data['return_code'] == 'FAIL') { - $return['code'] = -1; - $return['message'] = $data['return_msg']; - } - } - return new Result($return); - }); - return $this->send($this->uniformer, $this->builder()); + $client = new Client('qpay.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/xml']); + $client->withBody($this->builder()); + $client->post($this->uniformer); + $client->close(); + + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + + $data = Help::toArray($client->getBody()); + if (isset($data['return_code']) && $data['return_code'] != 'SUCCESS') { + return new Result(code: 503, message: $data['return_msg']); + } + if ($data['result_code'] != 'SUCCESS') { + return new Result(code: 504, message: $data['err_code_des']); + } + + return new Result(code: 0, data: $this->reception($data['prepayid'])); + } + + + /** + * @param string $prepay_id + * @return string + */ + public function reception(string $prepay_id): string + { + return Help::sign([ + 'signType' => $this->config->getSignType(), + 'package' => 'prepay_id=' . $prepay_id, + 'nonceStr' => Help::random(32), + 'timestamp' => time() + ], $this->getConfig()->getKey(), $this->getConfig()->getSignType()); } /** * @return string */ - protected function builder() + protected function builder(): string { $data = [ 'appid' => $this->config->getAppid(), @@ -99,18 +113,4 @@ class Recharge extends SmallProgram return Help::toXml($this->data); } - - /** - * @param $url - * @param $data - * @return array|mixed|Result - * @throws Exception - */ - private function send($url, $data) - { - $this->request->setIsSSL(true); - $this->request->setMethod(HttpClient::POST); - $this->request->addHeader('Content-Type', 'text/xml'); - return $this->request->send($url, $data); - } } diff --git a/wchat/qq/Redhat.php b/wchat/qq/Redhat.php index bbd4174..f165f31 100644 --- a/wchat/qq/Redhat.php +++ b/wchat/qq/Redhat.php @@ -3,399 +3,388 @@ namespace wchat\qq; +use Kiri\Client; use wchat\common\Help; use wchat\common\Result; -use qq\result\RedHatResult; class Redhat extends SmallProgram { - private $charset = 'UTF8'; - private $nonce_str = ''; - private $sign = ''; - private $mch_billno = ''; - private $mch_id = ''; - private $mch_name = ''; - private $qqappid = ''; - private $re_openid = ''; - private $total_amount = ''; - private $total_num = ''; - private $wishing = ''; - private $act_name = ''; - private $icon_id = ''; - private $banner_id = ''; - private $notify_url = ''; - private $not_send_msg = ''; - private $min_value = ''; - private $max_value = ''; - private $key = ''; - private $signType = ''; + private string $charset = 'UTF8'; + private string $nonce_str = ''; + private string $sign = ''; + private string $mch_billno = ''; + private string $mch_id = ''; + private string $mch_name = ''; + private string $qqappid = ''; + private string $re_openid = ''; + private string $total_amount = ''; + private string $total_num = ''; + private string $wishing = ''; + private string $act_name = ''; + private string $icon_id = ''; + private string $banner_id = ''; + private string $notify_url = ''; + private string $not_send_msg = ''; + private string $min_value = ''; + private string $max_value = ''; + private string $key = ''; + private string $signType = ''; - private $sendUrl = 'https://api.qpay.qq.com/cgi-bin/hongbao/qpay_hb_mch_send.cgi'; - private $searchUrl = 'https://qpay.qq.com/cgi-bin/mch_query/qpay_hb_mch_list_query.cgi'; + private string $sendUrl = '/cgi-bin/hongbao/qpay_hb_mch_send.cgi'; + private string $searchUrl = '/cgi-bin/mch_query/qpay_hb_mch_list_query.cgi'; /** * @return string */ - public function getKey() - { - return $this->key; - } - - /** - * @param $key - * @return Redhat - */ - public function setKey($key): Redhat - { - $this->key = $key; - return $this; - } - - /** - * @return string - */ - public function getSignType() - { - return $this->signType; - } - - /** - * @param $signType - * @return Redhat - */ - public function setSignType($signType): Redhat - { - $this->signType = $signType; - return $this; - } - - /** - * @return string - */ - public function getCharset() + public function getCharset(): string { return $this->charset; } /** - * @param $charset - * @return Redhat + * @param string $charset */ - public function setCharset($charset): Redhat + public function setCharset(string $charset): void { $this->charset = $charset; - return $this; } /** * @return string */ - public function getNonceStr() + public function getNonceStr(): string { return $this->nonce_str; } /** - * @param $nonce_str - * @return Redhat + * @param string $nonce_str */ - public function setNonceStr($nonce_str): Redhat + public function setNonceStr(string $nonce_str): void { $this->nonce_str = $nonce_str; - return $this; } /** * @return string */ - public function getSign() + public function getSign(): string { return $this->sign; } /** - * @param $sign - * @return Redhat + * @param string $sign */ - public function setSign($sign): Redhat + public function setSign(string $sign): void { $this->sign = $sign; - return $this; } /** * @return string */ - public function getMchBillno() + public function getMchBillno(): string { - if (empty($this->mch_billno)) { - return '1559179381' . date('Ymd') . mt_rand(11, 99) . date('His') . mt_rand(11, 99); - } return $this->mch_billno; } /** - * @param $mch_billno - * @return Redhat + * @param string $mch_billno */ - public function setMchBillno($mch_billno): Redhat + public function setMchBillno(string $mch_billno): void { $this->mch_billno = $mch_billno; - return $this; } /** * @return string */ - public function getMchId() + public function getMchId(): string { return $this->mch_id; } /** - * @param $mch_id - * @return Redhat + * @param string $mch_id */ - public function setMchId($mch_id): Redhat + public function setMchId(string $mch_id): void { $this->mch_id = $mch_id; - return $this; } /** * @return string */ - public function getMchName() + public function getMchName(): string { return $this->mch_name; } /** - * @param $mch_name - * @return Redhat + * @param string $mch_name */ - public function setMchName($mch_name): Redhat + public function setMchName(string $mch_name): void { $this->mch_name = $mch_name; - return $this; } /** * @return string */ - public function getQqappid() + public function getQqappid(): string { return $this->qqappid; } /** - * @param $qqappid - * @return Redhat + * @param string $qqappid */ - public function setQqappid($qqappid): Redhat + public function setQqappid(string $qqappid): void { $this->qqappid = $qqappid; - return $this; } /** * @return string */ - public function getReOpenid() + public function getReOpenid(): string { return $this->re_openid; } /** - * @param $re_openid - * @return Redhat + * @param string $re_openid */ - public function setReOpenid($re_openid): Redhat + public function setReOpenid(string $re_openid): void { $this->re_openid = $re_openid; - return $this; } /** * @return string */ - public function getTotalAmount() + public function getTotalAmount(): string { return $this->total_amount; } /** - * @param $total_amount - * @return Redhat + * @param string $total_amount */ - public function setTotalAmount($total_amount): Redhat + public function setTotalAmount(string $total_amount): void { $this->total_amount = $total_amount; - return $this; } /** * @return string */ - public function getTotalNum() + public function getTotalNum(): string { return $this->total_num; } /** - * @param $total_num - * @return Redhat + * @param string $total_num */ - public function setTotalNum($total_num): Redhat + public function setTotalNum(string $total_num): void { $this->total_num = $total_num; - return $this; } /** * @return string */ - public function getWishing() + public function getWishing(): string { return $this->wishing; } /** - * @param $wishing - * @return Redhat + * @param string $wishing */ - public function setWishing($wishing): Redhat + public function setWishing(string $wishing): void { $this->wishing = $wishing; - return $this; } /** * @return string */ - public function getActName() + public function getActName(): string { return $this->act_name; } /** - * @param $act_name - * @return Redhat + * @param string $act_name */ - public function setActName($act_name): Redhat + public function setActName(string $act_name): void { $this->act_name = $act_name; - return $this; } /** * @return string */ - public function getIconId() + public function getIconId(): string { return $this->icon_id; } /** - * @param $icon_id - * @return Redhat + * @param string $icon_id */ - public function setIconId($icon_id): Redhat + public function setIconId(string $icon_id): void { $this->icon_id = $icon_id; - return $this; } /** * @return string */ - public function getBannerId() + public function getBannerId(): string { return $this->banner_id; } /** - * @param $banner_id - * @return Redhat + * @param string $banner_id */ - public function setBannerId($banner_id): Redhat + public function setBannerId(string $banner_id): void { $this->banner_id = $banner_id; - return $this; } /** * @return string */ - public function getNotifyUrl() + public function getNotifyUrl(): string { return $this->notify_url; } /** - * @param $notify_url - * @return Redhat + * @param string $notify_url */ - public function setNotifyUrl($notify_url): Redhat + public function setNotifyUrl(string $notify_url): void { $this->notify_url = $notify_url; - return $this; } /** * @return string */ - public function getNotSendMsg() + public function getNotSendMsg(): string { return $this->not_send_msg; } /** - * @param $not_send_msg - * @return Redhat + * @param string $not_send_msg */ - public function setNotSendMsg($not_send_msg): Redhat + public function setNotSendMsg(string $not_send_msg): void { $this->not_send_msg = $not_send_msg; - return $this; } /** * @return string */ - public function getMinValue() + public function getMinValue(): string { return $this->min_value; } /** - * @param $min_value - * @return Redhat + * @param string $min_value */ - public function setMinValue($min_value): Redhat + public function setMinValue(string $min_value): void { $this->min_value = $min_value; - return $this; } /** * @return string */ - public function getMaxValue() + public function getMaxValue(): string { return $this->max_value; } /** - * @param $max_value - * @return Redhat + * @param string $max_value */ - public function setMaxValue($max_value): Redhat + public function setMaxValue(string $max_value): void { $this->max_value = $max_value; - return $this; + } + + /** + * @return string + */ + public function getKey(): string + { + return $this->key; + } + + /** + * @param string $key + */ + public function setKey(string $key): void + { + $this->key = $key; + } + + /** + * @return string + */ + public function getSignType(): string + { + return $this->signType; + } + + /** + * @param string $signType + */ + public function setSignType(string $signType): void + { + $this->signType = $signType; + } + + /** + * @return string + */ + public function getSendUrl(): string + { + return $this->sendUrl; + } + + /** + * @param string $sendUrl + */ + public function setSendUrl(string $sendUrl): void + { + $this->sendUrl = $sendUrl; + } + + /** + * @return string + */ + public function getSearchUrl(): string + { + return $this->searchUrl; + } + + /** + * @param string $searchUrl + */ + public function setSearchUrl(string $searchUrl): void + { + $this->searchUrl = $searchUrl; } @@ -403,8 +392,9 @@ class Redhat extends SmallProgram * @return mixed * 构建请求参数 */ - private function generate() + private function generate(): array { + $requestParam = []; $requestParam['charset'] = $this->getCharset(); $requestParam['nonce_str'] = $this->getNonceStr(); $requestParam['mch_billno'] = $this->getMchBillno(); @@ -431,48 +421,41 @@ class Redhat extends SmallProgram * @param $requestParam * @return string */ - private function builderSign($requestParam) + private function builderSign($requestParam): string { return Help::sign($requestParam, $this->getKey(), $this->getSignType()); } /** - * @return string - * @throws - * 发红包 + * @return Result */ - public function redEnvelopes() + public function redEnvelopes(): Result { - $callback = function ($response) { - $json = json_decode($response, true); - if (isset($json['return_code']) && $json['return_code'] != 'SUCCESS') { - $message = $json['return_msg'] ?? $json['retmsg']; - $param = ['code' => 500, 'message' => $message]; - } else if ($json['retcode'] != 0) { - $param = ['code' => $json['retcode'], 'message' => $json['retmsg']]; - } else { - $param = ['code' => 0, 'message' => $json['retmsg'], 'data' => ['listid' => $json['listid']]]; - } - return new Result($param); - }; - $this->request->setCallback($callback); - $response = $this->request->post($this->sendUrl, $this->generate()); - if (!$response->isResultsOK()) { - throw new \Exception($response->getMessage()); + $client = new Client('qpay.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->post($this->sendUrl, $this->generate()); + $client->close(); + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $json = json_decode($client->getBody(), true); + if (isset($json['return_code']) && $json['return_code'] != 'SUCCESS') { + return new Result(code: 500, message: $json['return_msg'] ?? $json['retmsg']); + } + if ($json['retcode'] != 0) { + return new Result(code: $json['retcode'], message: $json['retmsg']); + } else { + return new Result(code: 0, data: $json); } - return $response->getData('listid'); } /** * @param $listid - * @param null $orderNo - * @return RedHatResult - * @throws \Exception - * - * 查询红包状态 + * @param $orderNo + * @return Result */ - public function searchByOrderNo($listid, $orderNo = null) + public function searchByOrderNo($listid, $orderNo = null): Result { $requestParam['nonce_str'] = $this->getNonceStr(); $requestParam['mch_id'] = $this->getMchId(); @@ -481,20 +464,19 @@ class Redhat extends SmallProgram $requestParam['mch_billno'] = $orderNo; } $requestParam['sign'] = $this->builderSign($requestParam); - $this->request->setCallback(function ($response) { - $response = json_decode($response, true); - if (!isset($response['result']) || $response['result'] != 0) { - $param = ['code' => 500, 'message' => $response['res_info'] ?? '订单查询失败!', 'data' => $response]; - } else { - $param = ['code' => 0, 'message' => 'system success!', 'data' => $response]; - } - return new Result($param); - }); - $response = $this->request->get($this->searchUrl, $requestParam); - if (!$response->isResultsOK()) { - throw new \Exception($response->getMessage()); + $client = new Client('qpay.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->post($this->searchUrl, $requestParam); + $client->close(); + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $json = json_decode($client->getBody(), true); + if (isset($json['result']) && $json['result'] != 'SUCCESS') { + return new Result(code: 500, message: $response['res_info'] ?? '订单查询失败!'); + } else { + return new Result(code: 0, data: $json); } - return new RedHatResult($response->getData()); } } diff --git a/wchat/qq/SecCheck.php b/wchat/qq/SecCheck.php index 5c12dda..4bdb10b 100644 --- a/wchat/qq/SecCheck.php +++ b/wchat/qq/SecCheck.php @@ -4,6 +4,7 @@ namespace wchat\qq; +use Kiri\Client; use wchat\common\Result; /** @@ -13,57 +14,68 @@ use wchat\common\Result; class SecCheck extends SmallProgram { - private $_url = 'https://api.q.qq.com/api/json/security/ImgSecCheck?access_token='; + private string $_url = '/api/json/security/ImgSecCheck?access_token='; - private $_msgUrl = '/api/json/security/MsgSecCheck?access_token='; + private string $_msgUrl = '/api/json/security/MsgSecCheck?access_token='; /** - * @param $path - * @return array|Result|mixed + * @param string $path + * @return Result */ - public function image($path = '') + public function image(string $path = ''): Result { if (!file_exists($path)) { return $this->sendError('文件不存在', 404); } - $this->request->setUseSwoole(false); - $this->request->setHeader('Content-Type', 'multipart/form-data'); - $this->request->addHeader('Host', 'api.q.qq.com'); - $this->request->setErrorField('errCode'); - $this->request->setErrorMsgField('errMsg'); - $this->request->setAgent(''); $real_path = new \CURLFile($path); - return $this->request->upload($this->_url . $this->config->getAccessToken(), [ - 'appid' => $this->config->getAppid(), 'media' => new \CURLFile($path) - , 'form-data[filename]' => $path, 'form-data[content-type]' => $real_path->getMimeType() - ]); + $data = [ + 'appid' => $this->config->getAppid(), + 'media' => $real_path, + 'form-data[filename]' => $path, + 'form-data[content-type]' => $real_path->getMimeType() + ]; + $client = new Client('api.q.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'multipart/form-data']); + $client->upload($path, $data); + $client->close(); + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errCode']) && $body['errCode'] != 0) { + return new Result(code: $body['errCode'], message: $body['errMsg']); + } else { + return new Result(code: 0, data: $body); + } } /** - * @param $content - * @return array|Result|mixed + * @param string $content + * @return Result */ - public function text($content) + public function text(string $content): Result { if (empty($content)) { return $this->sendError('文件不存在', 404); } - $this->request->setUseSwoole(true); - $this->request->addHeader('Content-Type', 'application/json'); - $this->request->setErrorField('errCode'); - $this->request->setErrorMsgField('errMsg'); - $this->request->setData([ - 'appid' => $this->config->getAppid(), - 'content' => $content - ]); - $this->request->setHost('api.q.qq.com'); - $this->request->setIsSSL(true); + $url = '/' . ltrim($this->_url, '/') . $this->config->getAccessToken(); - $url = '/' . ltrim($this->_msgUrl, '/') . $this->config->getAccessToken(); - return $this->request->post($url); + $client = new Client('api.q.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->post($url, ['appid' => $this->config->getAppid(), 'content' => $content]); + $client->close(); + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errCode']) && $body['errCode'] != 0) { + return new Result(code: $body['errCode'], message: $body['errMsg']); + } else { + return new Result(code: 0, data: $body); + } } } diff --git a/wchat/qq/SmallProgram.php b/wchat/qq/SmallProgram.php index b83f307..e2aaf9c 100644 --- a/wchat/qq/SmallProgram.php +++ b/wchat/qq/SmallProgram.php @@ -4,37 +4,9 @@ namespace wchat\qq; -use wchat\common\Miniprogarampage; +use wchat\common\Multiprogramming; -class SmallProgram extends Miniprogarampage +class SmallProgram extends Multiprogramming { - protected static $instance; - - private $url = 'https://api.q.qq.com/api/getToken'; - - - /** - * @param $get_token - * @return mixed|null - */ - public function generateAccess_token($get_token = false) - { - if (!empty($this->config->getToken())) { - return $this->config->getToken(); - } - $query = [ - 'grant_type' => 'client_credential', - 'appid' => $this->config->getAppid(), - 'secret' => $this->config->getAppsecret() - ]; - $param = $this->request->get($this->url, $query); - if (!$param->isResultsOK()) { - return null; - } - if ($get_token) { - return $param->getData('access_token'); - } - return $param->getData(); - } } diff --git a/wchat/qq/Subject.php b/wchat/qq/Subject.php index b68552d..d527b25 100644 --- a/wchat/qq/Subject.php +++ b/wchat/qq/Subject.php @@ -13,14 +13,21 @@ use wchat\common\Result; class Subject extends \wchat\base\Subject { - private $sendUrl = 'https://api.q.qq.com/api/json/subscribe/SendSubscriptionMessage'; + /** + * @return string + */ + public function getUrl(): string + { + return '/api/json/subscribe/SendSubscriptionMessage'; + } + /** * @return string */ - public function getUrl() + public function getHost(): string { - return $this->sendUrl; + return 'api.q.qq.com'; } } diff --git a/wchat/qq/Template.php b/wchat/qq/Template.php deleted file mode 100644 index 30b38e8..0000000 --- a/wchat/qq/Template.php +++ /dev/null @@ -1,28 +0,0 @@ -sendUrl; - } - -} diff --git a/wchat/qq/Token.php b/wchat/qq/Token.php index 65d30f5..f007eac 100644 --- a/wchat/qq/Token.php +++ b/wchat/qq/Token.php @@ -4,12 +4,35 @@ namespace wchat\qq; +use Kiri\Client; +use wchat\common\Result; -use wchat\base\Access_Token; - -class Token extends SmallProgram implements Access_Token +class Token extends SmallProgram { - + /** + * @return Result + */ + public function token(): Result + { + $query = [ + 'grant_type' => 'client_credential', + 'appid' => $this->config->getAppid(), + 'secret' => $this->config->getAppsecret() + ]; + $client = new Client('api.q.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->get('/api/getToken', $query); + $client->close(); + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errcode']) && $body['errcode'] != 0) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } else { + return new Result(code: 0, data: $body); + } + } } diff --git a/wchat/qq/pay/Cash_Bonus.php b/wchat/qq/pay/Cash_Bonus.php index 5bf2205..e348eaa 100644 --- a/wchat/qq/pay/Cash_Bonus.php +++ b/wchat/qq/pay/Cash_Bonus.php @@ -5,6 +5,7 @@ namespace wchat\qq\pay; use Exception; +use Kiri\Client; use wchat\common\Help; use wchat\common\HttpClient; use wchat\common\Result; @@ -17,23 +18,23 @@ use wchat\wx\SmallProgram; class Cash_Bonus extends SmallProgram { - public $_cash = '/cgi-bin/hongbao/qpay_hb_mch_send.cgi'; + public string $_cash = '/cgi-bin/hongbao/qpay_hb_mch_send.cgi'; - private array $_errors = [ - '66228701' => '红包个数超出限制', - '66228705' => '总金额超出限制', - '66228706' => '总金额不足以按最小金额领取每个红包', - '66228707' => '商户签名校验失败', - '66228708' => '重入??', - '66228709' => 'openid转换uin失败', - '66228711' => '商户订单中的商户号有误', - '66228712' => '商户订单中的日期超过范围', - '66228713' => '余额不足', - '66228715' => '用户未关注公众号,发送AIO消息失败', - '66229716' => '用户禁用公众号,发AIO消息失败' - ]; + private array $_errors = [ + '66228701' => '红包个数超出限制', + '66228705' => '总金额超出限制', + '66228706' => '总金额不足以按最小金额领取每个红包', + '66228707' => '商户签名校验失败', + '66228708' => '重入??', + '66228709' => 'openid转换uin失败', + '66228711' => '商户订单中的商户号有误', + '66228712' => '商户订单中的日期超过范围', + '66228713' => '余额不足', + '66228715' => '用户未关注公众号,发送AIO消息失败', + '66229716' => '用户禁用公众号,发AIO消息失败' + ]; - private array $_requestParams = []; + private array $_requestParams = []; /** * @param $value @@ -83,39 +84,30 @@ class Cash_Bonus extends SmallProgram * @return mixed * @throws Exception */ - public function mch_send($mch_billno, $openId, $price) + public function mch_send($mch_billno, $openId, $price): Result { - $client = HttpClient::NewRequest(); - $client->setIsSSL(true); - $client->setSslCertFile($this->getConfig()->getSslCert()); - $client->setSslKeyFile($this->getConfig()->getSslKey()); - $client->setCa($this->getConfig()->getSslCa()); - $client->setUseSwoole($this->getConfig()->isUsrSwoole()); - $client->setHost('api.qpay.qq.com'); - $client->setCallback(function ($response, $requestParam) { - $json = json_decode($response, true); - if (isset($json['return_code']) && $json['return_code'] != 'SUCCESS') { - $array['code'] = 500; - $array['message'] = $json['return_msg'] ?? $json['retmsg']; - } else if ($json['retcode'] != 0) { - if (empty($json['retmsg']) && isset($this->_errors[$json['retcode']])) { - $json['retmsg'] = $this->_errors[$json['retcode']]; - } - $array['code'] = $json['retcode']; - $array['message'] = $json['retmsg']; - } else { - $array['code'] = 0; - $array['message'] = $json['retmsg']; - $array['data'] = ['listid' => $json['listid']]; - } - $array['data']['request'] = $requestParam; - return new Result($array); - }); - $response = $client->post($this->_cash, $this->orderConfig($mch_billno, $openId, $price)); - if (!$response->isResultsOK()) { - throw new Exception($response->getMessage()); + $client = new Client('api.qpay.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->withSslCertFile($this->getConfig()->getSslCert()); + $client->withSslKeyFile($this->getConfig()->getSslKey()); + $client->withCa($this->getConfig()->getSslCa()); + $client->post($this->_cash, $this->orderConfig($mch_billno, $openId, $price)); + $client->close(); + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $json = json_decode($client->getBody(), true); + + if (isset($json['return_code']) && $json['return_code'] != 'SUCCESS') { + return new Result(code: 500, message: $json['return_msg'] ?? $json['retmsg']); + } else if ($json['retcode'] != 0) { + if (empty($json['retmsg']) && isset($this->_errors[$json['retcode']])) { + $json['retmsg'] = $this->_errors[$json['retcode']]; + } + return new Result(code: $json['retcode'], message: $json['retmsg']); + } else { + return new Result(code: 0, data: $json); } - return $response->getData('listid'); } /** @@ -124,7 +116,7 @@ class Cash_Bonus extends SmallProgram * @param $price * @return array */ - private function orderConfig($mch_billno, $openId, $price) + private function orderConfig($mch_billno, $openId, $price): array { $requestParam['charset'] = 1; $requestParam['nonce_str'] = Help::random(32); @@ -138,7 +130,7 @@ class Cash_Bonus extends SmallProgram $requestParam['total_num'] = 1; $requestParam['notify_url'] = $this->getConfig()->getNotifyUrl(); - if (!empty($this->_requestParams) && is_array($this->_requestParams)) { + if (!empty($this->_requestParams)) { $requestParam = array_merge($requestParam, $this->_requestParams); } @@ -152,7 +144,7 @@ class Cash_Bonus extends SmallProgram * @return string * @throws Exception */ - public function mchOrderNo() + public function mchOrderNo(): string { return implode([ $this->getConfig()->getMchId(), @@ -168,7 +160,7 @@ class Cash_Bonus extends SmallProgram * @param array $requestParams * @return bool */ - public function validator(array $requestParams) + public function validator(array $requestParams): bool { $notifySign = $requestParams['sign']; unset($requestParams['sign']); diff --git a/wchat/qq/pay/Enterprise_payment.php b/wchat/qq/pay/Enterprise_payment.php index 33ef25c..9bcffa3 100644 --- a/wchat/qq/pay/Enterprise_payment.php +++ b/wchat/qq/pay/Enterprise_payment.php @@ -5,6 +5,7 @@ namespace wchat\qq\pay; use Exception; +use Kiri\Client; use wchat\common\Help; use wchat\common\HttpClient; use wchat\common\Result; @@ -16,7 +17,7 @@ use wchat\qq\SmallProgram; */ class Enterprise_payment extends SmallProgram { - public $_cash = '/cgi-bin/epay/qpay_epay_b2c.cgi'; + public string $_cash = '/cgi-bin/epay/qpay_epay_b2c.cgi'; private $_errors = [ 'SYSTEMERROR' => '系统错误', @@ -71,34 +72,24 @@ class Enterprise_payment extends SmallProgram */ public function mch_send($mch_billno, $openId, $price) { - $client = HttpClient::NewRequest(); - $client->setIsSSL(true); - $client->setSslCertFile($this->getConfig()->getSslCert()); - $client->setSslKeyFile($this->getConfig()->getSslKey()); - $client->setCa($this->getConfig()->getSslCa()); - $client->setUseSwoole($this->getConfig()->isUsrSwoole()); - $client->setHost('api.qpay.qq.com'); - $client->setCallback(function ($response, $requestParam) { - $json = json_decode($response, true); - if (isset($json['return_code']) && $json['return_code'] != 'SUCCESS') { - $array['code'] = 500; - $array['message'] = $json['return_msg'] ?? $json['retmsg']; - } else if ($json['result_code'] != 'SUCCESS') { - $array['code'] = 500; - $array['message'] = $this->_errors[$json['err_code']] ?? $json['err_code_desc']; - } else { - $array['code'] = 0; - $array['message'] = 'system success'; - $array['data'] = $json; - } - $array['data']['request'] = $requestParam; - return new Result($array); - }); - $response = $client->post($this->_cash, $this->orderConfig($mch_billno, $openId, $price)); - if (!$response->isResultsOK()) { - throw new Exception($response->getMessage()); + $client = new Client('api.qpay.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->withSslCertFile($this->getConfig()->getSslCert()); + $client->withSslKeyFile($this->getConfig()->getSslKey()); + $client->withCa($this->getConfig()->getSslCa()); + $client->post($this->_cash, $this->orderConfig($mch_billno, $openId, $price)); + $client->close(); + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $json = json_decode($client->getBody(), true); + if (isset($json['return_code']) && $json['return_code'] != 'SUCCESS') { + return new Result(code: 500, data: $json['return_msg'] ?? $json['retmsg']); + } else if ($json['result_code'] != 'SUCCESS') { + return new Result(code: 500, data: $this->_errors[$json['err_code']] ?? $json['err_code_desc']); + } else { + return new Result(code: 0, data: $json); } - return $response->getData(); } /** @@ -107,7 +98,7 @@ class Enterprise_payment extends SmallProgram * @param $price * @return array */ - private function orderConfig($mch_billno, $openId, $price) + private function orderConfig($mch_billno, $openId, $price): array { $requestParam['input_charset'] = 'UTF-8'; $requestParam['nonce_str'] = Help::random(32); @@ -135,7 +126,7 @@ class Enterprise_payment extends SmallProgram * @return string * @throws Exception */ - public function mchOrderNo() + public function mchOrderNo(): string { return implode([ $this->getConfig()->getMchId(), @@ -151,7 +142,7 @@ class Enterprise_payment extends SmallProgram * @param array $requestParams * @return bool */ - public function validator(array $requestParams) + public function validator(array $requestParams): bool { $notifySign = $requestParams['sign']; unset($requestParams['sign']); diff --git a/wchat/qq/result/RedHatResult.php b/wchat/qq/result/RedHatResult.php index 2ccffa3..3d9db2c 100644 --- a/wchat/qq/result/RedHatResult.php +++ b/wchat/qq/result/RedHatResult.php @@ -10,17 +10,17 @@ namespace wchat\qq\result; class RedHatResult { - public $result; - public $res_info; + public mixed $result; + public mixed $res_info; - public $listid; - public $state; - public $total_num; - public $recv_num; - public $total_amount; - public $recv_amount; - public $recv_details; - public $uin; + public mixed $listid; + public mixed $state; + public mixed $total_num; + public mixed $recv_num; + public mixed $total_amount; + public mixed $recv_amount; + public mixed $recv_details; + public mixed $uin; const RED_HAT_STATUS_PAID = 1; @@ -40,9 +40,9 @@ class RedHatResult /** * @param $array - * @return $this + * @return void */ - private function init($array) + private function init($array): void { foreach ($array as $key => $value) { if (!property_exists($this, $key)) { @@ -50,7 +50,6 @@ class RedHatResult } $this->{$key} = $value; } - return $this; } @@ -58,7 +57,7 @@ class RedHatResult * @param $field * @return mixed */ - public function get($field) + public function get($field): mixed { return $this->$field; } @@ -68,7 +67,7 @@ class RedHatResult * @return bool * 是否已完成支付 */ - public function isPaid() + public function isPaid(): bool { return $this->state == self::RED_HAT_STATUS_PAID; } @@ -77,7 +76,7 @@ class RedHatResult * @return bool * 是否已抢完 */ - public function isSnatched() + public function isSnatched(): bool { return $this->state == self::RED_HAT_STATUS_SNATCHED; } @@ -86,17 +85,16 @@ class RedHatResult /** * @return bool */ - public function isExpired() + public function isExpired(): bool { return $this->state == self::RED_HAT_STATUS_EXPIRED; } - /** * @return bool */ - public function isRefunded() + public function isRefunded(): bool { return $this->state == self::RED_HAT_STATUS_REFUNDED; } diff --git a/wchat/wx/Account.php b/wchat/wx/Account.php index 1632161..12b6f5f 100644 --- a/wchat/wx/Account.php +++ b/wchat/wx/Account.php @@ -8,6 +8,8 @@ namespace wchat\wx; +use Exception; +use Kiri\Client; use wchat\common\Decode; use wchat\common\HttpClient; use wchat\common\Result; @@ -15,48 +17,39 @@ use wchat\common\Result; class Account extends SmallProgram { - private $wxaqr = 'https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token='; - private $getwxacode = 'https://api.weixin.qq.com/wxa/getwxacode?access_token='; - private $getwxacodeunlimit = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token='; - - private $savePath = __DIR__ . '/../../Users/'; - - - /** - * @param $path - */ - public function setSavePath($path) - { - $this->savePath = $path; - } - /** * @param $code * @return Result */ - public function login($code) + public function login($code): Result { $param['appid'] = $this->config->getAppid(); $param['secret'] = $this->config->getAppsecret(); $param['js_code'] = $code; $param['grant_type'] = 'authorization_code'; - $this->request->setMethod(HttpClient::GET); - $this->request->addHeader('Content-Type', 'application/json'); - $this->request->setHost('api.weixin.qq.com'); - $this->request->addHeader('Host', 'api.weixin.qq.com'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); + $client = new Client('api.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->get('sns/jscode2session', $param); + $client->close(); - return $this->request->get('sns/jscode2session', $param); + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errcode']) && $body['errcode'] != 0) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } else { + return new Result(code: 0, data: $body); + } } /** * @param $openid - * @return array|mixed|Result - * @throws \Exception + * @return Result + * @throws Exception */ - public function getPublicUserInfo($openid) + public function getPublicUserInfo($openid): Result { $query = [ 'access_token' => $this->getAccessToken(), @@ -64,16 +57,19 @@ class Account extends SmallProgram 'lang' => 'zh_CN' ]; - $client = HttpClient::NewRequest(); - $client->setAgent($this->config->getAgent()); - $client->setUseSwoole($this->config->isUsrSwoole()); - $client->setMethod(HttpClient::GET); - $client->setIsSSL(true); - $client->setHost('api.weixin.qq.com'); - $client->addHeader('Host', 'api.weixin.qq.com'); - $client->setErrorField('errcode'); - $client->setErrorMsgField('errmsg'); - return $client->get('cgi-bin/user/info', $query); + $client = new Client('api.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->get('cgi-bin/user/info', $query); + $client->close(); + + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errcode']) && $body['errcode'] != 0) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } + return new Result(code: 0, data: $body); } @@ -81,7 +77,7 @@ class Account extends SmallProgram * @param $encryptedData * @param $iv * @param $sessionKey - * @param $asArray + * @param bool $asArray * @return object|array * @throws * @@ -91,7 +87,7 @@ class Account extends SmallProgram *
  • -41005: base64加密失败
  • *
  • -41016: base64解密失败
  • */ - public function decode($encryptedData, $iv, $sessionKey, $asArray = false) + public function decode($encryptedData, $iv, $sessionKey, bool $asArray = false): object|array { $decode = new Decode(); $decode->setSessionKey($sessionKey); @@ -107,21 +103,26 @@ class Account extends SmallProgram * @param $path * @param $width * @return array|mixed|Result - * @throws \Exception + * @throws Exception */ - public function createwxaqrcode($path, $width) + public function createwxaqrcode($path, $width): mixed { - $url = $this->wxaqr . $this->getAccessToken(); - + $url = 'cgi-bin/wxaapp/createwxaqrcode?access_token='; $sendBody['path'] = $path; $sendBody['width'] = $width; - - $this->request->setMethod(HttpClient::POST); - $this->request->setCallback([$this, 'saveByPath']); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - - return $this->request->post($url, $sendBody); + $client = new Client('api.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->post($url . $this->getConfig()->getAccessToken(), $sendBody); + $client->close(); + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (!is_null($body)) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } else { + return new Result(code: 0, data: $client->getBody()); + } } @@ -130,11 +131,10 @@ class Account extends SmallProgram * @param $width * @param bool $is_hyaline * @param bool $auto_color - * @param $line_color - * @return array|mixed|Result - * @throws \Exception + * @param string $line_color + * @return Result */ - public function getwxacode($path, $width, $is_hyaline = false, $auto_color = false, $line_color = '') + public function getwxacode($path, $width, bool $is_hyaline = false, bool $auto_color = false, string $line_color = ''): Result { $sendBody['path'] = $path; $sendBody['width'] = $width; @@ -144,13 +144,21 @@ class Account extends SmallProgram $sendBody['line_color'] = $line_color; } - $url = $this->getwxacode . $this->getAccessToken(); + $url = 'wxa/getwxacode?access_token=' . $this->getConfig()->getAccessToken(); - $this->request->setMethod(HttpClient::POST); - $this->request->setCallback([$this, 'saveByPath']); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - return $this->request->post($url, $sendBody); + $client = new Client('api.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->post($url . $this->getConfig()->getAccessToken(), $sendBody); + $client->close(); + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (!is_null($body)) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } else { + return new Result(code: 0, data: $client->getBody()); + } } @@ -159,11 +167,10 @@ class Account extends SmallProgram * @param $width * @param bool $is_hyaline * @param bool $auto_color - * @param $line_color - * @return array|mixed|Result - * @throws \Exception + * @param string $line_color + * @return Result */ - public function getwxacodeunlimit($path, $width, $is_hyaline = false, $auto_color = false, $line_color = '') + public function getwxacodeunlimit($path, $width, bool $is_hyaline = false, bool $auto_color = false, string $line_color = ''): Result { $sendBody['path'] = $path; $sendBody['width'] = $width; @@ -173,28 +180,21 @@ class Account extends SmallProgram $sendBody['line_color'] = $line_color; } - $url = $this->getwxacodeunlimit . $this->getAccessToken(); + $url = 'wxa/getwxacodeunlimit?access_token=' . $this->getConfig()->getAccessToken(); - $this->request->setMethod(HttpClient::POST); - $this->request->setCallback([$this, 'saveByPath']); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - return $this->request->post($url, $sendBody); - } - - /** - * @param mixed $body - * @return string - * @throws \Exception - */ - public function saveByPath($body) - { - if (!is_null($json = json_decode($body))) { - throw new \Exception($json['errmsg'], $json['errcode']); + $client = new Client('api.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->post($url . $this->getConfig()->getAccessToken(), $sendBody); + $client->close(); + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (!is_null($body)) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } else { + return new Result(code: 0, data: $client->getBody()); } - - $push = md5_file($body) . '.png'; - file_put_contents($this->savePath . $push, $this->savePath); - return $this->savePath . $push; } + } diff --git a/wchat/wx/ContentAsyncCheck.php b/wchat/wx/ContentAsyncCheck.php index ad313ee..0185050 100644 --- a/wchat/wx/ContentAsyncCheck.php +++ b/wchat/wx/ContentAsyncCheck.php @@ -10,21 +10,21 @@ namespace wchat\wx; */ class ContentAsyncCheck { - private $_ToUserName = ''; - private $_FromUserName = ''; - private $_CreateTime = ''; - private $_MsgType = ''; - private $_Event = ''; - private $_isrisky = ''; - private $_extra_info_json = ''; - private $_appid = ''; - private $_trace_id = ''; - private $_status_code = ''; + private mixed $_ToUserName = ''; + private mixed $_FromUserName = ''; + private mixed $_CreateTime = ''; + private mixed $_MsgType = ''; + private mixed $_Event = ''; + private mixed $_isrisky = ''; + private mixed $_extra_info_json = ''; + private mixed $_appid = ''; + private mixed $_trace_id = ''; + private mixed $_status_code = ''; /** * @return string */ - public function getToUserName() + public function getToUserName(): mixed { return $this->_ToUserName; } @@ -32,7 +32,7 @@ class ContentAsyncCheck /** * @return string */ - public function getFromUserName() + public function getFromUserName(): mixed { return $this->_FromUserName; } @@ -40,7 +40,7 @@ class ContentAsyncCheck /** * @return string */ - public function getCreateTime() + public function getCreateTime(): mixed { return $this->_CreateTime; } @@ -48,7 +48,7 @@ class ContentAsyncCheck /** * @return string */ - public function getMsgType() + public function getMsgType(): mixed { return $this->_MsgType; } @@ -56,7 +56,7 @@ class ContentAsyncCheck /** * @return string */ - public function getEvent() + public function getEvent(): mixed { return $this->_Event; } @@ -64,7 +64,7 @@ class ContentAsyncCheck /** * @return string */ - public function getIsrisky() + public function getIsrisky(): mixed { return $this->_isrisky; } @@ -72,7 +72,7 @@ class ContentAsyncCheck /** * @return string */ - public function getExtraInfoJson() + public function getExtraInfoJson(): mixed { return $this->_extra_info_json; } @@ -80,7 +80,7 @@ class ContentAsyncCheck /** * @return string */ - public function getAppid() + public function getAppid(): mixed { return $this->_appid; } @@ -88,7 +88,7 @@ class ContentAsyncCheck /** * @return string */ - public function getTraceId() + public function getTraceId(): mixed { return $this->_trace_id; } @@ -96,16 +96,16 @@ class ContentAsyncCheck /** * @return string */ - public function getStatusCode() + public function getStatusCode(): mixed { return $this->_status_code; } /** * @param array $params - * @return ContentAsyncCheck|null + * @return ContentAsyncCheck */ - public static function instance(array $params) + public static function instance(array $params): static { static $class = null; if ($class === null) { @@ -118,7 +118,7 @@ class ContentAsyncCheck * @param $params * @return $this */ - private function init($params) + private function init($params): static { foreach ($params as $item => $param) { $this->{'_' . $item} = $param; @@ -129,7 +129,7 @@ class ContentAsyncCheck /** * @return bool */ - public function isRisky() + public function isRisky(): bool { return intval($this->_isrisky) === 0; } @@ -137,7 +137,7 @@ class ContentAsyncCheck /** * @return bool */ - public function isSuccess() + public function isSuccess(): bool { return $this->_status_code === 0; } diff --git a/wchat/wx/Message.php b/wchat/wx/Message.php index bb357f0..a65e617 100644 --- a/wchat/wx/Message.php +++ b/wchat/wx/Message.php @@ -4,7 +4,7 @@ namespace wchat\wx; use Exception; -use wchat\common\HttpClient; +use Kiri\Client; use wchat\common\Result; @@ -15,287 +15,301 @@ use wchat\common\Result; class Message extends SmallProgram { - private array $msgData = []; + private array $msgData = []; - /** - * @param $openid - */ - public function setOpenid($openid) - { - $this->msgData['touser'] = $openid; - } + /** + * @param $openid + */ + public function setOpenid($openid) + { + $this->msgData['touser'] = $openid; + } - /** - * @param $content - * @return Result - * @throws Exception - */ - public function sendTextNews($content) - { - $this->msgData['msgtype'] = 'text'; - $this->msgData['text'] = ['content' => $content]; + /** + * @param $content + * @return Result + * @throws Exception + */ + public function sendTextNews($content): Result + { + $this->msgData['msgtype'] = 'text'; + $this->msgData['text'] = ['content' => $content]; - return $this->sendKefuMsg(); - } + return $this->sendKefuMsg(); + } - /** - * @param $media_id - * @return Result - * @throws Exception - */ - public function sendImageNews($media_id) - { - $this->msgData['msgtype'] = 'image'; - $this->msgData['image'] = ['media_id' => $media_id]; + /** + * @param $media_id + * @return Result + * @throws Exception + */ + public function sendImageNews($media_id): Result + { + $this->msgData['msgtype'] = 'image'; + $this->msgData['image'] = ['media_id' => $media_id]; - return $this->sendKefuMsg(); - } + return $this->sendKefuMsg(); + } - /** - * @param $media_id - * @return Result - * @throws Exception - */ - public function sendVoiceNews($media_id) - { - $this->msgData['msgtype'] = 'voice'; - $this->msgData['voice'] = ['media_id' => $media_id]; + /** + * @param $media_id + * @return Result + * @throws Exception + */ + public function sendVoiceNews($media_id): Result + { + $this->msgData['msgtype'] = 'voice'; + $this->msgData['voice'] = ['media_id' => $media_id]; - return $this->sendKefuMsg(); - } + return $this->sendKefuMsg(); + } - /** - * @param $media_id - * @return Result - * @throws Exception - */ - public function sendMpNewsNews($media_id) - { - $this->msgData['msgtype'] = 'mpnews'; - $this->msgData['mpnews'] = ['media_id' => $media_id]; + /** + * @param $media_id + * @return Result + * @throws Exception + */ + public function sendMpNewsNews($media_id): Result + { + $this->msgData['msgtype'] = 'mpnews'; + $this->msgData['mpnews'] = ['media_id' => $media_id]; - return $this->sendKefuMsg(); - } + return $this->sendKefuMsg(); + } - /** - * @param $title - * @param $description - * @param $url - * @param $picurl - * @return Result - * @throws Exception - */ - public function sendNewsNews($title, $description, $url, $picurl) - { - $this->msgData['msgtype'] = 'news'; - $this->msgData['news'] = ['articles' => [[ - 'title' => $title, - 'description' => $description, - 'url' => $url, - 'picurl' => $picurl - ]]]; - return $this->sendKefuMsg(); - } + /** + * @param $title + * @param $description + * @param $url + * @param $picurl + * @return Result + * @throws Exception + */ + public function sendNewsNews($title, $description, $url, $picurl): Result + { + $this->msgData['msgtype'] = 'news'; + $this->msgData['news'] = [ + 'articles' => [ + [ + 'title' => $title, + 'description' => $description, + 'url' => $url, + 'picurl' => $picurl + ] + ] + ]; + return $this->sendKefuMsg(); + } - /** - * @param $title - * @return Result - * @throws Exception - */ - public function sendCardNews($title) - { - $this->msgData['msgtype'] = 'wxcard'; - $this->msgData['wxcard'] = ['card_id' => $title]; + /** + * @param $title + * @return Result + * @throws Exception + */ + public function sendCardNews($title): Result + { + $this->msgData['msgtype'] = 'wxcard'; + $this->msgData['wxcard'] = ['card_id' => $title]; - return $this->sendKefuMsg(); - } + return $this->sendKefuMsg(); + } - /** - * @param $media_id - * @param $thumb_media_id - * @param $title - * @param $description - * @return Result - * @throws Exception - */ - public function sendVideoNews($media_id, $thumb_media_id, $title, $description) - { - $this->msgData['msgtype'] = 'video'; - $this->msgData['video'] = ['media_id' => [ - 'media_id' => $media_id, - 'thumb_media_id' => $thumb_media_id, - 'title' => $title, - 'description' => $description - ]]; - return $this->sendKefuMsg(); - } + /** + * @param $media_id + * @param $thumb_media_id + * @param $title + * @param $description + * @return Result + * @throws Exception + */ + public function sendVideoNews($media_id, $thumb_media_id, $title, $description): Result + { + $this->msgData['msgtype'] = 'video'; + $this->msgData['video'] = [ + 'media_id' => [ + 'media_id' => $media_id, + 'thumb_media_id' => $thumb_media_id, + 'title' => $title, + 'description' => $description + ] + ]; + return $this->sendKefuMsg(); + } - /** - * @param $musicurl - * @param $hqmusicurl - * @param $thumb_media_id - * @param $title - * @param $description - * @return Result - * @throws Exception - */ - public function sendMusicNews($musicurl, $hqmusicurl, $thumb_media_id, $title, $description) - { - $this->msgData['msgtype'] = 'music'; - $this->msgData['music'] = [ - 'title' => $title, - 'description' => $description, - 'musicurl' => $musicurl, - 'hqmusicurl' => $hqmusicurl, - 'thumb_media_id' => $thumb_media_id - ]; - return $this->sendKefuMsg(); - } + /** + * @param $musicurl + * @param $hqmusicurl + * @param $thumb_media_id + * @param $title + * @param $description + * @return Result + * @throws Exception + */ + public function sendMusicNews($musicurl, $hqmusicurl, $thumb_media_id, $title, $description): Result + { + $this->msgData['msgtype'] = 'music'; + $this->msgData['music'] = [ + 'title' => $title, + 'description' => $description, + 'musicurl' => $musicurl, + 'hqmusicurl' => $hqmusicurl, + 'thumb_media_id' => $thumb_media_id + ]; + return $this->sendKefuMsg(); + } - /** - * @param $head_content - * @param $tail_content - * @param array $menus - * @return Result - * @throws Exception - */ - public function sendMenuNews($head_content, $tail_content, array $menus = []) - { - $this->msgData['msgtype'] = 'msgmenu'; - $this->msgData['msgmenu'] = [ - 'head_content' => $head_content, - 'tail_content' => $tail_content, - ]; - if (empty($menus) || !is_array($menus) || count($menus) < 2) { - throw new Exception('菜单选项必须有2个'); - } - foreach ($menus as $key => $val) { - $this->addNewsMenu($val['id'], $val['name']); - } - return $this->sendKefuMsg(); - } + /** + * @param $head_content + * @param $tail_content + * @param array $menus + * @return Result + * @throws Exception + */ + public function sendMenuNews($head_content, $tail_content, array $menus = []): Result + { + $this->msgData['msgtype'] = 'msgmenu'; + $this->msgData['msgmenu'] = [ + 'head_content' => $head_content, + 'tail_content' => $tail_content, + ]; + if (empty($menus) || !is_array($menus) || count($menus) < 2) { + throw new Exception('菜单选项必须有2个'); + } + foreach ($menus as $val) { + $this->addNewsMenu($val['id'], $val['name']); + } + return $this->sendKefuMsg(); + } - private int $index = 0; + private int $index = 0; - /** - * @param $id - * @param $menuName - * @return $this - */ - public function addNewsMenu($id, $menuName) - { - $lists['id'] = $id; - $lists['content'] = $menuName; - $this->msgData['msgmenu']['list'][$this->index] = $lists; - ++$this->index; - return $this; - } + /** + * @param $id + * @param $menuName + * @return $this + */ + public function addNewsMenu($id, $menuName): static + { + $lists['id'] = $id; + $lists['content'] = $menuName; + $this->msgData['msgmenu']['list'][$this->index] = $lists; + ++$this->index; + return $this; + } - /** - * @param $title - * @param $appid - * @param $pagepath - * @param $thumb_media_id - * @return Result - * @throws Exception - */ - public function sendMiniprogrampageNews($title, $appid, $pagepath, $thumb_media_id) - { - $this->msgData['msgtype'] = 'msgmenu'; - $this->msgData['miniprogrampage'] = [ - 'title' => $title, - 'appid' => $appid, - 'pagepath' => $pagepath, - 'thumb_media_id' => $thumb_media_id, - ]; - return $this->sendKefuMsg(); - } + /** + * @param $title + * @param $appid + * @param $pagepath + * @param $thumb_media_id + * @return Result + * @throws Exception + */ + public function sendMiniprogrampageNews($title, $appid, $pagepath, $thumb_media_id): Result + { + $this->msgData['msgtype'] = 'msgmenu'; + $this->msgData['miniprogrampage'] = [ + 'title' => $title, + 'appid' => $appid, + 'pagepath' => $pagepath, + 'thumb_media_id' => $thumb_media_id, + ]; + return $this->sendKefuMsg(); + } - /** - * @param $filePath - * @param $type - * @param bool $isPermanent - * @param $title - * @param $introduction - * @return mixed - * @throws Exception - */ - public function upload($filePath, $type, $isPermanent = false, $title = '', $introduction = '') - { - if (!file_exists($filePath)) { - throw new Exception('文件不存在'); - } + /** + * @param $filePath + * @param $type + * @param bool $isPermanent + * @param string $title + * @param string $introduction + * @return mixed + * @throws Exception + */ + public function upload($filePath, $type, bool $isPermanent = false, string $title = '', string $introduction = ''): Result + { + if (!file_exists($filePath)) { + throw new Exception('文件不存在'); + } - if (!in_array($type, ['image', 'voice', 'video', 'thumb'])) { - throw new Exception('暂不支持的文件类型'); - } + if (!in_array($type, ['image', 'voice', 'video', 'thumb'])) { + throw new Exception('暂不支持的文件类型'); + } - $token = $this->getAccessToken(); - if ($isPermanent) { - $url = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={$token}&type={$type}"; - } else { - $url = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token={$token}&type={$type}"; - } + $token = $this->config->getAccessToken(); + if ($isPermanent) { + $url = "/cgi-bin/material/add_material?access_token={$token}&type={$type}"; + } else { + $url = "/cgi-bin/media/upload?access_token={$token}&type={$type}"; + } - $mime = mime_content_type($filePath); + $mime = mime_content_type($filePath); - $real_path = new \CURLFile(realpath($filePath)); + $real_path = new \CURLFile(realpath($filePath)); - $data = array("media" => $real_path, 'form-data[filename]' => $filePath, 'form-data[Content-Type]' => $mime); - if ($isPermanent && $mime == 'video/mp3') { - $data = ['media' => $real_path, 'description[title]' => $title, 'description[introduction]' => $introduction]; - } + $data = ["media" => $real_path, 'form-data[filename]' => $filePath, 'form-data[Content-Type]' => $mime]; + if ($isPermanent && $mime == 'video/mp3') { + $data = ['media' => $real_path, 'description[title]' => $title, 'description[introduction]' => $introduction]; + } - $this->request->setMethod(HttpClient::POST); + $client = new Client('api.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'multipart/form-data']); + $client->post($url, $data); + $client->close(); - /** @var Result $body */ - $data = $this->request->post($url, $data); - if (!$data->isResultsOK()) { - throw new Exception($data->getMessage()); - } + $this->msgData = []; - return $data->getData(); - } + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errcode']) && $body['errcode'] != 0) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } else { + return new Result(code: 0, data: $body); + } + } - /** - * @return array - */ - public function getContents() - { - return $this->msgData; - } + /** + * @return array + */ + public function getContents(): array + { + return $this->msgData; + } - /** - * @return Result - * @throws Exception - */ - private function sendKefuMsg() - { - $data = json_encode($this->msgData, JSON_UNESCAPED_UNICODE); + /** + * @return Result + * @throws Exception + */ + private function sendKefuMsg() + { + $url = '/cgi-bin/message/custom/send?access_token=' . $this->config->getAccessToken(); - $url = '/cgi-bin/message/custom/send?access_token=' . $this->getAccessToken(); - $this->request->setMethod(HttpClient::POST); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $this->request->setHost('api.weixin.qq.com'); + $client = new Client('api.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->post($url, $this->msgData); + $client->close(); - $this->request->addHeader('Content-Type', 'application/json'); + $this->msgData = []; - /** @var Result $body */ - $body = $this->request->post($url, $data); - - if (!$body->isResultsOK()) { - throw new Exception($body->getMessage()); - } - return $body; - } + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errcode']) && $body['errcode'] != 0) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } else { + return new Result(code: 0, data: $body); + } + } } diff --git a/wchat/wx/Notify.php b/wchat/wx/Notify.php index c422925..3606d66 100644 --- a/wchat/wx/Notify.php +++ b/wchat/wx/Notify.php @@ -3,43 +3,44 @@ namespace wchat\wx; +use wchat\common\Help; class Notify extends SmallProgram { - public $appid = ''; - public $mch_id = ''; - public $device_info = ''; - public $nonce_str = ''; - public $sign = ''; - public $sign_type = ''; - public $result_code = ''; - public $err_code = ''; - public $err_code_des = ''; - public $openid = ''; - public $is_subscribe = ''; - public $trade_type = ''; - public $bank_type = ''; - public $total_fee = ''; - public $settlement_total_fee = ''; - public $fee_type = ''; - public $cash_fee = ''; - public $cash_fee_type = ''; - public $coupon_fee = ''; - public $coupon_count = ''; - public $coupon_type_n = ''; - public $coupon_id_n = ''; - public $coupon_fee_n = ''; - public $transaction_id = ''; - public $out_trade_no = ''; - public $attach = ''; - public $time_end = ''; - public $return_code = ''; + public mixed $appid = ''; + public mixed $mch_id = ''; + public mixed $device_info = ''; + public mixed $nonce_str = ''; + public mixed $sign = ''; + public mixed $sign_type = ''; + public mixed $result_code = ''; + public mixed $err_code = ''; + public mixed $err_code_des = ''; + public mixed $openid = ''; + public mixed $is_subscribe = ''; + public mixed $trade_type = ''; + public mixed $bank_type = ''; + public mixed $total_fee = ''; + public mixed $settlement_total_fee = ''; + public mixed $fee_type = ''; + public mixed $cash_fee = ''; + public mixed $cash_fee_type = ''; + public mixed $coupon_fee = ''; + public mixed $coupon_count = ''; + public mixed $coupon_type_n = ''; + public mixed $coupon_id_n = ''; + public mixed $coupon_fee_n = ''; + public mixed $transaction_id = ''; + public mixed $out_trade_no = ''; + public mixed $attach = ''; + public mixed $time_end = ''; + public mixed $return_code = ''; /** * @return bool * 判断是否完成支付 */ - public function isSuccess() + public function isSuccess(): bool { if ($this->getReturnCode() != "SUCCESS") { return false; @@ -56,7 +57,7 @@ class Notify extends SmallProgram * @param array $params * @return $this */ - public function setPayNotifyData(array $params) + public function setPayNotifyData(array $params): static { if (!$this->validation($params)) { $this->setResultCode('FAIL'); @@ -64,20 +65,30 @@ class Notify extends SmallProgram unset($params['result_code'], $params['err_code_des']); } foreach ($params as $key => $val) { - if (!property_exists($this, $key)) { - continue; - } - $this->$key = $val; + $this->__set($key, $val); } return $this; } + /** + * @param string $name + * @param $value + * @return void + */ + public function __set(string $name, $value): void + { + if (property_exists($this, $name)) { + $this->$name = $value; + } + } + + /** * @param array $params * @return bool */ - public function validation(array $params) + public function validation(array $params): bool { $sign = $params['sign']; unset($params['sign']); @@ -92,507 +103,451 @@ class Notify extends SmallProgram } /** - * @return mixed + * @return mixed|string */ - public function getAppid() + public function getAppid(): mixed { return $this->appid; } /** - * @param mixed $appid - * @return Notify + * @param mixed|string $appid */ - public function setAppid($appid) + public function setAppid(mixed $appid): void { $this->appid = $appid; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getMchId() + public function getMchId(): mixed { return $this->mch_id; } /** - * @param mixed $mch_id - * @return Notify + * @param mixed|string $mch_id */ - public function setMchId($mch_id) + public function setMchId(mixed $mch_id): void { $this->mch_id = $mch_id; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getDeviceInfo() + public function getDeviceInfo(): mixed { return $this->device_info; } /** - * @param mixed $device_info - * @return Notify + * @param mixed|string $device_info */ - public function setDeviceInfo($device_info) + public function setDeviceInfo(mixed $device_info): void { $this->device_info = $device_info; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getNonceStr() + public function getNonceStr(): mixed { return $this->nonce_str; } /** - * @param mixed $nonce_str - * @return Notify + * @param mixed|string $nonce_str */ - public function setNonceStr($nonce_str) + public function setNonceStr(mixed $nonce_str): void { $this->nonce_str = $nonce_str; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getSign() + public function getSign(): mixed { return $this->sign; } /** - * @param mixed $sign - * @return Notify + * @param mixed|string $sign */ - public function setSign($sign) + public function setSign(mixed $sign): void { $this->sign = $sign; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getSignType() + public function getSignType(): mixed { return $this->sign_type; } /** - * @param mixed $sign_type - * @return Notify + * @param mixed|string $sign_type */ - public function setSignType($sign_type) + public function setSignType(mixed $sign_type): void { $this->sign_type = $sign_type; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getResultCode() + public function getResultCode(): mixed { return $this->result_code; } /** - * @param mixed $result_code - * @return Notify + * @param mixed|string $result_code */ - public function setResultCode($result_code) + public function setResultCode(mixed $result_code): void { $this->result_code = $result_code; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getErrCode() + public function getErrCode(): mixed { return $this->err_code; } /** - * @param mixed $err_code - * @return Notify + * @param mixed|string $err_code */ - public function setErrCode($err_code) + public function setErrCode(mixed $err_code): void { $this->err_code = $err_code; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getErrCodeDes() + public function getErrCodeDes(): mixed { return $this->err_code_des; } /** - * @param mixed $err_code_des - * @return Notify + * @param mixed|string $err_code_des */ - public function setErrCodeDes($err_code_des) + public function setErrCodeDes(mixed $err_code_des): void { $this->err_code_des = $err_code_des; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getOpenid() + public function getOpenid(): mixed { return $this->openid; } /** - * @param mixed $openid - * @return Notify + * @param mixed|string $openid */ - public function setOpenid($openid) + public function setOpenid(mixed $openid): void { $this->openid = $openid; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getIsSubscribe() + public function getIsSubscribe(): mixed { return $this->is_subscribe; } /** - * @param mixed $is_subscribe - * @return Notify + * @param mixed|string $is_subscribe */ - public function setIsSubscribe($is_subscribe) + public function setIsSubscribe(mixed $is_subscribe): void { $this->is_subscribe = $is_subscribe; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getTradeType() + public function getTradeType(): mixed { return $this->trade_type; } /** - * @param mixed $trade_type - * @return Notify + * @param mixed|string $trade_type */ - public function setTradeType($trade_type) + public function setTradeType(mixed $trade_type): void { $this->trade_type = $trade_type; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getBankType() + public function getBankType(): mixed { return $this->bank_type; } /** - * @param mixed $bank_type - * @return Notify + * @param mixed|string $bank_type */ - public function setBankType($bank_type) + public function setBankType(mixed $bank_type): void { $this->bank_type = $bank_type; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getTotalFee() + public function getTotalFee(): mixed { return $this->total_fee; } /** - * @param mixed $total_fee - * @return Notify + * @param mixed|string $total_fee */ - public function setTotalFee($total_fee) + public function setTotalFee(mixed $total_fee): void { $this->total_fee = $total_fee; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getSettlementTotalFee() + public function getSettlementTotalFee(): mixed { return $this->settlement_total_fee; } /** - * @param mixed $settlement_total_fee - * @return Notify + * @param mixed|string $settlement_total_fee */ - public function setSettlementTotalFee($settlement_total_fee) + public function setSettlementTotalFee(mixed $settlement_total_fee): void { $this->settlement_total_fee = $settlement_total_fee; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getFeeType() + public function getFeeType(): mixed { return $this->fee_type; } /** - * @param mixed $fee_type - * @return Notify + * @param mixed|string $fee_type */ - public function setFeeType($fee_type) + public function setFeeType(mixed $fee_type): void { $this->fee_type = $fee_type; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getCashFee() + public function getCashFee(): mixed { return $this->cash_fee; } /** - * @param mixed $cash_fee - * @return Notify + * @param mixed|string $cash_fee */ - public function setCashFee($cash_fee) + public function setCashFee(mixed $cash_fee): void { $this->cash_fee = $cash_fee; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getCashFeeType() + public function getCashFeeType(): mixed { return $this->cash_fee_type; } /** - * @param mixed $cash_fee_type - * @return Notify + * @param mixed|string $cash_fee_type */ - public function setCashFeeType($cash_fee_type) + public function setCashFeeType(mixed $cash_fee_type): void { $this->cash_fee_type = $cash_fee_type; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getCouponFee() + public function getCouponFee(): mixed { return $this->coupon_fee; } /** - * @param mixed $coupon_fee - * @return Notify + * @param mixed|string $coupon_fee */ - public function setCouponFee($coupon_fee) + public function setCouponFee(mixed $coupon_fee): void { $this->coupon_fee = $coupon_fee; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getCouponCount() + public function getCouponCount(): mixed { return $this->coupon_count; } /** - * @param mixed $coupon_count - * @return Notify + * @param mixed|string $coupon_count */ - public function setCouponCount($coupon_count) + public function setCouponCount(mixed $coupon_count): void { $this->coupon_count = $coupon_count; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getCouponTypeN() + public function getCouponTypeN(): mixed { return $this->coupon_type_n; } /** - * @param mixed $coupon_type_n - * @return Notify + * @param mixed|string $coupon_type_n */ - public function setCouponTypeN($coupon_type_n) + public function setCouponTypeN(mixed $coupon_type_n): void { $this->coupon_type_n = $coupon_type_n; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getCouponIdN() + public function getCouponIdN(): mixed { return $this->coupon_id_n; } /** - * @param mixed $coupon_id_n - * @return Notify + * @param mixed|string $coupon_id_n */ - public function setCouponIdN($coupon_id_n) + public function setCouponIdN(mixed $coupon_id_n): void { $this->coupon_id_n = $coupon_id_n; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getCouponFeeN() + public function getCouponFeeN(): mixed { return $this->coupon_fee_n; } /** - * @param mixed $coupon_fee_n - * @return Notify + * @param mixed|string $coupon_fee_n */ - public function setCouponFeeN($coupon_fee_n) + public function setCouponFeeN(mixed $coupon_fee_n): void { $this->coupon_fee_n = $coupon_fee_n; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getTransactionId() + public function getTransactionId(): mixed { return $this->transaction_id; } /** - * @param mixed $transaction_id - * @return Notify + * @param mixed|string $transaction_id */ - public function setTransactionId($transaction_id) + public function setTransactionId(mixed $transaction_id): void { $this->transaction_id = $transaction_id; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getOutTradeNo() + public function getOutTradeNo(): mixed { return $this->out_trade_no; } /** - * @param mixed $out_trade_no - * @return Notify + * @param mixed|string $out_trade_no */ - public function setOutTradeNo($out_trade_no) + public function setOutTradeNo(mixed $out_trade_no): void { $this->out_trade_no = $out_trade_no; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getAttach() + public function getAttach(): mixed { return $this->attach; } /** - * @param mixed $attach - * @return Notify + * @param mixed|string $attach */ - public function setAttach($attach) + public function setAttach(mixed $attach): void { $this->attach = $attach; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getTimeEnd() + public function getTimeEnd(): mixed { return $this->time_end; } /** - * @param mixed $time_end - * @return Notify + * @param mixed|string $time_end */ - public function setTimeEnd($time_end) + public function setTimeEnd(mixed $time_end): void { $this->time_end = $time_end; - return $this; } /** - * @return mixed + * @return mixed|string */ - public function getReturnCode() + public function getReturnCode(): mixed { return $this->return_code; } /** - * @param mixed $return_code - * @return Notify + * @param mixed|string $return_code */ - public function setReturnCode($return_code) + public function setReturnCode(mixed $return_code): void { $this->return_code = $return_code; - return $this; } } diff --git a/wchat/wx/PublicTemplate.php b/wchat/wx/PublicTemplate.php index ff90f03..d58b237 100644 --- a/wchat/wx/PublicTemplate.php +++ b/wchat/wx/PublicTemplate.php @@ -8,19 +8,20 @@ namespace wchat\wx; +use Kiri\Client; use wchat\common\Result; class PublicTemplate extends SmallProgram { - private $keywords = []; - private $templateId = ''; - private $first = ''; - private $remark = ''; - private $openId = ''; - private $defaultUrl = 'http://weixin.qq.com/download'; - private $sendUrl = 'https://api.weixin.qq.com/cgi-bin/message/template/send'; - private $miniprogram = []; + private array $keywords = []; + private string $templateId = ''; + private array $first = []; + private array $remark = []; + private string $openId = ''; + private string $defaultUrl = 'http://weixin.qq.com/download'; + private string $sendUrl = '/cgi-bin/message/template/send'; + private array $miniprogram = []; /** @@ -58,9 +59,9 @@ class PublicTemplate extends SmallProgram /** * @param $name * @param $context - * @param $color + * @param string $color */ - public function replaceKeyword($name, $context, $color = '') + public function replaceKeyword($name, $context, string $color = '') { $this->keywords[$name] = ['value' => $context, 'color' => $color]; } @@ -84,9 +85,10 @@ class PublicTemplate extends SmallProgram /** * @param $context - * @param $color + * @param string $color + * @return void */ - public function setFirst($context, $color = '#f00') + public function setFirst($context, string $color = '#f00'): void { $this->first = [ 'value' => $context, @@ -96,9 +98,10 @@ class PublicTemplate extends SmallProgram /** * @param $context - * @param $color + * @param string $color + * @return void */ - public function setRemark($context, $color = '#000') + public function setRemark($context, string $color = '#000'): void { $this->remark = [ 'value' => $context, @@ -108,12 +111,13 @@ class PublicTemplate extends SmallProgram /** * @param $appid - * @param $pagepath + * @param string $pagepath + * @return void */ - public function setMiniprogram($appid, $pagepath) + public function setMiniprogram($appid, string $pagepath): void { $this->miniprogram = [ - 'appid' => $appid, + 'appid' => $appid, 'pagepath' => $pagepath ]; } @@ -124,34 +128,37 @@ class PublicTemplate extends SmallProgram * * 奴隶交易通知 */ - public function sendTemplate() + public function sendTemplate(): Result { - $url = $this->sendUrl . '?access_token=' . $this->getAccessToken(); + $url = $this->sendUrl . '?access_token=' . $this->config->getAccessToken(); $keywords = $this->keywords; $keywords['first'] = $this->first; $keywords['remark'] = $this->remark; $default = [ - "touser" => $this->openId, + "touser" => $this->openId, "template_id" => $this->templateId, - "url" => $this->defaultUrl, - "data" => $keywords, + "url" => $this->defaultUrl, + "data" => $keywords, ]; - if (!empty($this->miniprogram)) { $default['miniprogram'] = $this->miniprogram; } - $params = json_encode($default, JSON_UNESCAPED_UNICODE); + $client = new Client('api.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->post($url, $default); + $client->close(); - $this->request->setIsSSL(true); - $this->request->addHeader('Content-Type', 'application/json'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $result = $this->request->post($url, $params); - $result->append('postBody', $default); - - return $result; + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errcode']) && $body['errcode'] != 0) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } else { + return new Result(code: 0, data: $body); + } } } diff --git a/wchat/wx/Recharge.php b/wchat/wx/Recharge.php deleted file mode 100644 index 2a285a9..0000000 --- a/wchat/wx/Recharge.php +++ /dev/null @@ -1,188 +0,0 @@ - 500, 'message' => '充值金额不能小于0.']); - } - $this->money = $money; - $this->orderNo = $orderNo; - $this->data['openid'] = $openId; - - $config = $this->config; - $this->request->setCallback(function ($result, $body) use ($config) { - $data = Help::toArray($result); - if (isset($data['sign'])) { - $sign = $data['sign']; - unset($data['sign']); - } - $return = []; - $_sign = Help::sign($data, $config->getKey(), $config->getSignType()); - if (!isset($sign) || $sign != $_sign) { - $return['code'] = -1; - $return['message'] = $data['return_msg'] ?? '返回数据签名验证失败'; - } else { - $return['code'] = 0; - $return['data'] = $data; - $return['data']['postBody'] = $body; - if ($data['return_code'] == 'FAIL') { - $return['code'] = -1; - $return['message'] = $data['return_msg']; - } - } - return new Result($return); - }); - - return $this->send($this->uniformed, $this->builder()); - } - - /** - * 'appId' => $result['appid'], - * 'nonceStr' => $result['nonce_str'], - * 'package' => 'prepay_id=' . $result['prepay_id'], - * 'signType' => 'MD5', - * 'timeStamp' => (string)time(), - * @param $prepay_id - * @return array - */ - public function reception($prepay_id) - { - $array = [ - 'appId' => $this->config->getAppid(), - 'nonceStr' => Help::random(32), - 'package' => 'prepay_id=' . $prepay_id, - 'signType' => 'MD5', - 'timeStamp' => (string)time(), - ]; - $key = $this->config->getKey(); - $sign_type = $this->config->getSignType(); - $array['paySign'] = Help::sign($array, $key, $sign_type); - return $array; - } - - /** - * @return string - */ - protected function builder() - { - $data = [ - 'appid' => $this->config->getAppid(), - 'mch_id' => $this->config->getMchId(), - 'nonce_str' => Help::random(32), - 'body' => $this->config->getBody(), - 'out_trade_no' => $this->orderNo, - 'total_fee' => $this->money, - 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], - 'notify_url' => $this->config->getNotifyUrl(), - 'trade_type' => $this->config->getTradeType(), - 'openid' => $this->data['openid'] - ]; - - $key = $this->config->getKey(); - $sign_type = $this->config->getSignType(); - - $data['sign'] = Help::sign($data, $key, $sign_type); -// $data['sign_type'] = $sign_type; - - return Help::toXml($data); - } - - public function getSignData() - { - $data = $this->data; - $data['key'] = $this->config->getKey(); - return $data; - } - - /** - * @param $money - * @param $openid - * @param $order - * @param $desc - * @return Result - * @throws - * - * 提现 - */ - public function cashWithdrawal($money, $openid, $order, $desc = '零钱提现') - { - $array = [ - 'nonce_str' => Help::random(32), - 'partner_trade_no' => $order, - 'mchid' => $this->config->getMchId(), - 'mch_appid' => $this->config->getAppid(), - 'openid' => $openid, - 'check_name' => 'NO_CHECK', - 'amount' => $money * 100, - 'spbill_create_ip' => $this->config->getRemoteAddr(), - 'desc' => $desc, - ]; - - $key = $this->config->getKey(); - $sign_type = $this->config->getSignType(); - $array['sign'] = Help::sign($array, $key, $sign_type); - - $this->request->setCallback(function ($data) { - $array = Help::toArray($data); - if ($array['return_code'] != 'SUCCESS') { - $data = ['code' => $array['return_code'], 'message' => $array['return_msg']]; - } else if ($array['result_code'] != 'SUCCESS') { - $data = ['code' => $array['err_code'], 'message' => $array['err_code_des']]; - } else { - $data = ['code' => 0, 'message' => '支付成功', 'data' => $array]; - } - return new Result($data); - }); - return $this->send($this->transfers, Help::toXml($array)); - } - - /** - * @param $url - * @param $data - * @return array|mixed|Result - * @throws \Exception - */ - private function send($url, $data) - { - $this->request->setIsSSL(true); - $this->request->setMethod(HttpClient::POST); - $this->request->addHeader('Content-Type', 'text/xml'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - return $this->request->send($url, $data); - } -} diff --git a/wchat/wx/SecCheck.php b/wchat/wx/SecCheck.php index 0070c7c..5bf2bf2 100644 --- a/wchat/wx/SecCheck.php +++ b/wchat/wx/SecCheck.php @@ -4,6 +4,7 @@ namespace wchat\wx; +use Kiri\Client; use wchat\common\Result; /** @@ -13,59 +14,70 @@ use wchat\common\Result; class SecCheck extends SmallProgram { - private $_url = 'https://api.weixin.qq.com/wxa/img_sec_check?access_token='; + private string $_url = '/wxa/img_sec_check?access_token='; - private $_msgUrl = '/wxa/msg_sec_check?access_token='; + private string $_msgUrl = '/wxa/msg_sec_check?access_token='; - private $_mediaCheckAsync = '/wxa/media_check_async?access_token='; + private string $_mediaCheckAsync = '/wxa/media_check_async?access_token='; const MEDIA_VIDEO = 1; const MEDIA_IMAGE = 1; /** - * @param $path - * @return array|Result|mixed + * @param string $path + * @return Result */ - public function image($path = '') + public function image(string $path = ''): Result { if (!file_exists($path)) { return $this->sendError('文件不存在', 404); } - $this->request->setUseSwoole(false); - $this->request->setIsSSL(true); - $this->request->setHeader('Content-Type', 'multipart/form-data'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - return $this->request->upload($this->_url . $this->config->getAccessToken(), ['media' => new \CURLFile($path)]); + $access_token = $this->config->getAccessToken(); + + $client = new Client('api.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'multipart/form-data']); + $client->upload($this->_url . '?access_token=' . $access_token, [ + 'media' => new \CURLFile($path) + ]); + $client->close(); + + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errcode']) && $body['errcode'] != 0) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } + return new Result(code: 0, data: $body); } /** - * @param $url + * @param string $url * @param int $type * @return mixed * @throws */ - public function mediaAsync($url, $type = SecCheck::MEDIA_IMAGE) + public function mediaAsync(string $url, int $type = SecCheck::MEDIA_IMAGE): Result { if (!in_array($type, [self::MEDIA_IMAGE, self::MEDIA_VIDEO])) { throw new \Exception('暂不支持的文件类型'); } - $this->request->setIsSSL(true); - $this->request->setHost('api.weixin.qq.com'); - $this->request->setHeader('Content-Type', 'application/json'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $requestUrl = $this->_mediaCheckAsync . $this->config->getAccessToken(); - $response = $this->request->post($requestUrl, [ - 'media_url' => $url, - 'media_type' => $type - ]); - if (!$response->isResultsOK()) { - throw new \Exception($response->getMessage()); + $client = new Client('api.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->post($requestUrl, ['media_url' => $url, 'media_type' => $type]); + $client->close(); + + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errcode']) && $body['errcode'] != 0) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } else { + return new Result(code: 0, data: $body); } - return $response->getData('trace_id'); } @@ -73,7 +85,7 @@ class SecCheck extends SmallProgram * @param $params * @return ContentAsyncCheck|null */ - public function readByEvent($params) + public function readByEvent($params): ?ContentAsyncCheck { return ContentAsyncCheck::instance($params); } @@ -81,22 +93,29 @@ class SecCheck extends SmallProgram /** * @param $content - * @return array|Result|mixed + * @return Result */ - public function text($content) + public function text($content): Result { if (empty($content)) { return $this->sendError('文件不存在', 404); } - $this->request->setIsSSL(true); - $this->request->setHost('api.weixin.qq.com'); - $this->request->setHeader('Content-Type', 'application/json'); - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); + $requestUrl = $this->_msgUrl . $this->config->getAccessToken(); - $requestUrl = $this->_msgUrl . $this->config->getAccessToken(); + $client = new Client('api.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->post($requestUrl, ['content' => $content]); + $client->close(); - return $this->request->post($requestUrl, ['content' => $content]); + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errcode']) && $body['errcode'] != 0) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } else { + return new Result(code: 0, data: $body); + } } } diff --git a/wchat/wx/SmallProgram.php b/wchat/wx/SmallProgram.php index ad4d85f..811eac7 100644 --- a/wchat/wx/SmallProgram.php +++ b/wchat/wx/SmallProgram.php @@ -4,41 +4,8 @@ namespace wchat\wx; -use wchat\common\Miniprogarampage; +use wchat\common\Multiprogramming; -class SmallProgram extends Miniprogarampage +class SmallProgram extends Multiprogramming { - - protected static $instance; - - private $url = 'https://api.weixin.qq.com/cgi-bin/token'; - - - /** - * @param bool $get_token - * @return mixed - * @throws \Exception - */ - public function generateAccess_token($get_token = false) - { - if (!empty($this->config->getToken())) { - return $this->config->getToken(); - } - $query = [ - 'grant_type' => 'client_credential', - 'appid' => $this->config->getAppid(), - 'secret' => $this->config->getAppsecret() - ]; - $this->request->setErrorField('errcode'); - $this->request->setErrorMsgField('errmsg'); - $param = $this->request->get($this->url, $query); - if (!$param->isResultsOK()) { - throw new \Exception($param->getMessage()); - } - if ($get_token) { - return $param->getData('access_token'); - } - return $param->getData(); - } - } diff --git a/wchat/wx/Subject.php b/wchat/wx/Subject.php index 11c1d44..3f48a56 100644 --- a/wchat/wx/Subject.php +++ b/wchat/wx/Subject.php @@ -13,13 +13,21 @@ use wchat\common\Result; class Subject extends \wchat\base\Subject { - private $sendUrl = 'https://api.weixin.qq.com/cgi-bin/message/subscribe/send'; /** * @return string */ - public function getUrl() + public function getUrl(): string { - return $this->sendUrl; + return 'cgi-bin/message/subscribe/send'; + } + + + /** + * @return string + */ + public function getHost(): string + { + return 'api.weixin.qq.com'; } } diff --git a/wchat/wx/Template.php b/wchat/wx/Template.php index ba7b709..b9f7640 100644 --- a/wchat/wx/Template.php +++ b/wchat/wx/Template.php @@ -14,11 +14,23 @@ namespace wchat\wx; */ class Template extends \wchat\base\Template { - private $sendUrl = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send'; - public function getUrl() + + /** + * @return string + */ + public function getUrl(): string { - return $this->sendUrl; + return '/cgi-bin/message/wxopen/template/send'; + } + + + /** + * @return string + */ + public function getHost(): string + { + return 'api.weixin.qq.com'; } } diff --git a/wchat/wx/Token.php b/wchat/wx/Token.php index 96a6f1a..8212bca 100644 --- a/wchat/wx/Token.php +++ b/wchat/wx/Token.php @@ -4,11 +4,35 @@ namespace wchat\wx; -use wchat\base\Access_Token; +use Kiri\Client; +use wchat\common\Result; -class Token extends SmallProgram implements Access_Token +class Token extends SmallProgram { + /** + * @return Result + */ + public function token(): Result + { + $query = [ + 'grant_type' => 'client_credential', + 'appid' => $this->config->getAppid(), + 'secret' => $this->config->getAppsecret() + ]; + $client = new Client('api.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->get('cgi-bin/token', $query); + $client->close(); + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $body = json_decode($client->getBody(), true); + if (isset($body['errcode']) && $body['errcode'] != 0) { + return new Result(code: $body['errcode'], message: $body['errmsg']); + } + return new Result(code: 0, data: $body); + } } diff --git a/wchat/wx/V2/WxV2AppPayment.php b/wchat/wx/V2/WxV2AppPayment.php new file mode 100644 index 0000000..7a60d30 --- /dev/null +++ b/wchat/wx/V2/WxV2AppPayment.php @@ -0,0 +1,72 @@ +getInitCore($orderNo, $money); + $body['trade_type'] = 'APP'; + $body['spbill_create_ip'] = $spbill_create_ip; + + $client = new Client('api.mch.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->withBody($this->sign($body)); + $client->post($this->uniformed); + $client->close(); + + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $data = Help::toArray($client->getBody()); + if (isset($data['return_code']) && $data['return_code'] != 'SUCCESS') { + return new Result(code: 503, message: $data['return_msg']); + } + if ($data['result_code'] != 'SUCCESS') { + return new Result(code: 504, message: $data['err_code_des']); + } + + return new Result(code: 0, data: $this->reception($data['prepayid'])); + } + + + /** + * @param string $prepay_id + * @return string + */ + public function reception(string $prepay_id): string + { + return $this->sign([ + 'appId' => $this->config->getAppid(), + 'partnerid' => $this->config->getMchId(), + 'prepayid' => $prepay_id, + 'package' => 'Sign=WXPay', + 'noncestr' => Help::random(32), + 'timestamp' => time() + ]); + } + +} diff --git a/wchat/wx/V2/WxV2PayJsApi.php b/wchat/wx/V2/WxV2PayJsApi.php new file mode 100644 index 0000000..59b00d7 --- /dev/null +++ b/wchat/wx/V2/WxV2PayJsApi.php @@ -0,0 +1,210 @@ +getInitCore($orderNo, $money); + $body['trade_type'] = 'JSAPI'; + $body['spbill_create_ip'] = $spbill_create_ip; + $body['openid'] = $openId; + + $client = new Client('api.mch.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->withBody($this->sign($body)); + $client->post($this->uniformed); + $client->close(); + + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $data = Help::toArray($client->getBody()); + if (isset($data['return_code']) && $data['return_code'] != 'SUCCESS') { + return new Result(code: 503, message: $data['return_msg']); + } + if ($data['result_code'] != 'SUCCESS') { + return new Result(code: 504, message: $data['err_code_des']); + } + + return new Result(code: 0, data: $this->reception($data['prepayid'])); + } + + + /** + * @param int $money + * @param string $orderNo + * @param string $app_name + * @param string $package_name + * @param string $spbill_create_ip + * @return Result + */ + public function h5Android(int $money, string $orderNo, string $app_name, string $package_name, string $spbill_create_ip = '127.0.0.1'): Result + { + if ($money < 0) { + return new Result(code: 400, message: '充值金额不能小于0.'); + } + + $body = $this->getInitCore($orderNo, $money); + $body['trade_type'] = 'MWEB'; + $body['spbill_create_ip'] = $spbill_create_ip; + $body['scene_info'] = json_encode([ + 'h5_info' => [ + 'type' => 'Android', + 'app_name' => $app_name, + 'package_name' => $package_name + ] + ], JSON_UNESCAPED_UNICODE); + + $client = new Client('api.mch.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->withBody($this->sign($body)); + $client->post($this->uniformed); + $client->close(); + + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $data = Help::toArray($client->getBody()); + if (isset($data['return_code']) && $data['return_code'] != 'SUCCESS') { + return new Result(code: 503, message: $data['return_msg']); + } + if ($data['result_code'] != 'SUCCESS') { + return new Result(code: 504, message: $data['err_code_des']); + } + + return new Result(code: 0, data: $this->reception($data['prepayid'])); + } + + + /** + * @param int $money + * @param string $orderNo + * @param string $app_name + * @param string $bundle_id + * @param string $spbill_create_ip + * @return Result + */ + public function h5Ios(int $money, string $orderNo, string $app_name, string $bundle_id, string $spbill_create_ip = '127.0.0.1'): Result + { + if ($money < 0) { + return new Result(code: 400, message: '充值金额不能小于0.'); + } + + $body = $this->getInitCore($orderNo, $money); + $body['trade_type'] = 'MWEB'; + $body['spbill_create_ip'] = $spbill_create_ip; + $body['scene_info'] = json_encode([ + 'h5_info' => [ + 'type' => 'IOS', + 'app_name' => $app_name, + 'bundle_id' => $bundle_id + ] + ], JSON_UNESCAPED_UNICODE); + + $client = new Client('api.mch.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->withBody($this->sign($body)); + $client->post($this->uniformed); + $client->close(); + + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $data = Help::toArray($client->getBody()); + if (isset($data['return_code']) && $data['return_code'] != 'SUCCESS') { + return new Result(code: 503, message: $data['return_msg']); + } + if ($data['result_code'] != 'SUCCESS') { + return new Result(code: 504, message: $data['err_code_des']); + } + + return new Result(code: 0, data: $this->reception($data['prepayid'])); + } + + + /** + * @param int $money + * @param string $orderNo + * @param string $wap_url + * @param string $wap_name + * @param string $spbill_create_ip + * @return Result + */ + public function h5(int $money, string $orderNo, string $wap_url, string $wap_name, string $spbill_create_ip = '127.0.0.1'): Result + { + if ($money < 0) { + return new Result(code: 400, message: '充值金额不能小于0.'); + } + + $body = $this->getInitCore($orderNo, $money); + $body['trade_type'] = 'MWEB'; + $body['spbill_create_ip'] = $spbill_create_ip; + $body['scene_info'] = json_encode([ + 'h5_info' => [ + 'type' => 'IOS', + 'wap_url' => $wap_url, + 'wap_name' => $wap_name + ] + ], JSON_UNESCAPED_UNICODE); + + $client = new Client('api.mch.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->withBody($this->sign($body)); + $client->post($this->uniformed); + $client->close(); + + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + $data = Help::toArray($client->getBody()); + if (isset($data['return_code']) && $data['return_code'] != 'SUCCESS') { + return new Result(code: 503, message: $data['return_msg']); + } + if ($data['result_code'] != 'SUCCESS') { + return new Result(code: 504, message: $data['err_code_des']); + } + + return new Result(code: 0, data: $this->reception($data['prepayid'])); + } + + + /** + * @param string $prepay_id + * @return string + */ + public function reception(string $prepay_id): string + { + return $this->sign([ + 'signType' => $this->config->getSignType(), + 'package' => 'prepay_id=' . $prepay_id, + 'nonceStr' => Help::random(32), + 'timestamp' => time() + ]); + } + +} diff --git a/wchat/wx/V2/WxV2PayTait.php b/wchat/wx/V2/WxV2PayTait.php new file mode 100644 index 0000000..06762ab --- /dev/null +++ b/wchat/wx/V2/WxV2PayTait.php @@ -0,0 +1,100 @@ + $result['appid'], + * 'nonceStr' => $result['nonce_str'], + * 'package' => 'prepay_id=' . $result['prepay_id'], + * 'signType' => 'MD5', + * 'timeStamp' => (string)time(), + * @param $prepay_id + * @return array + */ + #[ArrayShape(['appId' => "string", 'nonceStr' => "string", 'package' => "string", 'signType' => "string", 'timeStamp' => "string", 'paySign' => "string"])] + public function reception($prepay_id): array + { + $array = [ + 'appId' => $this->config->getAppid(), + 'nonceStr' => Help::random(32), + 'package' => 'prepay_id=' . $prepay_id, + 'signType' => 'MD5', + 'timeStamp' => (string)time(), + ]; + $key = $this->config->getKey(); + $sign_type = $this->config->getSignType(); + $array['paySign'] = Help::sign($array, $key, $sign_type); + return $array; + } + + + /** + * @param string $orderNo + * @param float|int $total + * @return array + */ + #[ArrayShape(['appid' => "string", 'mch_id' => "string", 'nonce_str' => "string", 'body' => "string", 'out_trade_no' => "string", 'total_fee' => "float|int", 'spbill_create_ip' => "mixed", 'notify_url' => "string", 'trade_type' => "string"])] + protected function getInitCore(string $orderNo, float|int $total): array + { + return [ + 'appid' => $this->config->getAppid(), + 'mch_id' => $this->config->getMchId(), + 'nonce_str' => Help::random(32), + 'body' => $this->config->getBody(), + 'out_trade_no' => $orderNo, + 'total_fee' => $total, + 'notify_url' => $this->config->getNotifyUrl(), + 'trade_type' => $this->config->getTradeType(), + ]; + } + + + /** + * @param array $data + * @return string + */ + protected function sign(array $data): string + { + $key = $this->config->getKey(); + $sign_type = $this->config->getSignType(); + + $data['sign'] = Help::sign($data, $key, $sign_type); + + return Help::toXml($data); + } + + /** + * @param string $orderNo + * @param int|float $money + * @param string $openid + * @return string + */ + protected function builder(string $orderNo, int|float $money, string $openid): string + { + $data = [ + 'appid' => $this->config->getAppid(), + 'mch_id' => $this->config->getMchId(), + 'nonce_str' => Help::random(32), + 'body' => $this->config->getBody(), + 'out_trade_no' => $orderNo, + 'total_fee' => $money, + 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], + 'notify_url' => $this->config->getNotifyUrl(), + 'trade_type' => $this->config->getTradeType(), + 'openid' => $openid + ]; + + $key = $this->config->getKey(); + $sign_type = $this->config->getSignType(); + + $data['sign'] = Help::sign($data, $key, $sign_type); + + return Help::toXml($data); + } +} diff --git a/wchat/wx/V2/WxV2Withdrawal.php b/wchat/wx/V2/WxV2Withdrawal.php new file mode 100644 index 0000000..be7bf3e --- /dev/null +++ b/wchat/wx/V2/WxV2Withdrawal.php @@ -0,0 +1,62 @@ + Help::random(32), + 'partner_trade_no' => $order, + 'mchid' => $this->config->getMchId(), + 'mch_appid' => $this->config->getAppid(), + 'openid' => $openid, + 'check_name' => 'NO_CHECK', + 'amount' => $money * 100, + 'spbill_create_ip' => $this->config->getRemoteAddr(), + 'desc' => $desc, + ]; + + $key = $this->config->getKey(); + $sign_type = $this->config->getSignType(); + $array['sign'] = Help::sign($array, $key, $sign_type); + + $client = new Client('api.mch.weixin.qq.com', 443, true); + $client->withHeader(['Content-Type' => 'application/json']); + $client->withBody($body = Help::toXml($array)); + $client->post($this->transfers); + $client->close(); + + if (!in_array($client->getStatusCode(), [101, 200, 201])) { + return new Result(code: 505, message: 'network error.'); + } + + $data = Help::toArray($client->getBody()); + + $data['body'] = $body; + if ($data['return_code'] == 'FAIL') { + return new Result(code: $array['return_code'], message: $data['return_msg'], data: $data); + } else if ($array['result_code'] != 'SUCCESS') { + return new Result(code: $array['err_code'], message: $data['err_code_des'], data: $data); + } else { + return new Result(code: 0, message: '提现成功', data: $data); + } + } + +} diff --git a/wchat/wx/V3/TransferDetail.php b/wchat/wx/V3/TransferDetail.php new file mode 100644 index 0000000..c8858b2 --- /dev/null +++ b/wchat/wx/V3/TransferDetail.php @@ -0,0 +1,36 @@ + "string", 'transfer_amount' => "float|int", 'transfer_remark' => "string", 'openid' => "string", 'user_name' => "string"])] + public function toArray(): array + { + return [ + 'out_detail_no' => $this->out_detail_no, + 'transfer_amount' => $this->transfer_amount, + 'transfer_remark' => $this->transfer_remark, + 'openid' => $this->openid, + 'user_name' => $this->user_name, + ]; + } + +} diff --git a/wchat/wx/V3/WxV3AppPayment.php b/wchat/wx/V3/WxV3AppPayment.php new file mode 100644 index 0000000..866cb52 --- /dev/null +++ b/wchat/wx/V3/WxV3AppPayment.php @@ -0,0 +1,46 @@ +getInitCore($orderNo, $total); + + $body['scene_info'] = ['payer_client_ip' => $payer_client_ip]; + + $sign = $this->signature('POST', '/v3/pay/transactions/components', $json = json_encode($body, JSON_UNESCAPED_UNICODE)); + + $client = new Client('api.mch.weixin.qq.com', 443, TRUE); + $client->withAddedHeader('Authorization', $sign)->withContentType('application/json') + ->withAgent('application/json')->withBody($json) + ->post('/v3/pay/transactions/components'); + $client->close(); + + $json = json_decode($client->getBody(), TRUE); + if (!isset($json['prepay_id'])) { + throw new Exception('微信支付调用失败'); + } + return $this->createResponse($json, $body); + } + + +} diff --git a/wchat/wx/V3/WxV3NativePayment.php b/wchat/wx/V3/WxV3NativePayment.php new file mode 100644 index 0000000..3fba296 --- /dev/null +++ b/wchat/wx/V3/WxV3NativePayment.php @@ -0,0 +1,47 @@ + "string"])] + public function payment($orderNo, int $total, string $openId = NULL, string $payer_client_ip = '127.0.0.1'): array + { + $body = $this->getInitCore($orderNo, $total); + + $sign = $this->signature('POST', '/v3/pay/transactions/native', $json = json_encode($body, JSON_UNESCAPED_UNICODE)); + + $client = new Client('api.mch.weixin.qq.com', 443, TRUE); + $client->withAddedHeader('Authorization', $sign)->withContentType('application/json') + ->withAgent('application/json')->withBody(new Stream($json)) + ->post('/v3/pay/transactions/native'); + $client->close(); + + $json = json_decode($client->getBody(), TRUE); + if (!isset($json['code_url'])) { + throw new Exception('微信支付调用失败'); + } + return ['code_url' => $json['code_url']]; + } + + +} diff --git a/wchat/wx/V3/WxV3Payment.php b/wchat/wx/V3/WxV3Payment.php new file mode 100644 index 0000000..4c2d509 --- /dev/null +++ b/wchat/wx/V3/WxV3Payment.php @@ -0,0 +1,50 @@ +getInitCore($orderNo, $total); + $body['payer'] = ['openid' => $openId]; + $body['scene_info'] = ['payer_client_ip' => $payer_client_ip]; + + $sign = $this->signature('POST', '/v3/pay/transactions/jsapi', $json = json_encode($body, JSON_UNESCAPED_UNICODE)); + + $client = new Client('api.mch.weixin.qq.com', 443, TRUE); + $client->withAddedHeader('Authorization', $sign) + ->withContentType('application/json') + ->withAddedHeader('User-Agent', 'application/json') + ->withBody(new Stream($json)) + ->post('/v3/pay/transactions/jsapi'); + $client->close(); + + $json = json_decode($client->getBody(), TRUE); + if (!isset($json['prepay_id'])) { + throw new Exception('微信支付调用失败'); + } + + return $this->createResponse($json, $body); + } + + +} diff --git a/wchat/wx/V3/WxV3PaymentTait.php b/wchat/wx/V3/WxV3PaymentTait.php new file mode 100644 index 0000000..22ca45c --- /dev/null +++ b/wchat/wx/V3/WxV3PaymentTait.php @@ -0,0 +1,114 @@ +getConfig()->getAppid(); + $body['mchid'] = $this->getConfig()->getMchId(); + $body['description'] = $this->getConfig()->getBody(); + $body['out_trade_no'] = $orderNo; + $body['notify_url'] = $this->getConfig()->getNotifyUrl(); + $body['amount'] = ['total' => $total, 'currency' => 'CNY']; + return $body; + } + + + /** + * @param string $http_method + * @param string $canonical_url + * @param string $body + * @return string + * @throws Exception + */ + public function signature(string $http_method, string $canonical_url, string $body = ''): string + { + $message = $http_method . "\n" . $canonical_url . "\n" . ($time = time()) . "\n" . ($rand = md5(random_bytes(32))) . "\n" . $body . "\n"; + + $sign = $this->openssl_signature($message); + + return sprintf('%s mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $this->getConfig()->getSchema(), + $this->getConfig()->getMchId(), $rand, $time, $this->getConfig()->getSerialNo(), $sign); + } + + + /** + * @param $body + * @return string + */ + public function openssl_signature($body): string + { + $pem = file_get_contents($this->getConfig()->getSslCert()); + + $mch_private_key = openssl_get_privatekey($pem); + + openssl_sign($body, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption'); + return base64_encode($raw_sign); + } + + + /** + * @param $json + * @param $body + * @return array + */ + private function createResponse($json, $body): array + { + $responseArray['appId'] = $body['appid']; + $responseArray['timeStamp'] = (string)time(); + $responseArray['nonceStr'] = Help::random(32); + $responseArray['package'] = "prepay_id=" . $json['prepay_id']; + + $responseBody = $responseArray['appId'] . PHP_EOL . $responseArray['timeStamp'] . PHP_EOL . $responseArray['nonceStr'] . PHP_EOL . $responseArray['package'] . PHP_EOL; + + $responseArray['signType'] = 'RSA'; + $responseArray['signBody'] = $responseBody; + $responseArray['paySign'] = $this->openssl_signature($responseBody); + $responseArray['prepay_id'] = $json['prepay_id']; + + return $responseArray; + } + + + /** + * @param $associatedData + * @param $nonceStr + * @param $ciphertext + * @return bool|string + */ + public function decryptToString($associatedData, $nonceStr, $ciphertext): bool|string + { + $ciphertext = \base64_decode($ciphertext); + if (strlen($ciphertext) <= AUTH_TAG_LENGTH_BYTE) { + return FALSE; + } + if (function_exists('\sodium\crypto_aead_aes256gcm_is_available') && crypto_aead_aes256gcm_is_available()) { + return crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR'); + } + if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && crypto_aead_aes256gcm_is_available()) { + return crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR'); + } + if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) { + $ctext = substr($ciphertext, 0, -AUTH_TAG_LENGTH_BYTE); + $authTag = substr($ciphertext, -AUTH_TAG_LENGTH_BYTE); + return \openssl_decrypt($ctext, 'aes-256-gcm', 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR', \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData); + } + throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php'); + } +} diff --git a/wchat/wx/V3/WxV3Withdrawal.php b/wchat/wx/V3/WxV3Withdrawal.php new file mode 100644 index 0000000..434dfa8 --- /dev/null +++ b/wchat/wx/V3/WxV3Withdrawal.php @@ -0,0 +1,67 @@ +create($orderNo, $batch_name, $batch_remark, $details); + + $sign = $this->signature('POST', '/v3/pay/transactions/batches', $json = json_encode($body, JSON_UNESCAPED_UNICODE)); + + $client = new Client('api.mch.weixin.qq.com', 443, TRUE); + $client->withAddedHeader('Authorization', $sign) + ->withContentType('application/json') + ->withAddedHeader('User-Agent', 'application/json') + ->withBody(new Stream($json)) + ->post('/v3/pay/transactions/batches'); + $client->close(); + + $json = json_decode($client->getBody(), TRUE); + if (!isset($json['prepay_id'])) { + throw new Exception('微信支付调用失败'); + } + + return $this->createResponse($json, $body); + } + + + #[ArrayShape(['transfer_detail_list' => "array", 'total_amount' => "int", 'total_num' => "int", 'batch_remark' => "string", 'batch_name' => "string", 'out_batch_no' => ""])] + private function create($orderNo, string $batch_name, string $batch_remark, array $details): array + { + $total = 0; + $body = ['transfer_detail_list' => []]; + $body['out_batch_no'] = $orderNo; + $body['batch_name'] = $batch_name; + $body['batch_remark'] = $batch_remark; + $body['total_num'] = count($details); + foreach ($details as $detail) { + $total += $detail->transfer_amount; + $body['transfer_detail_list'][] = $detail->toArray(); + } + $body['total_amount'] = $total; + return $body; + } + + +} diff --git a/wchat/wx/WxFactory.php b/wchat/wx/WxFactory.php new file mode 100644 index 0000000..b175a25 --- /dev/null +++ b/wchat/wx/WxFactory.php @@ -0,0 +1,26 @@ +get($class); + $object->setConfig($config); + return $object; + } + + +}