From 6f056b4e0394de2b1363c4fc67c688a3923541d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=8A=80=E6=9C=AF=E8=80=81=E8=83=A1?= <1094551889@qq.com> Date: Mon, 25 Nov 2024 07:56:16 +0000 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6=20extend/p?= =?UTF-8?q?ayclient?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/payclient/PayClass.php | 208 -------------------------------- extend/payclient/ShouQianBa.php | 193 ----------------------------- extend/payclient/payclient.zip | Bin 17868 -> 0 bytes 3 files changed, 401 deletions(-) delete mode 100644 extend/payclient/PayClass.php delete mode 100644 extend/payclient/ShouQianBa.php delete mode 100644 extend/payclient/payclient.zip diff --git a/extend/payclient/PayClass.php b/extend/payclient/PayClass.php deleted file mode 100644 index 74028af..0000000 --- a/extend/payclient/PayClass.php +++ /dev/null @@ -1,208 +0,0 @@ -username = $config['username']; - $this->password = $config['password']; - $this->now = time(); - // 检查token/cookie目录 - $dir_path = runtime_path() . "token/{$this->pay_type}/"; - if (!is_dir($dir_path)) { - if (!mkdir($dir_path, 755, true)) echo '创建token/cookie目录失败'; - } - // token/cookie文件路径 - $this->token_path = $dir_path . md5($this->username . $this->password . __CLASS__) . '.json'; - $this->cookie_path = $dir_path . md5($this->username . $this->password . __CLASS__) . '.txt'; - // 检查token文件 - if (!file_exists($this->token_path)) { - file_put_contents($this->token_path, json_encode(['token' => 'ok', 'update_time' => date('Y-m-d H:i:s')])); - } - } - // 获取订单信息 - public function getOrderInfo(array $query): array - { - $order_list = $this->queryOrder($query); - $orders = []; - if (!$order_list) return $orders; - $payways = ['ALI' => 'alipay', 'WECHAT' => 'wxpay']; - foreach ($order_list as $value) { - $order = []; - // 平台订单流水号 - $order['order_no'] = $value['tranAcpBsNo']; - // 支付类型 - $order['payway'] = $payways[$value['tranChannelType']]; - // 收款金额 - $order['price'] = (float)$value['tranOrdAmt']; - // 收款渠道(二维码编号) - $order['channel'] = $value['bsShopCode']; - // 添加到订单列表 - $orders[] = $order; - } - return $orders; - } - // 查询订单 - private function queryOrder(array $query, $times = 0): array - { - // 查询订单列表 - $url = $this->payhost . $this->order_query_path; - $token = $this->getToken(); - $header = ['Host:xym.ysepay.com', 'token:' . $token]; - $new_query = $this->getOrderQuery($query); - $res = $this->getHttpResponse($url . '?' . http_build_query($new_query), $header, json_encode($new_query)); - $result = json_decode($res, true); - // 检查订单信息 - $order_list = []; - if ($result['code'] === 0) { - $order_list = $result['data']['list']; - } else { - // 重试3次 - if ($times < 3) { - $this->updateToken(); - $order_list = $this->queryOrder($query, $times + 1); - } - } - return $order_list; - } - // 构建订单查询数组信息 - private function getOrderQuery(array $query): array - { - $new_query = $query; - $now = $this->now; - $startTime = date('Y-m-d H:i:s', $now - 175); - $endTime = date('Y-m-d H:i:s', $now); - $new_query['queryStartTime'] = $startTime; - $new_query['queryEndTime'] = $endTime; - $new_query['time'] = $now . mt_rand(100, 999); - return $new_query; - } - // 获取验证码图像 - private function getCaptcha(): array - { - $url = $this->payhost . $this->captcha_path . '?time=' . $this->now . mt_rand(100, 999); - $header = ['Host:xym.ysepay.com']; - $res = $this->getHttpResponse($url, $header); - $data = json_decode($res, true); - $captcha_info = []; - if ($data['code'] === 0) { - $captcha_info['randomCodeBase64'] = $data['data']['randomCodeBase64']; - $captcha_info['uuid'] = $data['data']['uuid']; - } - return $captcha_info; - } - // 登陆账号 - private function login($times = 0): bool - { - $captcha_info = $this->getCaptcha(); - $captcha = $this->getCaptchaInfo($captcha_info['randomCodeBase64']); - $url = $this->payhost . $this->login_path; - $user_info = [ - 'loginName' => $this->username, - 'password' => $this->password, - 'randomCode' => $captcha, - 'uuid' => $captcha_info['uuid'], - 'time' => (int)($this->now . mt_rand(100, 999)) - ]; - $header = ['Host:xym.ysepay.com']; - $res = $this->getHttpResponse($url, $header, json_encode($user_info)); - $data = json_decode($res, true); - if ($data['code'] === 0) { - // 如何需要,就保存token - $this->saveToken($data['data']); - return true; - } else { - // 重试3次 - $is_login = false; - if ($times < 3) { - $is_login = $this->login($times + 1); - return $is_login; - } - return $is_login; - } - } - // 更新token - private function updateToken(): bool - { - $is_login = $this->login(); - return $is_login; - } - - // 获取token - private function getToken(): string - { - $token_info = json_decode(file_get_contents($this->token_path), true); - return $token_info['token']; - } - // 保存token - private function saveToken($data) - { - $token = $data['token']; - file_put_contents($this->token_path, json_encode(['token' => $token, 'update_time' => date('Y-m-d H:i:s')])); - } - // 解析验证码 - private function getCaptchaInfo(string $image = '', string $typeid = '3'): string - { - $api_url = 'http://api.ttshitu.com/predict'; - $info = ['username' => '2679275057', 'password' => '7698177hcnTJ', 'typeid' => $typeid, 'image' => $image]; - $res = $this->getHttpResponse($api_url, [], json_encode($info)); - $data = json_decode($res, true); - $captcha = ''; - if ($data['success'] === true) { - $captcha = $data['data']['result']; - } - return $captcha; - } - // 请求外部资源 - private function getHttpResponse($url, $header = [], $post = null, $timeout = 10) - { - $ch = curl_init($url); - curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); - curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookie_path); - curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookie_path); - if ($header) { - curl_setopt($ch, CURLOPT_HTTPHEADER, $header); - } else { - $httpheader[] = "Accept: */*"; - $httpheader[] = "Accept-Language: zh-CN,zh;q=0.9"; - $httpheader[] = "Connection: close"; - curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader); - } - curl_setopt($ch, CURLOPT_HEADER, false); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - if ($post) { - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $post); - } - $response = curl_exec($ch); - curl_close($ch); - return $response; - } -} diff --git a/extend/payclient/ShouQianBa.php b/extend/payclient/ShouQianBa.php deleted file mode 100644 index 10f4141..0000000 --- a/extend/payclient/ShouQianBa.php +++ /dev/null @@ -1,193 +0,0 @@ -username = $config['username']; - $this->password = md5($config['password']); - $this->now = time(); - // 检查token/cookie目录 - $dir_path = runtime_path() . "token/{$this->pay_type}/"; - if (!is_dir($dir_path)) { - if (!mkdir($dir_path, 755, true)) echo '创建token/cookie目录失败'; - } - // token/cookie文件路径 - $this->token_path = $dir_path . md5($this->username . $this->password . __CLASS__) . '.json'; - $this->cookie_path = $dir_path . md5($this->username . $this->password . __CLASS__) . '.txt'; - // 检查token文件 - if (!file_exists($this->token_path)) { - file_put_contents($this->token_path, json_encode(['token' => 'ok', 'update_time' => date('Y-m-d H:i:s')])); - } - } - // 获取订单信息 - public function getOrderInfo(array $query): array - { - $order_list = $this->queryOrder($query); - $orders = []; - if (!$order_list) return $orders; - $payways = [2 => 'alipay', 3 => 'wxpay']; - foreach ($order_list as $value) { - $order = []; - // 平台订单流水号 - $order['order_no'] = $value['order_sn']; - // 支付类型 - $order['payway'] = $payways[$value['payway']]; - // 收款金额 - $order['price'] = (float)($value['original_amount'] / 100); - // 收款渠道(二维码编号) - $order['channel'] = $value['terminal_device_fingerprint']; - // 添加到订单列表 - $orders[] = $order; - } - return $orders; - } - // 查询订单 - private function queryOrder(array $query, $times = 0): array - { - // 查询订单列表 - $token = $this->getToken(); - $url = $this->payhost . $this->order_query_path . '?client_version=7.0.0&token=' . $token; - $header = ['Content-Type: application/json;charset=UTF-8']; - $new_query = $this->getOrderQuery($query); - $res = $this->getHttpResponse($url, $header, json_encode($new_query)); - $result = json_decode($res, true); - // 检查订单信息 - $order_list = []; - if ($result['code'] === 50000) { - $order_list = $result['data']['records']; - } else { - // 重试1次 - if ($times < 1) { - $this->updateToken(); - $order_list = $this->queryOrder($query, $times + 1); - } - } - return $order_list; - } - // 构建订单查询数组信息 - private function getOrderQuery(array $query): array - { - $new_query = $query; - $now = $this->now; - $begin_time = (int)(($now - 175) . '000'); - $end_time = (int)($now . '999'); - $new_query['date_start'] = $begin_time; - $new_query['date_end'] = $end_time; - return $new_query; - } - // 登陆账号 - private function login($times = 0): bool - { - $url = $this->payhost . $this->login_path; - $user_info = [ - "username" => $this->username, - "password" => $this->password, - "uc_device" => [ - "device_type" => 2, - "default_device" => 0, - "platform" => "商户服务平台", - "device_fingerprint" => "12340d18-e414-49cf-815a-66ab8ec1a480", - "device_name" => "收钱吧商户平台", - "device_model" => "Windows", - "device_brand" => "Chrome" - ] - ]; - $header = ['Content-Type:application/json;charset=UTF-8', 'Host:web-platforms-msp.shouqianba.com', 'Origin:https://s.shouqianba.com', 'Referer:https://s.shouqianba.com/login']; - $res = $this->getHttpResponse($url, $header, json_encode($user_info)); - $data = json_decode($res, true); - if ($data['code'] === 50000 && $data['data']['code'] === 50000) { - // 保存token - $this->saveToken($data['data']['mchUserTokenInfo']); - return true; - } else { - // 重试2次 - $is_login = false; - if ($times < 2) { - $is_login = $this->login($times + 1); - return $is_login; - } - return $is_login; - } - } - // 更新token - private function updateToken(): bool - { - $token = $this->getToken(); - $url = $this->payhost . $this->refresh_token_path . '?token=' . $token; - $header = ["Authorization:Bearer {$token}"]; - $res = $this->getHttpResponse($url, $header, true); - $data = json_decode($res, true); - if ($data['data']['status'] === 0) { - // 登陆刷新Token - $this->login(); - } else { - $this->saveToken($data['data']); - } - return true; - } - // 获取token - private function getToken(): string - { - $token_info = json_decode(file_get_contents($this->token_path), true); - return $token_info['token']; - } - // 保存token - private function saveToken($data) - { - $token = $data['token']; - file_put_contents($this->token_path, json_encode(['token' => $token, 'update_time' => date('Y-m-d H:i:s')])); - } - // 请求外部资源 - private function getHttpResponse($url, $header = [], $post = null, $timeout = 10) - { - $ch = curl_init($url); - curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); - curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookie_path); - curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookie_path); - if ($header) { - curl_setopt($ch, CURLOPT_HTTPHEADER, $header); - } else { - $httpheader[] = "Accept: */*"; - $httpheader[] = "Accept-Language: zh-CN,zh;q=0.9"; - $httpheader[] = "Connection: close"; - curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader); - } - curl_setopt($ch, CURLOPT_HEADER, false); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - if ($post) { - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $post); - } - $response = curl_exec($ch); - curl_close($ch); - return $response; - } -} diff --git a/extend/payclient/payclient.zip b/extend/payclient/payclient.zip deleted file mode 100644 index e4ac4afc5d3081748cac30f6f7f5e6ef8ce8ba48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17868 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 z 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