This commit is contained in:
xl
2023-11-14 00:45:54 +08:00
parent e721fe4f36
commit 0d8ddfef54
12 changed files with 763 additions and 1300 deletions
+57 -4
View File
@@ -29,10 +29,13 @@ class AppConfig
private string $proxyHost = ''; private string $proxyHost = '';
private int $proxyPort = 0; private int $proxyPort = 0;
private string $notifyUrl = ''; private string $notifyUrl = '';
private string $body = ''; private string $body = '';
private string $currency = 'CNY'; private string $currency = 'CNY';
private string $remoteIp = ''; private string $remoteIp = '';
private string $accessToken = '';
private string $tradeType = 'JSAPI';
private string $signType = 'MD5';
/** /**
* @var int * @var int
@@ -165,4 +168,54 @@ class AppConfig
{ {
$this->remoteIp = $remoteIp; $this->remoteIp = $remoteIp;
} }
/**
* @return string
*/
public function getAccessToken(): string
{
return $this->accessToken;
}
/**
* @param string $accessToken
*/
public function setAccessToken(string $accessToken): void
{
$this->accessToken = $accessToken;
}
/**
* @return string
*/
public function getTradeType(): string
{
return $this->tradeType;
}
/**
* @param string $tradeType
*/
public function setTradeType(string $tradeType): void
{
$this->tradeType = $tradeType;
}
/**
* @return string
*/
public function getSignType(): string
{
return $this->signType;
}
/**
* @param string $signType
*/
public function setSignType(string $signType): void
{
$this->signType = $signType;
}
} }
+148 -78
View File
@@ -8,16 +8,18 @@
namespace wchat\common; namespace wchat\common;
use Kiri\Client;
abstract class Multiprogramming implements Progaram abstract class Multiprogramming implements Progaram
{ {
/** @var Config */ /** @var Config */
protected Config $config; protected Config $config;
protected static ?Multiprogramming $instance = null; protected static ?Multiprogramming $instance = null;
protected int $errorCode = 0; protected int $errorCode = 0;
protected string $errorMsg = ''; protected string $errorMsg = '';
/** /**
@@ -26,57 +28,57 @@ abstract class Multiprogramming implements Progaram
protected AppConfig $payConfig; protected AppConfig $payConfig;
/** /**
* @param $message * @param $message
* @param int $code * @param int $code
* @return Result * @return Result
*/ */
protected function sendError($message, int $code = 500): Result protected function sendError($message, int $code = 500): Result
{ {
return new Result(code: $code, message: $message); return new Result(code: $code, message: $message);
} }
/** /**
* @param $code * @param $code
*/ */
public function setErrorCode($code) public function setErrorCode($code)
{ {
$this->errorCode = $code; $this->errorCode = $code;
} }
/** /**
* @param $message * @param $message
*/ */
public function setErrorMessage($message) public function setErrorMessage($message)
{ {
$this->errorMsg = $message; $this->errorMsg = $message;
} }
/** /**
* @return int * @return int
*/ */
public function getErrorCode(): int public function getErrorCode(): int
{ {
return $this->errorCode; return $this->errorCode;
} }
/** /**
* @return string * @return string
*/ */
public function getErrorMessage(): string public function getErrorMessage(): string
{ {
return $this->errorMsg; return $this->errorMsg;
} }
/** /**
* @param Config $config * @param Config $config
* @return void * @return void
*/ */
public function setConfig(Config $config): void public function setConfig(Config $config): void
{ {
$this->config = $config; $this->config = $config;
} }
/** /**
* @return AppConfig * @return AppConfig
@@ -95,39 +97,107 @@ abstract class Multiprogramming implements Progaram
} }
/** /**
* @return Config * @return Config
*/ */
public function getConfig(): Config public function getConfig(): Config
{ {
return $this->config; return $this->config;
} }
/** /**
* @param $result * @param $result
* @return array|bool * @return array|bool
* @throws \Exception * @throws \Exception
*/ */
protected function checkSign($result): array|bool protected function checkSign($result): array|bool
{ {
$data = Help::toArray($result); $data = Help::toArray($result);
if (!isset($data['sign'])) { if (!isset($data['sign'])) {
return $data; return $data;
} }
$sign = $data['sign']; $sign = $data['sign'];
unset($data['sign']); unset($data['sign']);
$key = $this->config->getKey(); $key = $this->config->getKey();
$sign_type = $this->config->getSignType(); $sign_type = $this->config->getSignType();
$_sign = Help::sign($data, $key, $sign_type); $_sign = Help::sign($data, $key, $sign_type);
if ($sign != $_sign) { if ($sign != $_sign) {
return FALSE; return FALSE;
} }
return $data; return $data;
} }
/**
* @param string $requestUrl
* @param mixed $body
* @return Result
*/
protected function post(string $requestUrl, mixed $body): Result
{
return $this->request('post', $requestUrl, $body);
}
/**
* @param string $requestUrl
* @param mixed $body
* @return Result
*/
protected function get(string $requestUrl, mixed $body): Result
{
return $this->request('get', $requestUrl, $body);
}
/**
* @param string $requestUrl
* @param mixed $body
* @return Result
*/
protected function upload(string $requestUrl, mixed $body): Result
{
return $this->request('upload', $requestUrl, $body);
}
/**
* @param string $method
* @param string $requestUrl
* @param $body
* @return Result
*/
private function request(string $method, string $requestUrl, $body): Result
{
$client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
if ($method == 'post') {
$client->post($requestUrl, $body);
} else if ($method == 'upload') {
$client->upload($requestUrl, $body);
} else {
$client->get($requestUrl, $body);
}
$client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) {
return new Result(code: 505, message: $client->getBody());
}
$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());
}
}
} }
+137 -187
View File
@@ -9,204 +9,154 @@
namespace wchat\wx; namespace wchat\wx;
use Exception; use Exception;
use Kiri\Client;
use wchat\common\Decode; use wchat\common\Decode;
use wchat\common\HttpClient;
use wchat\common\Result; use wchat\common\Result;
class Account extends SmallProgram class Account extends SmallProgram
{ {
/** /**
* @param $code * @param $code
* @return Result * @return Result
*/ */
public function login($code): Result public function login($code): Result
{ {
$param['appid'] = $this->config->getAppid(); $param['appid'] = $this->payConfig->appId;
$param['secret'] = $this->config->getAppsecret(); $param['secret'] = $this->payConfig->appSecret;
$param['js_code'] = $code; $param['js_code'] = $code;
$param['grant_type'] = 'authorization_code'; $param['grant_type'] = 'authorization_code';
$client = new Client('api.weixin.qq.com', 443, true); return $this->get('/sns/jscode2session', $param);
$client->withHeader(['Content-Type' => 'application/json']); }
if (!empty($this->getConfig()->getProxyHost()) && $this->getConfig()->getProxyPort() > 0) {
$client->withProxyHost("192.168.0.57")->withProxyPort(12286); /**
* @param $code
* @return Result
*/
public function AppLogin($code): Result
{
$param['appid'] = $this->payConfig->pay->wx->appId;
$param['secret'] = $this->payConfig->pay->wx->appSecret;
$param['js_code'] = $code;
$param['grant_type'] = 'authorization_code';
return $this->get('/sns/oauth2/access_token', $param);
}
/**
* @param $openid
* @return Result
* @throws Exception
*/
public function getPublicUserInfo($openid): Result
{
$query = [
'access_token' => $this->payConfig->getAccessToken(),
'openid' => $openid,
'lang' => 'zh_CN'
];
return $this->get('/cgi-bin/user/info', $query);
}
/**
* @param $openid
* @return Result
* @throws Exception
*/
public function getAppUserInfo($openid): Result
{
$query = [
'access_token' => $this->payConfig->getAccessToken(),
'openid' => $openid,
];
return $this->get('/sns/userinfo', $query);
}
/**
* @param $encryptedData
* @param $iv
* @param $sessionKey
* @param bool $asArray
* @return object|array
* @throws
*
* * <li>-41001: encodingAesKey 非法</li>
* <li>-41003: aes 解密失败</li>
* <li>-41004: 解密后得到的buffer非法</li>
* <li>-41005: base64加密失败</li>
* <li>-41016: base64解密失败</li>
*/
public function decode($encryptedData, $iv, $sessionKey, bool $asArray = false): object|array
{
$decode = new Decode();
$decode->setSessionKey($sessionKey);
$decode->setEncryptedData($encryptedData);
$decode->setAppId($this->payConfig->getAppid());
$decode->setIv($iv);
return $decode->decode($asArray);
}
/**
* @param $path
* @param $width
* @return array|mixed|Result
* @throws Exception
*/
public function createwxaqrcode($path, $width): mixed
{
$url = 'cgi-bin/wxaapp/createwxaqrcode?access_token=';
$sendBody['path'] = $path;
$sendBody['width'] = $width;
return $this->get($url . $this->payConfig->getAccessToken(), $sendBody);
}
/**
* @param $path
* @param $width
* @param bool $is_hyaline
* @param bool $auto_color
* @param string $line_color
* @return Result
*/
public function getwxacode($path, $width, bool $is_hyaline = false, bool $auto_color = false, string $line_color = ''): Result
{
$sendBody['path'] = $path;
$sendBody['width'] = $width;
$sendBody['auto_color'] = $auto_color;
$sendBody['is_hyaline'] = $is_hyaline;
$url = 'wxa/getwxacode?access_token=' . $this->getConfig()->getAccessToken();
if ($auto_color) {
$sendBody['line_color'] = $line_color;
} }
$client->get('sns/jscode2session', $param); return $this->get($url . $this->payConfig->getAccessToken(), $sendBody);
$client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) { }
return new Result(code: 505, message: $client->getBody());
}
$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 Result
* @throws Exception
*/
public function getPublicUserInfo($openid): Result
{
$query = [
'access_token' => $this->config->getAccessToken(),
'openid' => $openid,
'lang' => 'zh_CN'
];
$client = new Client('api.weixin.qq.com', 443, true); /**
$client->withHeader(['Content-Type' => 'application/json']); * @param $path
if (!empty($this->getConfig()->getProxyHost()) && $this->getConfig()->getProxyPort() > 0) { * @param $width
$client->withProxyHost("192.168.0.57")->withProxyPort(12286); * @param bool $is_hyaline
* @param bool $auto_color
* @param string $line_color
* @return Result
*/
public function getwxacodeunlimit($path, $width, bool $is_hyaline = false, bool $auto_color = false, string $line_color = ''): Result
{
$sendBody['path'] = $path;
$sendBody['width'] = $width;
$sendBody['auto_color'] = $auto_color;
$sendBody['is_hyaline'] = $is_hyaline;
$url = 'wxa/getwxacodeunlimit?access_token=' . $this->getConfig()->getAccessToken();
if ($auto_color) {
$sendBody['line_color'] = $line_color;
} }
$client->get('cgi-bin/user/info', $query); return $this->get($url . $this->payConfig->getAccessToken(), $sendBody);
$client->close(); }
if (!in_array($client->getStatusCode(), [101, 200, 201])) {
return new Result(code: 505, message: $client->getBody());
}
$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 $encryptedData
* @param $iv
* @param $sessionKey
* @param bool $asArray
* @return object|array
* @throws
*
* * <li>-41001: encodingAesKey 非法</li>
* <li>-41003: aes 解密失败</li>
* <li>-41004: 解密后得到的buffer非法</li>
* <li>-41005: base64加密失败</li>
* <li>-41016: base64解密失败</li>
*/
public function decode($encryptedData, $iv, $sessionKey, bool $asArray = false): object|array
{
$decode = new Decode();
$decode->setSessionKey($sessionKey);
$decode->setEncryptedData($encryptedData);
$decode->setAppId($this->config->getAppid());
$decode->setIv($iv);
return $decode->decode($asArray);
}
/**
* @param $path
* @param $width
* @return array|mixed|Result
* @throws Exception
*/
public function createwxaqrcode($path, $width): mixed
{
$url = 'cgi-bin/wxaapp/createwxaqrcode?access_token=';
$sendBody['path'] = $path;
$sendBody['width'] = $width;
$client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($url . $this->getConfig()->getAccessToken(), $sendBody);
$client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) {
return new Result(code: 505, message: $client->getBody());
}
$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());
}
}
/**
* @param $path
* @param $width
* @param bool $is_hyaline
* @param bool $auto_color
* @param string $line_color
* @return Result
*/
public function getwxacode($path, $width, bool $is_hyaline = false, bool $auto_color = false, string $line_color = ''): Result
{
$sendBody['path'] = $path;
$sendBody['width'] = $width;
$sendBody['auto_color'] = $auto_color;
$sendBody['is_hyaline'] = $is_hyaline;
if ($auto_color) {
$sendBody['line_color'] = $line_color;
}
$url = 'wxa/getwxacode?access_token=' . $this->getConfig()->getAccessToken();
$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: $client->getBody());
}
$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());
}
}
/**
* @param $path
* @param $width
* @param bool $is_hyaline
* @param bool $auto_color
* @param string $line_color
* @return Result
*/
public function getwxacodeunlimit($path, $width, bool $is_hyaline = false, bool $auto_color = false, string $line_color = ''): Result
{
$sendBody['path'] = $path;
$sendBody['width'] = $width;
$sendBody['auto_color'] = $auto_color;
$sendBody['is_hyaline'] = $is_hyaline;
if ($auto_color) {
$sendBody['line_color'] = $line_color;
}
$url = 'wxa/getwxacodeunlimit?access_token=' . $this->getConfig()->getAccessToken();
$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: $client->getBody());
}
$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());
}
}
} }
+234 -281
View File
@@ -15,311 +15,264 @@ use wchat\common\Result;
class Message extends SmallProgram class Message extends SmallProgram
{ {
private array $msgData = []; private array $msgData = [];
/** /**
* @param $openid * @param $openid
*/ */
public function setOpenid($openid) public function setOpenid($openid)
{ {
$this->msgData['touser'] = $openid; $this->msgData['touser'] = $openid;
} }
/** /**
* @param $content * @param $content
* @return Result * @return Result
* @throws Exception * @throws Exception
*/ */
public function sendTextNews($content): Result public function sendTextNews($content): Result
{ {
$this->msgData['msgtype'] = 'text'; $this->msgData['msgtype'] = 'text';
$this->msgData['text'] = ['content' => $content]; $this->msgData['text'] = ['content' => $content];
return $this->sendKefuMsg(); return $this->sendKefuMsg();
} }
/** /**
* @param $media_id * @param $media_id
* @return Result * @return Result
* @throws Exception * @throws Exception
*/ */
public function sendImageNews($media_id): Result public function sendImageNews($media_id): Result
{ {
$this->msgData['msgtype'] = 'image'; $this->msgData['msgtype'] = 'image';
$this->msgData['image'] = ['media_id' => $media_id]; $this->msgData['image'] = ['media_id' => $media_id];
return $this->sendKefuMsg(); return $this->sendKefuMsg();
} }
/** /**
* @param $media_id * @param $media_id
* @return Result * @return Result
* @throws Exception * @throws Exception
*/ */
public function sendVoiceNews($media_id): Result public function sendVoiceNews($media_id): Result
{ {
$this->msgData['msgtype'] = 'voice'; $this->msgData['msgtype'] = 'voice';
$this->msgData['voice'] = ['media_id' => $media_id]; $this->msgData['voice'] = ['media_id' => $media_id];
return $this->sendKefuMsg(); return $this->sendKefuMsg();
} }
/** /**
* @param $media_id * @param $media_id
* @return Result * @return Result
* @throws Exception * @throws Exception
*/ */
public function sendMpNewsNews($media_id): Result public function sendMpNewsNews($media_id): Result
{ {
$this->msgData['msgtype'] = 'mpnews'; $this->msgData['msgtype'] = 'mpnews';
$this->msgData['mpnews'] = ['media_id' => $media_id]; $this->msgData['mpnews'] = ['media_id' => $media_id];
return $this->sendKefuMsg(); return $this->sendKefuMsg();
} }
/** /**
* @param $title * @param $title
* @param $description * @param $description
* @param $url * @param $url
* @param $picurl * @param $picurl
* @return Result * @return Result
* @throws Exception * @throws Exception
*/ */
public function sendNewsNews($title, $description, $url, $picurl): Result public function sendNewsNews($title, $description, $url, $picurl): Result
{ {
$this->msgData['msgtype'] = 'news'; $this->msgData['msgtype'] = 'news';
$this->msgData['news'] = [ $this->msgData['news'] = [
'articles' => [ 'articles' => [
[ [
'title' => $title, 'title' => $title,
'description' => $description, 'description' => $description,
'url' => $url, 'url' => $url,
'picurl' => $picurl 'picurl' => $picurl
] ]
] ]
]; ];
return $this->sendKefuMsg(); return $this->sendKefuMsg();
} }
/** /**
* @param $title * @param $title
* @return Result * @return Result
* @throws Exception * @throws Exception
*/ */
public function sendCardNews($title): Result public function sendCardNews($title): Result
{ {
$this->msgData['msgtype'] = 'wxcard'; $this->msgData['msgtype'] = 'wxcard';
$this->msgData['wxcard'] = ['card_id' => $title]; $this->msgData['wxcard'] = ['card_id' => $title];
return $this->sendKefuMsg(); return $this->sendKefuMsg();
} }
/** /**
* @param $media_id * @param $media_id
* @param $thumb_media_id * @param $thumb_media_id
* @param $title * @param $title
* @param $description * @param $description
* @return Result * @return Result
* @throws Exception * @throws Exception
*/ */
public function sendVideoNews($media_id, $thumb_media_id, $title, $description): Result public function sendVideoNews($media_id, $thumb_media_id, $title, $description): Result
{ {
$this->msgData['msgtype'] = 'video'; $this->msgData['msgtype'] = 'video';
$this->msgData['video'] = [ $this->msgData['video'] = [
'media_id' => [ 'media_id' => [
'media_id' => $media_id, 'media_id' => $media_id,
'thumb_media_id' => $thumb_media_id, 'thumb_media_id' => $thumb_media_id,
'title' => $title, 'title' => $title,
'description' => $description 'description' => $description
] ]
]; ];
return $this->sendKefuMsg(); return $this->sendKefuMsg();
} }
/** /**
* @param $musicurl * @param $musicurl
* @param $hqmusicurl * @param $hqmusicurl
* @param $thumb_media_id * @param $thumb_media_id
* @param $title * @param $title
* @param $description * @param $description
* @return Result * @return Result
* @throws Exception * @throws Exception
*/ */
public function sendMusicNews($musicurl, $hqmusicurl, $thumb_media_id, $title, $description): Result public function sendMusicNews($musicurl, $hqmusicurl, $thumb_media_id, $title, $description): Result
{ {
$this->msgData['msgtype'] = 'music'; $this->msgData['msgtype'] = 'music';
$this->msgData['music'] = [ $this->msgData['music'] = [
'title' => $title, 'title' => $title,
'description' => $description, 'description' => $description,
'musicurl' => $musicurl, 'musicurl' => $musicurl,
'hqmusicurl' => $hqmusicurl, 'hqmusicurl' => $hqmusicurl,
'thumb_media_id' => $thumb_media_id 'thumb_media_id' => $thumb_media_id
]; ];
return $this->sendKefuMsg(); return $this->sendKefuMsg();
} }
/** /**
* @param $head_content * @param $head_content
* @param $tail_content * @param $tail_content
* @param array $menus * @param array $menus
* @return Result * @return Result
* @throws Exception * @throws Exception
*/ */
public function sendMenuNews($head_content, $tail_content, array $menus = []): Result public function sendMenuNews($head_content, $tail_content, array $menus = []): Result
{ {
$this->msgData['msgtype'] = 'msgmenu'; $this->msgData['msgtype'] = 'msgmenu';
$this->msgData['msgmenu'] = [ $this->msgData['msgmenu'] = [
'head_content' => $head_content, 'head_content' => $head_content,
'tail_content' => $tail_content, 'tail_content' => $tail_content,
]; ];
if (empty($menus) || !is_array($menus) || count($menus) < 2) { if (empty($menus) || !is_array($menus) || count($menus) < 2) {
throw new Exception('菜单选项必须有2个'); throw new Exception('菜单选项必须有2个');
}
foreach ($menus as $val) {
$this->addNewsMenu($val['id'], $val['name']);
}
return $this->sendKefuMsg();
}
private int $index = 0;
/**
* @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): 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 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('暂不支持的文件类型');
}
$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);
$real_path = new \CURLFile(realpath($filePath));
$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];
}
$client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'multipart/form-data']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
} }
$client->post($url, $data); foreach ($menus as $val) {
$client->close(); $this->addNewsMenu($val['id'], $val['name']);
$this->msgData = [];
if (!in_array($client->getStatusCode(), [101, 200, 201])) {
return new Result(code: 505, message: $client->getBody());
}
$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(): array
{
return $this->msgData;
}
/**
* @return Result
* @throws Exception
*/
private function sendKefuMsg()
{
$url = '/cgi-bin/message/custom/send?access_token=' . $this->config->getAccessToken();
$client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
} }
$client->post($url, $this->msgData); return $this->sendKefuMsg();
$client->close(); }
$this->msgData = []; private int $index = 0;
if (!in_array($client->getStatusCode(), [101, 200, 201])) { /**
return new Result(code: 505, message: $client->getBody()); * @param $id
} * @param $menuName
$body = json_decode($client->getBody(), true); * @return $this
if (isset($body['errcode']) && $body['errcode'] != 0) { */
return new Result(code: $body['errcode'], message: $body['errmsg']); public function addNewsMenu($id, $menuName): static
} else { {
return new Result(code: 0, data: $body); $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): 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 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('暂不支持的文件类型');
}
$token = $this->payConfig->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);
$real_path = new \CURLFile(realpath($filePath));
$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];
}
return $this->post($url, $data);
}
/**
* @return array
*/
public function getContents(): array
{
return $this->msgData;
}
/**
* @return Result
* @throws Exception
*/
private function sendKefuMsg()
{
$url = '/cgi-bin/message/custom/send?access_token=' . $this->payConfig->getAccessToken();
return $this->post($url, $this->msgData);
}
} }
+2 -2
View File
@@ -93,8 +93,8 @@ class Notify extends SmallProgram
$sign = $params['sign']; $sign = $params['sign'];
unset($params['sign']); unset($params['sign']);
$signType = $this->config->getSignType(); $signType = $this->payConfig->getSignType();
$privateKey = $this->config->getKey(); $privateKey = $this->payConfig->getKey();
$nowSign = Help::sign($params, $privateKey, $signType); $nowSign = Help::sign($params, $privateKey, $signType);
if ($sign === $nowSign) { if ($sign === $nowSign) {
return true; return true;
+121 -142
View File
@@ -14,156 +14,135 @@ use wchat\common\Result;
class PublicTemplate extends SmallProgram class PublicTemplate extends SmallProgram
{ {
private array $keywords = []; private array $keywords = [];
private string $templateId = ''; private string $templateId = '';
private array $first = []; private array $first = [];
private array $remark = []; private array $remark = [];
private string $openId = ''; private string $openId = '';
private string $defaultUrl = 'http://weixin.qq.com/download'; private string $defaultUrl = 'http://weixin.qq.com/download';
private string $sendUrl = '/cgi-bin/message/template/send'; private string $sendUrl = '/cgi-bin/message/template/send';
private array $miniprogram = []; private array $miniprogram = [];
/** /**
* @param array $keywords * @param array $keywords
*/ */
public function setKeywords(array $keywords) public function setKeywords(array $keywords)
{ {
$this->keywords = $keywords; $this->keywords = $keywords;
} }
/** /**
* @param $templateId * @param $templateId
*/ */
public function setTemplateId($templateId) public function setTemplateId($templateId)
{ {
$this->templateId = $templateId; $this->templateId = $templateId;
} }
/** /**
* @param $openId * @param $openId
*/ */
public function setOpenId($openId) public function setOpenId($openId)
{ {
$this->openId = $openId; $this->openId = $openId;
} }
/** /**
* @param $defaultUrl * @param $defaultUrl
*/ */
public function setDefaultUrl($defaultUrl) public function setDefaultUrl($defaultUrl)
{ {
$this->defaultUrl = $defaultUrl; $this->defaultUrl = $defaultUrl;
} }
/** /**
* @param $name * @param $name
* @param $context * @param $context
* @param string $color * @param string $color
*/ */
public function replaceKeyword($name, $context, string $color = '') public function replaceKeyword($name, $context, string $color = '')
{ {
$this->keywords[$name] = ['value' => $context, 'color' => $color]; $this->keywords[$name] = ['value' => $context, 'color' => $color];
} }
/** /**
* @param $name * @param $name
* @param $context * @param $context
* @param null $color * @param null $color
*/ */
public function addKeyword($name, $context, $color = null) public function addKeyword($name, $context, $color = null)
{ {
if (empty($color)) { if (empty($color)) {
$color = '#000'; $color = '#000';
}
$this->keywords[$name] = [
'value' => $context,
'color' => $color
];
}
/**
* @param $context
* @param string $color
* @return void
*/
public function setFirst($context, string $color = '#f00'): void
{
$this->first = [
'value' => $context,
'color' => $color
];
}
/**
* @param $context
* @param string $color
* @return void
*/
public function setRemark($context, string $color = '#000'): void
{
$this->remark = [
'value' => $context,
'color' => $color
];
}
/**
* @param $appid
* @param string $pagepath
* @return void
*/
public function setMiniprogram($appid, string $pagepath): void
{
$this->miniprogram = [
'appid' => $appid,
'pagepath' => $pagepath
];
}
/**
* @return Result
* @throws \Exception
*
* 奴隶交易通知
*/
public function sendTemplate(): Result
{
$url = $this->sendUrl . '?access_token=' . $this->config->getAccessToken();
$keywords = $this->keywords;
$keywords['first'] = $this->first;
$keywords['remark'] = $this->remark;
$default = [
"touser" => $this->openId,
"template_id" => $this->templateId,
"url" => $this->defaultUrl,
"data" => $keywords,
];
if (!empty($this->miniprogram)) {
$default['miniprogram'] = $this->miniprogram;
}
$client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
} }
$client->post($url, $default); $this->keywords[$name] = [
$client->close(); 'value' => $context,
'color' => $color
];
}
if (!in_array($client->getStatusCode(), [101, 200, 201])) { /**
return new Result(code: 505, message: $client->getBody()); * @param $context
} * @param string $color
$body = json_decode($client->getBody(), true); * @return void
if (isset($body['errcode']) && $body['errcode'] != 0) { */
return new Result(code: $body['errcode'], message: $body['errmsg']); public function setFirst($context, string $color = '#f00'): void
} else { {
return new Result(code: 0, data: $body); $this->first = [
} 'value' => $context,
} 'color' => $color
];
}
/**
* @param $context
* @param string $color
* @return void
*/
public function setRemark($context, string $color = '#000'): void
{
$this->remark = [
'value' => $context,
'color' => $color
];
}
/**
* @param $appid
* @param string $pagepath
* @return void
*/
public function setMiniprogram($appid, string $pagepath): void
{
$this->miniprogram = [
'appid' => $appid,
'pagepath' => $pagepath
];
}
/**
* @return Result
* @throws \Exception
*
* 奴隶交易通知
*/
public function sendTemplate(): Result
{
$url = $this->sendUrl . '?access_token=' . $this->payConfig->getAccessToken();
$keywords = $this->keywords;
$keywords['first'] = $this->first;
$keywords['remark'] = $this->remark;
$default = [
"touser" => $this->openId,
"template_id" => $this->templateId,
"url" => $this->defaultUrl,
"data" => $keywords,
];
if (!empty($this->miniprogram)) {
$default['miniprogram'] = $this->miniprogram;
}
return $this->post($url, $default);
}
} }
+50 -105
View File
@@ -14,123 +14,68 @@ use wchat\common\Result;
class SecCheck extends SmallProgram class SecCheck extends SmallProgram
{ {
private string $_url = '/wxa/img_sec_check?access_token='; private string $_url = '/wxa/img_sec_check?access_token=';
private string $_msgUrl = '/wxa/msg_sec_check?access_token=';
private string $_mediaCheckAsync = '/wxa/media_check_async?access_token=';
const MEDIA_VIDEO = 1;
const MEDIA_IMAGE = 1;
private string $_msgUrl = '/wxa/msg_sec_check?access_token='; /**
* @param string $path
private string $_mediaCheckAsync = '/wxa/media_check_async?access_token='; * @return Result
*/
const MEDIA_VIDEO = 1; public function image(string $path = ''): Result
const MEDIA_IMAGE = 1; {
if (!file_exists($path)) {
/** return $this->sendError('文件不存在', 404);
* @param string $path
* @return Result
*/
public function image(string $path = ''): Result
{
if (!file_exists($path)) {
return $this->sendError('文件不存在', 404);
}
$access_token = $this->config->getAccessToken();
$client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'multipart/form-data']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
} }
$client->upload($this->_url . '?access_token=' . $access_token, [ $access_token = $this->payConfig->getAccessToken();
'media' => new \CURLFile($path)
]);
$client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) { return $this->upload($this->_url . '?access_token=' . $access_token, [
return new Result(code: 505, message: $client->getBody()); 'media' => new \CURLFile($path)
} ]);
$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 string $url * @param string $url
* @param int $type * @param int $type
* @return mixed * @return mixed
* @throws * @throws
*/ */
public function mediaAsync(string $url, int $type = SecCheck::MEDIA_IMAGE): Result public function mediaAsync(string $url, int $type = SecCheck::MEDIA_IMAGE): Result
{ {
if (!in_array($type, [self::MEDIA_IMAGE, self::MEDIA_VIDEO])) { if (!in_array($type, [self::MEDIA_IMAGE, self::MEDIA_VIDEO])) {
throw new \Exception('暂不支持的文件类型'); throw new \Exception('暂不支持的文件类型');
}
$requestUrl = $this->_mediaCheckAsync . $this->config->getAccessToken();
$client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
} }
$client->post($requestUrl, ['media_url' => $url, 'media_type' => $type]); $requestUrl = $this->_mediaCheckAsync . $this->payConfig->getAccessToken();
$client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) { return $this->post($requestUrl, ['media_url' => $url, 'media_type' => $type]);
return new Result(code: 505, message: $client->getBody()); }
}
$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 $params * @param $params
* @return ContentAsyncCheck|null * @return ContentAsyncCheck|null
*/ */
public function readByEvent($params): ?ContentAsyncCheck public function readByEvent($params): ?ContentAsyncCheck
{ {
return ContentAsyncCheck::instance($params); return ContentAsyncCheck::instance($params);
} }
/** /**
* @param $content * @param $content
* @return Result * @return Result
*/ */
public function text($content): Result public function text($content): Result
{ {
if (empty($content)) { if (empty($content)) {
return $this->sendError('文件不存在', 404); return $this->sendError('文件不存在', 404);
}
$requestUrl = $this->_msgUrl . $this->config->getAccessToken();
$client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
} }
$client->post($requestUrl, ['content' => $content]); $requestUrl = $this->_msgUrl . $this->payConfig->getAccessToken();
$client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) { return $this->post($requestUrl, ['content' => $content]);
return new Result(code: 505, message: $client->getBody()); }
}
$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);
}
}
} }
+14 -27
View File
@@ -10,34 +10,21 @@ use wchat\common\Result;
class Token extends SmallProgram class Token extends SmallProgram
{ {
/** /**
* @return Result * @return Result
*/ */
public function token(): Result public function token(): Result
{ {
$query = [ $query = ['grant_type' => 'client_credential'];
'grant_type' => 'client_credential', if ($this->payConfig->typeIsApp()) {
'appid' => $this->config->getAppid(), $query['appid'] = $this->payConfig->pay->wx->appId;
'secret' => $this->config->getAppsecret() $query['secret'] = $this->payConfig->pay->wx->appSecret;
]; } else {
$client = new Client('api.weixin.qq.com', 443, true); $query['appid'] = $this->payConfig->appId;
$client->withHeader(['Content-Type' => 'application/json']); $query['secret'] = $this->payConfig->appSecret;
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
} }
$client->get('cgi-bin/token', $query); return $this->get('cgi-bin/token', $query);
$client->close(); }
if (!in_array($client->getStatusCode(), [101, 200, 201])) {
return new Result(code: 505, message: $client->getBody());
}
$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);
}
} }
-77
View File
@@ -1,77 +0,0 @@
<?php
namespace wchat\wx\V2;
use Kiri\Client;
use wchat\common\Help;
use wchat\common\Result;
use wchat\wx\SmallProgram;
class WxV2AppPayment extends SmallProgram
{
private string $uniformed = '/pay/unifiedorder';
use WxV2PayTait;
/**
* @param int $money
* @param string $orderNo
* @param string $spbill_create_ip
* @return Result
*/
public function payment(int $money, string $orderNo, 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'] = 'APP';
$body['spbill_create_ip'] = $spbill_create_ip;
$client = new Client('api.mch.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$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: $client->getBody());
}
$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()
]);
}
}
-230
View File
@@ -1,230 +0,0 @@
<?php
namespace wchat\wx\V2;
use Kiri\Client;
use Phalcon\Cache\Frontend\Json;
use wchat\common\Help;
use wchat\common\Result;
use wchat\wx\SmallProgram;
class WxV2PayJsApi extends SmallProgram
{
private string $uniformed = '/pay/unifiedorder';
use WxV2PayTait;
/**
* @param int $money
* @param string $orderNo
* @param string $openId
* @param string $spbill_create_ip
* @return Result
*/
public function applet(int $money, string $orderNo, string $openId, 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'] = '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));
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->uniformed);
$client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) {
return new Result(code: 505, message: $client->getBody());
}
$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));
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->uniformed);
$client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) {
return new Result(code: 505, message: $client->getBody());
}
$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));
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->uniformed);
$client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) {
return new Result(code: 505, message: $client->getBody());
}
$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));
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->uniformed);
$client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) {
return new Result(code: 505, message: $client->getBody());
}
$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()
]);
}
}
-100
View File
@@ -1,100 +0,0 @@
<?php
namespace wchat\wx\V2;
use JetBrains\PhpStorm\ArrayShape;
use wchat\common\Help;
trait WxV2PayTait
{
/**
* 'appId' => $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);
}
}
-67
View File
@@ -1,67 +0,0 @@
<?php
namespace wchat\wx\V2;
use Kiri\Client;
use wchat\common\Help;
use wchat\common\Result;
use wchat\wx\SmallProgram;
class WxV2Withdrawal extends SmallProgram
{
private string $transfers = '/mmpaymkttransfers/promotion/transfers';
/**
* @param int|float $money
* @param string $openid
* @param string $order
* @param string $desc
* @return Result
*/
public function payment(int|float $money, string $openid, string $order, string $desc = '零钱提现'): Result
{
$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);
$client = new Client('api.mch.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']);
$client->withBody($body = Help::toXml($array));
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->transfers);
$client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) {
return new Result(code: 505, message: $client->getBody());
}
$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);
}
}
}