diff --git a/Application/Admin/Controller/ConsoleController.class.php b/Application/Admin/Controller/ConsoleController.class.php index a2c145e51..047251194 100644 --- a/Application/Admin/Controller/ConsoleController.class.php +++ b/Application/Admin/Controller/ConsoleController.class.php @@ -17,6 +17,7 @@ use Base\Repository\GameRepository; use Base\Service\PromoteCompanyService; use Base\Tool\Redis; use Think\Model; +use Org\QzlPay\Api as QzlApi; class ConsoleController extends Think { @@ -892,4 +893,18 @@ class ConsoleController extends Think { $month = date('Y-m', strtotime("$month +1 month")); } while ($month <= $lastMonth); } + + public function testPay() { + $extra = [ + 'notifyUrl' => 'http://www.baidu.com', + 'callbackUrl' => 'http://www.baidu.com', + ]; + $response = QzlApi::paySubmit( + '' . time() . rand(1000, 9999), + 6 * 100, + QzlApi::CHANNEL_WX_H5, + '测试充值', + $extra + ); + } } diff --git a/ThinkPHP/Library/Org/QzlPay/Api.class.php b/ThinkPHP/Library/Org/QzlPay/Api.class.php new file mode 100644 index 000000000..0a4e42107 --- /dev/null +++ b/ThinkPHP/Library/Org/QzlPay/Api.class.php @@ -0,0 +1,37 @@ + $channel, + 'body' => $body, + 'mchOrderNo' => $orderNo, + 'amount' => $amount, + 'currency' => 'CNY', + 'timePaid' => date('YmdHis'), + 'timeExpire' => date('YmdHis', time() + 15*60), + 'remark' => '', + 'extra' => $extra, + ]; + return self::request('cs.pay.submit', $params); + } + + public static function queryOrder($orderNo = '', $cpOrderNo = '') { + $params = [ + 'mchOrderNo' => $orderNo, + 'cpOrderNo' => $cpOrderNo, + ]; + return self::request('cs.order.query', $params); + } +} \ No newline at end of file diff --git a/ThinkPHP/Library/Org/QzlPay/ApiCommonTrait.php b/ThinkPHP/Library/Org/QzlPay/ApiCommonTrait.php new file mode 100644 index 000000000..822d771aa --- /dev/null +++ b/ThinkPHP/Library/Org/QzlPay/ApiCommonTrait.php @@ -0,0 +1,24 @@ + $apiName, + 'version' => '2.0', + 'mchNo' => Config::get('mchNo'), + ]; + } + + protected static function request($apiName, $params) { + $params = array_merge(self::getCommonParams($apiName), $params); + $params[Signer::SIGN_NAME] = Signer::sign($params, Config::get('paySecret')); + return Client::request(self::getUrl(), $params); + } + + protected static function getUrl() { + return Config::get('baseUrl') . '/gateway/api/trade'; + } +} \ No newline at end of file diff --git a/ThinkPHP/Library/Org/QzlPay/Client.class.php b/ThinkPHP/Library/Org/QzlPay/Client.class.php new file mode 100644 index 000000000..7032b5637 --- /dev/null +++ b/ThinkPHP/Library/Org/QzlPay/Client.class.php @@ -0,0 +1,43 @@ +getMessage()); + $response = json_encode([ + 'result' => -99, + 'errorMsg' => '网络异常', + 'signature' => true, + ]); + } + return new Response($response); + } + + public static function post($url, $params): string + { + Log::write('REQUEST_URL: ' . $url); + Log::write('REQUEST_DATA: ' . json_encode($params)); + $curl = curl_init(); + if (stripos($url, 'https://') !== false){ + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + } + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_POST, true); + $headers = ['Content-Type: application/x-www-form-urlencoded']; + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($params)); + $response = curl_exec($curl); + curl_close($curl); + return $response; + } +} \ No newline at end of file diff --git a/ThinkPHP/Library/Org/QzlPay/Config.class.php b/ThinkPHP/Library/Org/QzlPay/Config.class.php new file mode 100644 index 000000000..cf6cc1717 --- /dev/null +++ b/ThinkPHP/Library/Org/QzlPay/Config.class.php @@ -0,0 +1,15 @@ + 'http://game.quzhilian.net', + 'mchNo' => '68822023041910000101', + 'paySecret' => '040f0a9dd7d640f1b9270a0931aa8230', + ]; + + public static function get($key) { + return self::$params[$key] ?? null; + } +} \ No newline at end of file diff --git a/ThinkPHP/Library/Org/QzlPay/Log.class.php b/ThinkPHP/Library/Org/QzlPay/Log.class.php new file mode 100644 index 000000000..0cc47e82b --- /dev/null +++ b/ThinkPHP/Library/Org/QzlPay/Log.class.php @@ -0,0 +1,12 @@ +parse($content); + } + + public function isSuccess() { + if ($this->status === 0 && $this->resultCode === 0) { + return true; + } + return false; + } + + private function parse($response) + { + if (is_array($response)) { + Log::write('RESPONSE_ARRAY: ' . json_encode($response)); + $data = $response; + } else { + Log::write('RESPONSE_STR: ' . $response); + $data = json_decode($response, true); + } + if (!$data) { + $data = [ + 'status' => -98, + 'message' => '数据异常', + ]; + } + + $this->data = $data; + $this->status = $data['status']; + $this->message = $data['message']; + if ($data['status'] === 0) { + $this->resultCode = $data['resultCode']; + $this->message = '[' . $data['errCode'] . ']' . $data['errorMsg']; + } + } + + public function getData($key) { + return $this->data[$key] ?? null; + } + + public function getMessage() { + return $this->message; + } + + public function verify() + { + return Signer::verify($this->data, Config::get('paySecret')); + } +} \ No newline at end of file diff --git a/ThinkPHP/Library/Org/QzlPay/Signer.class.php b/ThinkPHP/Library/Org/QzlPay/Signer.class.php new file mode 100644 index 000000000..81ad2b7ac --- /dev/null +++ b/ThinkPHP/Library/Org/QzlPay/Signer.class.php @@ -0,0 +1,32 @@ + $value) { + $signPrams[] = $key . '=' . $value; + } + $signPrams[] = 'paySecret=' . $paySecret; + $signString = implode('&', $signPrams); + return strtoupper(md5($signString)); + } + + public static function verify($params, $paySecret) { + $sign = $params[self::SIGN_NAME] ?? ''; + if ($sign == self::sign($params, $paySecret)) { + return true; + } + return false; + } +} \ No newline at end of file