From e0de54a9e9c39e5b993b05c176128f8a14e55503 Mon Sep 17 00:00:00 2001 From: li Date: Wed, 15 Apr 2026 23:06:20 +0800 Subject: [PATCH 01/32] =?UTF-8?q?feat:=20=E6=8E=A5=E5=85=A5=E5=BD=A9?= =?UTF-8?q?=E8=99=B9=E6=98=93=E6=94=AF=E4=BB=98(USDT=20TRC20)=E5=85=85?= =?UTF-8?q?=E5=80=BC=E9=80=9A=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 extend/pay/Epay.php 易支付协议实现(MD5签名、buildPayUrl、queryOrder、verifyNotifyCallback) - 新增 traits/epayPay.php 提供 epay_online_order 和 epay_recharge_callback,独立结算事务 - config.php 加 pay_list.epay 配置段 (pid=1000, key已配, pay.g7g7.top) - Order.php / Pcapi.php 引入 epayPay trait 支付流程: 用户下单 -> 返回 pay.g7g7.top 跳转 URL -> 用户付款USDT -> 易支付异步回调 -> 验签 -> 结算加余额 通道标识: pay_channel_id=8, pay_channel_name=epay 订单号前缀: P (区别 AlinPay 的 E) --- application/config.php | 14 + application/onlinechip/controller/Order.php | 1 + application/onlinechip/controller/Pcapi.php | 1 + .../onlinechip/controller/traits/epayPay.php | 327 ++++++++++++++++++ extend/pay/Epay.php | 208 +++++++++++ 5 files changed, 551 insertions(+) create mode 100644 application/onlinechip/controller/traits/epayPay.php create mode 100644 extend/pay/Epay.php diff --git a/application/config.php b/application/config.php index 6eb0e7b..2438492 100644 --- a/application/config.php +++ b/application/config.php @@ -359,5 +359,19 @@ return [ '11' => '越南代收' ] ], + 'epay' => [//彩虹易支付(USDT/支付宝/微信 聚合) + 'online_order_fac' => 'epay_online_order', + 'notify_url' => 'https://api.g7g7.top/order/epay_recharge_callback',// 异步回调 + 'callback_url' => 'https://api.g7g7.top/order/epay_return',// 同步跳转回业务 + 'api_url' => 'https://pay.g7g7.top', + 'pid' => '1000', + 'key' => 'bf7b83653f5c056a6103e26263a75fa1', + 'goods_name' => '账户充值', + 'type' => [ + 'usdt' => 'USDT支付', + // 'alipay' => '支付宝', + // 'wxpay' => '微信支付', + ] + ], ] ]; diff --git a/application/onlinechip/controller/Order.php b/application/onlinechip/controller/Order.php index 86b3bcf..92c8f6f 100644 --- a/application/onlinechip/controller/Order.php +++ b/application/onlinechip/controller/Order.php @@ -14,6 +14,7 @@ class Order Extends Controller{ use traits\happyPay; use traits\hengfuPay; use traits\alinPay; + use traits\epayPay; public function __construct() { diff --git a/application/onlinechip/controller/Pcapi.php b/application/onlinechip/controller/Pcapi.php index 8a9391f..37b9beb 100755 --- a/application/onlinechip/controller/Pcapi.php +++ b/application/onlinechip/controller/Pcapi.php @@ -17,6 +17,7 @@ use Waybill\WaybillRoulette; class Pcapi extends Controller{ use traits\alinPay; + use traits\epayPay; public function __construct(){ parent::__construct(); // CORS headers diff --git a/application/onlinechip/controller/traits/epayPay.php b/application/onlinechip/controller/traits/epayPay.php new file mode 100644 index 0000000..2b26970 --- /dev/null +++ b/application/onlinechip/controller/traits/epayPay.php @@ -0,0 +1,327 @@ +post(); + if (isset($post['encryptData'])) { + $post = decrypt_data($post); + if (!$post) { + return json(['status' => 0, 'message' => '数据解密失败']); + } + } + + $user_id = intval($post['user_id'] ?? 0); + $money = intval($post['price'] ?? 0); + $client = intval($post['client'] ?? 0); + $username = trim($post['username'] ?? ''); + // 支付子类型:usdt / alipay / wxpay 等,默认 usdt + $pay_type = trim($post['pay_type'] ?? 'usdt'); + + $user = Db::name('user')->where([ + 'id' => $user_id, + 'status' => 1, + 'is_delete' => 0, + 'agent' => 0, + ])->find(); + + if (!$user || $user_id <= 0 || $money <= 0 || $client <= 0) { + return json(['status' => 0, 'message' => '参数错误,请稍后再试']); + } + + // 地区支线权限(与 AlinPay 一致的风控) + $zdlIdArr = explode(',', $user['agent_parent_id_path']); + $area_list = config('area_list'); + + if (!isset($area_list[$user['area_id']])) { + return json(['status' => 0, 'message' => '所在地区暂不支持充值']); + } + + $isAllow = false; + foreach ($area_list[$user['area_id']]['limit_agent'] as $allowAgentId) { + if (in_array($allowAgentId, $zdlIdArr)) { + $isAllow = true; + } + } + if (!$isAllow) { + return json(['status' => 0, 'message' => '该账号暂不支持在线充值']); + } + + // 总代理余额校验 + $zdlId = $zdlIdArr[0]; + $zdl = Db::name('user')->where([ + 'id' => $zdlId, + 'status' => 1, + 'is_delete' => 0, + 'agent' => 1, + ])->find(); + + if (!$zdl) { + return json(['status' => 0, 'message' => '所属代理账号异常,暂不能充值']); + } + if ($zdl['money'] < $money) { + return json(['status' => 0, 'message' => '所属代理余额不足,暂不能充值']); + } + + $pay_list = config('pay_list'); + $pay_orderid = 'P' . date('YmdHis') . rand(100000, 999999); // P 前缀区分 AlinPay 的 E + $notify_url = $pay_list['epay']['notify_url'] ?? ''; + $return_url = $pay_list['epay']['callback_url'] ?? ''; + $goods_name = $pay_list['epay']['goods_name'] ?? '账户充值'; + + try { + $epay = new \pay\Epay(); + + $payUrl = $epay->buildPayUrl( + $pay_orderid, + $pay_type, + sprintf('%.2f', $money), + $goods_name, + $notify_url, + $return_url, + 'uid:' . $user_id + ); + + if (!$payUrl) { + addLogToFile('epay 下单构造 URL 失败:order=' . $pay_orderid, 'epay_error', 'epay'); + $data = encrypt_data(['status' => 0, 'message' => '支付地址生成失败,请稍后再试']); + return json(['Success' => 1, 'Data' => $data]); + } + + // 写订单 + $order_id = Db::name('order_record')->insertGetId([ + 'pay_channel_id' => 8, + 'pay_channel_name' => 'epay', + 'user_id' => $user_id, + 'order_sn' => $pay_orderid, + 'appid' => strval($epay->getConfigInfo()['pid'] ?? ''), + 'api_key' => '', + 'money' => $money, + 'sign' => '', + 'create_time' => time(), + 'back_order_sn' => '', + 'client' => $client, + ]); + + Db::name('order_log')->insert([ + 'pay_channel_id' => 8, + 'pay_channel_name' => 'epay', + 'money' => $money, + 'create_time' => time(), + 'remake' => 'user_id:' . $user_id . ',用户名:' . $username . ',发起充值(' . $pay_type . '):' . $money . ',时间:' . date('Y-m-d H:i:s'), + 'order_id' => $order_id, + 'client' => $client, + ]); + + $data = encrypt_data(['status' => 1, 'message' => '发起支付成功,即将跳转...', 'url' => $payUrl]); + return json(['Success' => 1, 'Data' => $data]); + } catch (\Exception $e) { + addLogToFile('epay 下单异常:' . $e->getMessage() . ' | file:' . $e->getFile() . ':' . $e->getLine(), 'epay_error', 'epay'); + $data = encrypt_data(['status' => 0, 'message' => '支付发起失败[' . $e->getMessage() . ']']); + return json(['Success' => 1, 'Data' => $data]); + } + } + + /** + * 易支付 - 异步回调处理 + * + * 易支付回调是 GET(pay.php 跳转后用 GET 带参数回 notify_url), + * 但也可能 POST —— 都兼容 + */ + public function epay_recharge_callback() + { + $request = Request::instance(); + $data = $request->post(); + if (empty($data)) { + $data = $request->get(); + } + + $json = json_encode($data, JSON_UNESCAPED_UNICODE); + addLogToFile('epay 回调原始数据:' . $json, 'epay_callback', 'epay'); + + if (!is_array($data) || empty($data['out_trade_no']) || empty($data['sign'])) { + Log::record($data, 'epay_error_callback'); + exit('fail'); + } + + // 记录回调日志 + $logId = Db::name('pay_callback_log')->insertGetId([ + 'pay_channel' => 'EPAY_RECHARGE', + 'type' => 'recharge', + 'json' => $json, + 'create_time' => date('Y-m-d H:i:s'), + ]); + + try { + $epay = new \pay\Epay(); + $result = $epay->verifyNotifyCallback($data, $logId); + + if (!$result['verified']) { + exit('fail'); + } + + if ($result['success']) { + $this->epay_recharge_settle($data); + exit('success'); + } else { + // 非 TRADE_SUCCESS —— 返 success 让对方不再重试 + addLogToFile('epay 回调非成功状态,ack 防重试:order=' . ($data['out_trade_no'] ?? ''), 'epay_callback', 'epay'); + exit('success'); + } + } catch (\Exception $e) { + addLogToFile('epay 回调处理异常:' . $e->getMessage(), 'epay_callback_error', 'epay'); + exit('fail'); + } + } + + /** + * 易支付结算(事务保护:加锁 → 扣代理 → 加用户 → 写日志) + * 和 alin_recharge_settle 同构,只是 pay_channel 改成 epay + */ + private function epay_recharge_settle($data) + { + $orderNo = $data['out_trade_no']; + + Db::startTrans(); + try { + $order = Db::name('order_record')->where('order_sn', $orderNo)->lock(true)->find(); + if (!$order || $order['status'] == 3) { + Db::rollback(); + return; + } + + $user = Db::name('user')->where([ + 'id' => $order['user_id'], + 'status' => 1, + 'is_delete' => 0, + 'agent' => 0, + ])->lock(true)->find(); + if (!$user) { + Db::rollback(); + return; + } + + $zdlIdArr = explode(',', $user['agent_parent_id_path']); + $zdlId = $zdlIdArr[0]; + + $zdl = Db::name('user')->where([ + 'id' => $zdlId, + 'status' => 1, + 'is_delete' => 0, + 'agent' => 1, + ])->lock(true)->find(); + + if (!$zdl || $zdl['money'] < $order['money']) { + Db::rollback(); + addLogToFile('epay 结算失败:代理余额不足 order=' . $orderNo, 'epay_callback_error', 'epay'); + return; + } + + // 实际到账金额:易支付回调中的 money 字段(CNY) + $actualMoney = isset($data['money']) ? floatval($data['money']) : $order['money']; + + // 1. 更新订单 + Db::name('order_record')->where('id', $order['id'])->update([ + 'back_money' => $actualMoney, + 'back_time' => time(), + 'status' => 3, + 'agent_parent_id' => $user['agent_parent_id'], + 'agent_parent_username' => $user['agent_parent_username'], + 'zdl_id' => $zdl['id'], + 'zdl_username' => $zdl['username'], + 'zdl_money_before' => $zdl['money'], + 'zdl_money_after' => $zdl['money'] - $order['money'], + 'money_before' => $user['money'], + 'money_after' => $user['money'] + $order['money'], + ]); + + // 2. 订单日志 + Db::name('order_log')->insert([ + 'pay_channel_id' => 8, + 'pay_channel_name' => 'epay', + 'money' => $order['money'], + 'create_time' => time(), + 'remake' => '易支付回调成功 trade_no=' . ($data['trade_no'] ?? '') . ' type=' . ($data['type'] ?? ''), + 'order_id' => $order['id'], + ]); + + // 3. recharge 流水 + Db::name('recharge')->insert([ + 'type' => 4, + 'amount' => $order['money'], + 'mode' => 1, + 'agent_or_admin' => 3, + 'controller_id' => $zdl['id'], + 'controller_username' => $zdl['username'], + 'controller_nickname' => $zdl['nickname'], + 'controller_type' => '易支付第三方充值,扣取总代理余分', + 'controller_old_money' => $zdl['money'], + 'controller_new_money' => $zdl['money'] - $order['money'], + 'user_id' => $order['user_id'], + 'user_type' => $user['agent'], + 'user_agent_level' => 0, + 'username_for' => $user['username'], + 'nickname_for' => $user['nickname'], + 'user_parent_id' => $user['agent_parent_id'], + 'create_time' => time(), + 'old_money' => $user['money'], + 'new_money' => $user['money'] + $order['money'], + 'controller_system' => 3, + 'remake' => '易支付第三方充值成功(' . ($data['type'] ?? '') . ')', + ]); + + // 4. 扣代理 + Db::name('user')->where('id', $zdl['id'])->update([ + 'money' => $zdl['money'] - $order['money'], + 'last_recharge_out' => $order['money'], + 'last_recharge_out_time' => time(), + 'recharge_out_count' => $zdl['recharge_out_count'] + 1, + 'recharge_out_total_amount' => $zdl['recharge_out_total_amount'] + $order['money'], + ]); + + // 5. 加用户 + Db::name('user')->where('id', $order['user_id'])->update([ + 'money' => $user['money'] + $order['money'], + 'last_recharge' => $order['money'], + 'last_recharge_time' => time(), + 'recharge_count' => $user['recharge_count'] + 1, + 'recharge_total_amount' => $user['recharge_total_amount'] + $order['money'], + ]); + + Db::commit(); + addLogToFile('epay 结算成功:order=' . $orderNo . ' money=' . $order['money'], 'epay_callback', 'epay'); + } catch (\Exception $e) { + Db::rollback(); + addLogToFile('epay 结算异常:' . $e->getMessage(), 'epay_callback_error', 'epay'); + } + } +} diff --git a/extend/pay/Epay.php b/extend/pay/Epay.php new file mode 100644 index 0000000..9de924b --- /dev/null +++ b/extend/pay/Epay.php @@ -0,0 +1,208 @@ +getConfig(); + } + + /** + * 获取配置 + * 优先读 pay_channel 表(和 AlinPay 一致的存储位置), + * 回退到 config('pay_list.epay') + */ + private function getConfig() + { + $dbConfig = Db::name('pay_channel')->where('key', 'EPAY')->value('value'); + if ($dbConfig) { + $this->config = json_decode($dbConfig, true) ?: []; + } else { + $this->config = config('pay_list.epay') ?: []; + } + $this->apiUrl = $this->config['api_url'] ?? 'https://pay.g7g7.top'; + } + + public function getConfigInfo() + { + return $this->config; + } + + /** + * 生成签名 + * + * @param array $params + * @return string + */ + public function generateSign(array $params) + { + unset($params['sign'], $params['sign_type']); + + // 过滤空值(易支付官方要求) + $params = array_filter($params, function ($val) { + return $val !== '' && $val !== null; + }); + + ksort($params); + + $parts = []; + foreach ($params as $k => $v) { + $parts[] = $k . '=' . $v; + } + $str = implode('&', $parts) . ($this->config['key'] ?? ''); + + return md5($str); + } + + /** + * 验证回调签名(时间安全比较) + * + * @param array $params + * @return bool + */ + public function verifySign(array $params) + { + $received = $params['sign'] ?? ''; + $calculated = $this->generateSign($params); + return hash_equals($calculated, $received); + } + + /** + * 构造发起支付的 URL(跳转式 submit.php) + * 前端收到该 URL 后直接 window.location 跳转即可 + * + * @param string $orderNo 商户订单号 + * @param string $type 支付方式:alipay|wxpay|qqpay|bank|jdpay|usdt + * @param string $amount 金额(元) + * @param string $name 商品名称 + * @param string $notifyUrl 异步通知地址 + * @param string $returnUrl 同步跳转地址 + * @param string $param 业务扩展参数(可选,原样回传) + * @return string + */ + public function buildPayUrl($orderNo, $type, $amount, $name, $notifyUrl, $returnUrl = '', $param = '') + { + $params = [ + 'pid' => strval($this->config['pid'] ?? ''), + 'type' => $type, + 'out_trade_no' => strval($orderNo), + 'notify_url' => $notifyUrl, + 'return_url' => $returnUrl, + 'name' => $name, + 'money' => strval($amount), + 'param' => $param, + 'sign_type' => 'MD5', + ]; + + $params['sign'] = $this->generateSign($params); + + $params = array_filter($params, function ($v) { + return $v !== '' && $v !== null; + }); + + return rtrim($this->apiUrl, '/') . '/submit.php?' . http_build_query($params); + } + + /** + * API 模式下单(mapi.php) + * + * @return array|null + */ + public function createOrderApi($orderNo, $type, $amount, $name, $notifyUrl, $returnUrl = '', $param = '') + { + $params = [ + 'pid' => strval($this->config['pid'] ?? ''), + 'type' => $type, + 'out_trade_no' => strval($orderNo), + 'notify_url' => $notifyUrl, + 'return_url' => $returnUrl, + 'name' => $name, + 'money' => strval($amount), + 'param' => $param, + 'sign_type' => 'MD5', + ]; + $params['sign'] = $this->generateSign($params); + + $url = rtrim($this->apiUrl, '/') . '/mapi.php'; + + addLogToFile('epay API 下单请求:' . $url . ' params=' . json_encode($params, JSON_UNESCAPED_UNICODE), 'epay_request', 'epay'); + + $result = httpPost($url, $params); + + addLogToFile('epay API 下单返回:' . json_encode($result, JSON_UNESCAPED_UNICODE), 'epay_response', 'epay'); + + if (is_array($result)) return $result; + if (is_string($result)) return json_decode($result, true); + return null; + } + + /** + * 订单查询 + */ + public function queryOrder($orderNo) + { + $params = [ + 'act' => 'order', + 'pid' => strval($this->config['pid'] ?? ''), + 'out_trade_no' => strval($orderNo), + ]; + $params['sign'] = $this->generateSign($params); + $params['sign_type'] = 'MD5'; + + $url = rtrim($this->apiUrl, '/') . '/api.php?' . http_build_query($params); + $resp = httpGet($url); + return is_string($resp) ? json_decode($resp, true) : $resp; + } + + /** + * 处理异步回调 — 仅验签+解析状态,不操作余额 + * 余额结算由 trait 内 epay_recharge_settle() 统一处理 + * + * @param array $data $_POST 或 $_GET + * @param int $logId 日志 ID + * @return array ['verified' => bool, 'success' => bool, 'data' => array] + */ + public function verifyNotifyCallback($data, $logId = 0) + { + if (!$this->verifySign($data)) { + addLogToFile('epay 回调验签失败:' . json_encode($data, 320), 'epay_callback_error', 'epay'); + return ['verified' => false, 'success' => false, 'data' => $data]; + } + + $orderNo = $data['out_trade_no'] ?? ''; + if ($logId && $orderNo) { + Db::name('pay_callback_log')->where('id', $logId)->update(['unique_no' => $orderNo]); + } + + $success = isset($data['trade_status']) && $data['trade_status'] === 'TRADE_SUCCESS'; + + addLogToFile('epay 回调验签通过:order=' . $orderNo . ' status=' . ($data['trade_status'] ?? ''), 'epay_callback', 'epay'); + + return ['verified' => true, 'success' => $success, 'data' => $data]; + } +} From 2df6527b7512d79ec70d1a172bb2d792a5d8ada9 Mon Sep 17 00:00:00 2001 From: li Date: Thu, 16 Apr 2026 00:07:40 +0800 Subject: [PATCH 02/32] =?UTF-8?q?feat(order):=20wappay/index=20=E8=B6=8A?= =?UTF-8?q?=E5=8D=97=E5=9C=B0=E5=8C=BA=E8=BF=BD=E5=8A=A0=20USDT(Epay)=20?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Order::wappay/index: area_id=3 时合并 pay_list['epay']['type'] 到 payMethod, 每个选项带 pay_routes 映射到对应 online_order_fac - wappay.html: select 的 option 加 data-url,JS 按选中项查路由 - 兼容旧行为:未设置 pay_routes 时 fallback 到原 online_order_fac --- application/onlinechip/controller/Order.php | 45 +++++++++++++++---- application/onlinechip/view/order/wappay.html | 5 ++- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/application/onlinechip/controller/Order.php b/application/onlinechip/controller/Order.php index 92c8f6f..2b35bab 100644 --- a/application/onlinechip/controller/Order.php +++ b/application/onlinechip/controller/Order.php @@ -35,10 +35,23 @@ class Order Extends Controller{ } $pay_method = $area_list[$user['area_id']]['pay']; if($user && $user['api_token'] == $api_token){ - $this->assign('online_order_fac',$pay_list[$pay_method]['online_order_fac']); - $this->assign('payMethod',$pay_list[$pay_method]['type']); - $this->assign('client',1); - $this->assign('user_info',$user); + $payMethod = $pay_list[$pay_method]['type']; + $pay_routes = []; + foreach($payMethod as $k => $v){ + $pay_routes[$k] = $pay_list[$pay_method]['online_order_fac']; + } + // 越南地区追加 USDT (Epay) + if($user['area_id'] == 3 && !empty($pay_list['epay']['type'])){ + foreach($pay_list['epay']['type'] as $k => $v){ + $payMethod[$k] = $v; + $pay_routes[$k] = $pay_list['epay']['online_order_fac']; + } + } + $this->assign('online_order_fac', $pay_list[$pay_method]['online_order_fac']); + $this->assign('payMethod', $payMethod); + $this->assign('pay_routes', $pay_routes); + $this->assign('client', 1); + $this->assign('user_info', $user); return $this->fetch(); }else{ exit('页面错误,请退出再登录!'); @@ -56,10 +69,26 @@ class Order Extends Controller{ } $pay_method = $area_list[$user['area_id']]['pay']; if($user && $user['api_token'] == $api_token){ - $this->assign('online_order_fac',$pay_list[$pay_method]['online_order_fac']); - $this->assign('payMethod',$pay_list[$pay_method]['type']); - $this->assign('client',2); - $this->assign('user_info',$user); + // 主通道(按 area_list 的 pay 配置) + $payMethod = $pay_list[$pay_method]['type']; + $pay_routes = []; + foreach($payMethod as $k => $v){ + $pay_routes[$k] = $pay_list[$pay_method]['online_order_fac']; + } + + // 越南地区追加 USDT (Epay) 通道作为第二选项 + if($user['area_id'] == 3 && !empty($pay_list['epay']['type'])){ + foreach($pay_list['epay']['type'] as $k => $v){ + $payMethod[$k] = $v; + $pay_routes[$k] = $pay_list['epay']['online_order_fac']; + } + } + + $this->assign('online_order_fac', $pay_list[$pay_method]['online_order_fac']); // 兼容旧模板 + $this->assign('payMethod', $payMethod); + $this->assign('pay_routes', $pay_routes); + $this->assign('client', 2); + $this->assign('user_info', $user); return $this->fetch(); }else{ exit('页面错误,请退出再登录!'); diff --git a/application/onlinechip/view/order/wappay.html b/application/onlinechip/view/order/wappay.html index 28e83e5..44f8296 100644 --- a/application/onlinechip/view/order/wappay.html +++ b/application/onlinechip/view/order/wappay.html @@ -204,7 +204,7 @@ @@ -233,7 +233,8 @@ query.price = price; query.username = username; query.pay_type = pay_type; - url = '/order/'; + // 每种支付方式对应的 online_order 路由可能不同 + url = $('#pay_type option:selected').data('url') || '/order/'; //var winRef = window.open("","_blank"); $.ajax({ url:url, From 93ea9cdc411bb97c0ac52230eb91ba8e12cd50de Mon Sep 17 00:00:00 2001 From: testadmin Date: Thu, 16 Apr 2026 23:13:25 +0800 Subject: [PATCH 03/32] =?UTF-8?q?feat(epay):=20=E5=86=85=E5=B5=8C=E4=BA=8C?= =?UTF-8?q?=E7=BB=B4=E7=A0=81=E6=A8=A1=E5=BC=8F=20+=20=E8=AE=A2=E5=8D=95?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E8=BD=AE=E8=AF=A2=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - epay_online_order: 直接跨库写 epay.pre_order,自算 usdtpro 指纹金额(对齐 usdtpro_plugin::submit 算法) - 返回值新增 qrcode 字段(address/amount/expires_at),前端内嵌渲染,无需跳转 pay.g7g7.top - 保留 url 字段兼容老调用方 - 新增 epay_order_status: 前端轮询订单状态(0=待支付/1=已到账/2=超时) --- .../onlinechip/controller/traits/epayPay.php | 215 +++++++++++++++++- 1 file changed, 212 insertions(+), 3 deletions(-) diff --git a/application/onlinechip/controller/traits/epayPay.php b/application/onlinechip/controller/traits/epayPay.php index 2b26970..6bb3f41 100644 --- a/application/onlinechip/controller/traits/epayPay.php +++ b/application/onlinechip/controller/traits/epayPay.php @@ -27,7 +27,26 @@ use think\Request; trait epayPay { /** - * 易支付 - 发起充值下单 + * 易支付 - 发起充值下单(内嵌二维码模式) + * + * 直接跨库写 epay.pre_order + 计算 usdtpro 指纹金额, + * 前端内嵌渲染二维码,无需跳转 pay.g7g7.top。 + * + * 返回的 Data 结构: + * { + * status: 1|0 + * message: 文案 + * url: 兼容字段(老前端仍可 window.open 跳转 /pay/leader/trade_no/) + * qrcode: { 新字段,前端内嵌渲染 + * order_sn: OG 侧订单号(用于轮询) + * usdt_address: TRC20 收款地址 + * usdt_amount: 含指纹尾数的精确金额(如 10.0003) + * vnd_amount: VND 原始金额 + * rate: 汇率 + * expires_at: 订单超时绝对时间戳 + * timeout_sec: 总超时秒数 + * } + * } */ public function epay_online_order() { @@ -97,10 +116,13 @@ trait epayPay $notify_url = $pay_list['epay']['notify_url'] ?? ''; $return_url = $pay_list['epay']['callback_url'] ?? ''; $goods_name = $pay_list['epay']['goods_name'] ?? '账户充值'; + $epay_api = $pay_list['epay']['api_url'] ?? 'https://pay.g7g7.top'; + $merchant_id = intval($pay_list['epay']['pid'] ?? 0); try { $epay = new \pay\Epay(); + // 兼容用:老版 pay/leader 页跳转 URL $payUrl = $epay->buildPayUrl( $pay_orderid, $pay_type, @@ -117,7 +139,7 @@ trait epayPay return json(['Success' => 1, 'Data' => $data]); } - // 写订单 + // 写 OG 侧订单 $order_id = Db::name('order_record')->insertGetId([ 'pay_channel_id' => 8, 'pay_channel_name' => 'epay', @@ -142,7 +164,26 @@ trait epayPay 'client' => $client, ]); - $data = encrypt_data(['status' => 1, 'message' => '发起支付成功,即将跳转...', 'url' => $payUrl]); + // 跨库写 epay.pre_order 并算 usdtpro 指纹金额 + $qrcode = null; + if ($pay_type === 'usdt' && $merchant_id > 0) { + $qrcode = $this->epay_create_usdt_pre_order( + $pay_orderid, + $money, + $goods_name, + $notify_url, + $return_url, + $merchant_id, + 'uid:' . $user_id + ); + } + + $data = encrypt_data([ + 'status' => 1, + 'message' => '发起支付成功', + 'url' => $payUrl, // 兼容老前端 + 'qrcode' => $qrcode, // 新前端内嵌渲染用 + ]); return json(['Success' => 1, 'Data' => $data]); } catch (\Exception $e) { addLogToFile('epay 下单异常:' . $e->getMessage() . ' | file:' . $e->getFile() . ':' . $e->getLine(), 'epay_error', 'epay'); @@ -151,6 +192,174 @@ trait epayPay } } + /** + * 跨库创建 epay.pre_order 并算 usdtpro 指纹金额 + * + * 算法对齐 pay.g7g7.top/plugins/usdtpro/usdtpro_plugin.php::submit(): + * - 指纹金额 = round(realmoney / rate, 4) + * - 同通道+同金额+未超时订单存在则 +0.0001 递增错开 + */ + private function epay_create_usdt_pre_order($orderNo, $money, $goodsName, $notifyUrl, $returnUrl, $pid, $param = '') + { + // 查 usdtpro 通道(写死 plugin=usdtpro,status=1) + $channel = Db::query("SELECT `id`, `config`, `rate` FROM `epay`.`pre_channel` WHERE `plugin`='usdtpro' AND `status`=1 LIMIT 1"); + if (empty($channel)) { + addLogToFile('epay USDT 通道未启用:order=' . $orderNo, 'epay_error', 'epay'); + return null; + } + $channel = $channel[0]; + $channel_config = json_decode($channel['config'], true); + if (!$channel_config || empty($channel_config['address'])) { + addLogToFile('epay USDT 通道配置缺失 address:order=' . $orderNo, 'epay_error', 'epay'); + return null; + } + $address = $channel_config['address']; + $rate = floatval($channel_config['rate'] ?? 100000); + $timeout = intval($channel_config['timeout'] ?? 600); + + // usdt type id(按插件约定 usdt -> pre_type.id=7,但直接查一下更稳) + $typeRow = Db::query("SELECT `id` FROM `epay`.`pre_type` WHERE `name`='usdt' AND `status`=1 LIMIT 1"); + if (empty($typeRow)) { + addLogToFile('epay pre_type usdt 未启用', 'epay_error', 'epay'); + return null; + } + $type_id = intval($typeRow[0]['id']); + + // 算指纹金额(碰撞检测) + $unique_usdt = round($money / $rate, 4); + $max_try = 100; + while ($max_try-- > 0) { + $same = Db::query( + "SELECT 1 FROM `epay`.`pre_order` WHERE `channel`=:ch AND `usdtpro`=:amt AND UNIX_TIMESTAMP(`addtime`) + :win >= :now LIMIT 1", + [ + ':ch' => $channel['id'], + ':amt' => $unique_usdt, + ':win' => $timeout * 3, + ':now' => time(), + ] + ); + if (empty($same)) { + break; + } + $unique_usdt = round($unique_usdt + 0.0001, 4); + } + + // epay 侧的 trade_no(YmdHis + 5 随机) + $trade_no = date('YmdHis') . rand(11111, 99999); + $realmoney = sprintf('%.2f', $money); + $domain = parse_url($notifyUrl, PHP_URL_HOST) ?: ''; + + Db::execute( + "INSERT INTO `epay`.`pre_order` + (`trade_no`, `out_trade_no`, `uid`, `type`, `channel`, `name`, `money`, `realmoney`, `getmoney`, + `notify_url`, `return_url`, `param`, `addtime`, `date`, `domain`, `ip`, `status`, `version`, `usdtpro`) + VALUES + (:trade_no, :out_trade_no, :uid, :type, :channel, :name, :money, :realmoney, :getmoney, + :notify_url, :return_url, :param, NOW(), CURDATE(), :domain, :ip, 0, 1, :usdtpro)", + [ + ':trade_no' => $trade_no, + ':out_trade_no' => $orderNo, + ':uid' => $pid, + ':type' => $type_id, + ':channel' => $channel['id'], + ':name' => $goodsName, + ':money' => $realmoney, + ':realmoney' => $realmoney, + ':getmoney' => $realmoney, + ':notify_url' => $notifyUrl, + ':return_url' => $returnUrl, + ':param' => $param, + ':domain' => $domain, + ':ip' => Request::instance()->ip(), + ':usdtpro' => $unique_usdt, + ] + ); + + $expires_at = time() + $timeout; + addLogToFile('epay USDT 内嵌下单成功: order=' . $orderNo . ' trade_no=' . $trade_no . ' usdt=' . $unique_usdt, 'epay_request', 'epay'); + + return [ + 'order_sn' => $orderNo, + 'trade_no' => $trade_no, + 'usdt_address' => $address, + 'usdt_amount' => sprintf('%.4f', $unique_usdt), + 'vnd_amount' => $realmoney, + 'rate' => (string) $rate, + 'expires_at' => $expires_at, + 'timeout_sec' => $timeout, + ]; + } + + /** + * 易支付 - 订单状态轮询 + * + * 前端轮询该接口,判断是否到账或已超时。 + * 返回 Data 结构: + * { status: 0|1|2, message, money, paid_time } + * 0=待支付, 1=已到账, 2=已超时 + */ + public function epay_order_status() + { + $post = Request::instance()->post(); + if (isset($post['encryptData'])) { + $post = decrypt_data($post); + if (!$post) { + return json(['status' => 0, 'message' => '数据解密失败']); + } + } + + $order_sn = trim($post['order_sn'] ?? ''); + $user_id = intval($post['user_id'] ?? 0); + + if ($order_sn === '' || $user_id <= 0) { + $data = encrypt_data(['status' => 0, 'message' => '参数错误']); + return json(['Success' => 1, 'Data' => $data]); + } + + $order = Db::name('order_record') + ->where([ + 'order_sn' => $order_sn, + 'user_id' => $user_id, + 'pay_channel_id' => 8, + ]) + ->find(); + + if (!$order) { + $data = encrypt_data(['status' => 0, 'message' => '订单不存在']); + return json(['Success' => 1, 'Data' => $data]); + } + + // status=3 代表已回调结算完成(见 epay_recharge_settle) + if (intval($order['status']) == 3) { + $data = encrypt_data([ + 'status' => 1, + 'message' => '充值成功', + 'money' => $order['money'], + 'paid_time' => $order['back_time'], + ]); + return json(['Success' => 1, 'Data' => $data]); + } + + // 超时判定:从 epay 配置拿 timeout,兜底 600 + $pay_list = config('pay_list'); + $timeout = intval($pay_list['epay']['timeout'] ?? 600); + if (time() - intval($order['create_time']) > $timeout) { + $data = encrypt_data([ + 'status' => 2, + 'message' => '订单超时', + 'money' => $order['money'], + ]); + return json(['Success' => 1, 'Data' => $data]); + } + + $data = encrypt_data([ + 'status' => 0, + 'message' => '等待支付', + 'money' => $order['money'], + ]); + return json(['Success' => 1, 'Data' => $data]); + } + /** * 易支付 - 异步回调处理 * From 56c9b1591da0f4aba91bdfd3b9ee940ea4dfbd1a Mon Sep 17 00:00:00 2001 From: testadmin Date: Thu, 16 Apr 2026 23:25:20 +0800 Subject: [PATCH 04/32] =?UTF-8?q?fix(epay):=20PDO=20bind=20key=20=E4=B8=8D?= =?UTF-8?q?=E5=BA=94=E5=B8=A6=E5=86=92=E5=8F=B7=EF=BC=88TP5=20=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=8A=A0=20:=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onlinechip/controller/traits/epayPay.php | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/application/onlinechip/controller/traits/epayPay.php b/application/onlinechip/controller/traits/epayPay.php index 6bb3f41..2976a25 100644 --- a/application/onlinechip/controller/traits/epayPay.php +++ b/application/onlinechip/controller/traits/epayPay.php @@ -232,10 +232,10 @@ trait epayPay $same = Db::query( "SELECT 1 FROM `epay`.`pre_order` WHERE `channel`=:ch AND `usdtpro`=:amt AND UNIX_TIMESTAMP(`addtime`) + :win >= :now LIMIT 1", [ - ':ch' => $channel['id'], - ':amt' => $unique_usdt, - ':win' => $timeout * 3, - ':now' => time(), + 'ch' => $channel['id'], + 'amt' => $unique_usdt, + 'win' => $timeout * 3, + 'now' => time(), ] ); if (empty($same)) { @@ -257,21 +257,21 @@ trait epayPay (:trade_no, :out_trade_no, :uid, :type, :channel, :name, :money, :realmoney, :getmoney, :notify_url, :return_url, :param, NOW(), CURDATE(), :domain, :ip, 0, 1, :usdtpro)", [ - ':trade_no' => $trade_no, - ':out_trade_no' => $orderNo, - ':uid' => $pid, - ':type' => $type_id, - ':channel' => $channel['id'], - ':name' => $goodsName, - ':money' => $realmoney, - ':realmoney' => $realmoney, - ':getmoney' => $realmoney, - ':notify_url' => $notifyUrl, - ':return_url' => $returnUrl, - ':param' => $param, - ':domain' => $domain, - ':ip' => Request::instance()->ip(), - ':usdtpro' => $unique_usdt, + 'trade_no' => $trade_no, + 'out_trade_no' => $orderNo, + 'uid' => $pid, + 'type' => $type_id, + 'channel' => $channel['id'], + 'name' => $goodsName, + 'money' => $realmoney, + 'realmoney' => $realmoney, + 'getmoney' => $realmoney, + 'notify_url' => $notifyUrl, + 'return_url' => $returnUrl, + 'param' => $param, + 'domain' => $domain, + 'ip' => Request::instance()->ip(), + 'usdtpro' => $unique_usdt, ] ); From f3eb260841e0782a04b6be2509666495b871cf85 Mon Sep 17 00:00:00 2001 From: testadmin Date: Thu, 16 Apr 2026 23:49:08 +0800 Subject: [PATCH 05/32] =?UTF-8?q?fix(epay):=20usdtpro=20=E6=8C=87=E7=BA=B9?= =?UTF-8?q?=E9=87=91=E9=A2=9D=E6=94=B9=E7=94=B1=20epay=20=E4=BE=A7?= =?UTF-8?q?=E6=9D=83=E5=A8=81=E8=AE=A1=E7=AE=97=EF=BC=8C=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E7=B2=BE=E5=BA=A6=E6=BC=82=E7=A7=BB=E5=AF=BC=E8=87=B4=E5=85=85?= =?UTF-8?q?=E5=80=BC=E4=B8=8D=E5=88=B0=E8=B4=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - epay_online_order 改为调用 epay mapi.php(createOrderApi) - 让 epay 自己走完 Pay::create → Plugin::loadForSubmit → usdtpro_plugin::submit - 从返回 jump url 解析 trade_no,再查 epay.pre_order 读取权威 usdtpro - 错误返回统一 encrypt_data + Success/Data 加密结构,前端能正确显示 - 所有错误文案改为越南语用户友好版(代理余额不足→"Hạn mức nạp mỗi lần ... VND") - 代理余额不足场景额外返回 max_amount 字段,前端可用作输入上限提示 - 移除 epay_create_usdt_pre_order 自算方法 --- .../onlinechip/controller/traits/epayPay.php | 216 +++++++----------- 1 file changed, 82 insertions(+), 134 deletions(-) diff --git a/application/onlinechip/controller/traits/epayPay.php b/application/onlinechip/controller/traits/epayPay.php index 2976a25..e51e38b 100644 --- a/application/onlinechip/controller/traits/epayPay.php +++ b/application/onlinechip/controller/traits/epayPay.php @@ -55,7 +55,8 @@ trait epayPay if (isset($post['encryptData'])) { $post = decrypt_data($post); if (!$post) { - return json(['status' => 0, 'message' => '数据解密失败']); + $data = encrypt_data(['status' => 0, 'message' => 'Dữ liệu không hợp lệ']); + return json(['Success' => 1, 'Data' => $data]); } } @@ -74,7 +75,8 @@ trait epayPay ])->find(); if (!$user || $user_id <= 0 || $money <= 0 || $client <= 0) { - return json(['status' => 0, 'message' => '参数错误,请稍后再试']); + $data = encrypt_data(['status' => 0, 'message' => 'Tham số không hợp lệ, vui lòng thử lại']); + return json(['Success' => 1, 'Data' => $data]); } // 地区支线权限(与 AlinPay 一致的风控) @@ -82,7 +84,8 @@ trait epayPay $area_list = config('area_list'); if (!isset($area_list[$user['area_id']])) { - return json(['status' => 0, 'message' => '所在地区暂不支持充值']); + $data = encrypt_data(['status' => 0, 'message' => 'Khu vực hiện chưa hỗ trợ nạp tiền']); + return json(['Success' => 1, 'Data' => $data]); } $isAllow = false; @@ -92,7 +95,8 @@ trait epayPay } } if (!$isAllow) { - return json(['status' => 0, 'message' => '该账号暂不支持在线充值']); + $data = encrypt_data(['status' => 0, 'message' => 'Tài khoản này chưa được phép nạp online']); + return json(['Success' => 1, 'Data' => $data]); } // 总代理余额校验 @@ -105,10 +109,18 @@ trait epayPay ])->find(); if (!$zdl) { - return json(['status' => 0, 'message' => '所属代理账号异常,暂不能充值']); + $data = encrypt_data(['status' => 0, 'message' => 'Tài khoản đại lý có vấn đề, không thể nạp']); + return json(['Success' => 1, 'Data' => $data]); } if ($zdl['money'] < $money) { - return json(['status' => 0, 'message' => '所属代理余额不足,暂不能充值']); + $maxAllowed = intval($zdl['money']); + $data = encrypt_data([ + 'status' => 0, + 'code' => 'AGENT_LIMIT', + 'message' => 'Hạn mức nạp mỗi lần hiện tại là ' . number_format($maxAllowed, 0, '.', ',') . ' VND. Vui lòng nhập số tiền nhỏ hơn hoặc bằng mức trên.', + 'max_amount' => $maxAllowed, + ]); + return json(['Success' => 1, 'Data' => $data]); } $pay_list = config('pay_list'); @@ -122,23 +134,6 @@ trait epayPay try { $epay = new \pay\Epay(); - // 兼容用:老版 pay/leader 页跳转 URL - $payUrl = $epay->buildPayUrl( - $pay_orderid, - $pay_type, - sprintf('%.2f', $money), - $goods_name, - $notify_url, - $return_url, - 'uid:' . $user_id - ); - - if (!$payUrl) { - addLogToFile('epay 下单构造 URL 失败:order=' . $pay_orderid, 'epay_error', 'epay'); - $data = encrypt_data(['status' => 0, 'message' => '支付地址生成失败,请稍后再试']); - return json(['Success' => 1, 'Data' => $data]); - } - // 写 OG 侧订单 $order_id = Db::name('order_record')->insertGetId([ 'pay_channel_id' => 8, @@ -164,132 +159,85 @@ trait epayPay 'client' => $client, ]); - // 跨库写 epay.pre_order 并算 usdtpro 指纹金额 + // 调用 epay 的 mapi.php,让 epay 自己走完整个流程: + // 1) INSERT pre_order + // 2) Channel::submit 算通道 + // 3) Plugin::loadForSubmit → usdtpro_plugin::submit() 算 usdtpro 指纹金额并写入 pre_order + // 4) 返回 {type:'jump', url:'/pay/leader/TRADE_NO/'} + // 注意:usdtpro 指纹金额必须由 epay 侧算,OG 侧算会与 monitor 对账逻辑产生精度漂移,导致充值不到账 + $apiResult = $epay->createOrderApi( + $pay_orderid, + $pay_type, + sprintf('%.2f', $money), + $goods_name, + $notify_url, + $return_url, + 'uid:' . $user_id + ); + + if (!is_array($apiResult) || empty($apiResult['url'])) { + $errMsg = is_array($apiResult) ? (isset($apiResult['msg']) ? $apiResult['msg'] : json_encode($apiResult, JSON_UNESCAPED_UNICODE)) : 'mapi 无响应'; + addLogToFile('epay mapi 下单失败:order=' . $pay_orderid . ' err=' . $errMsg, 'epay_error', 'epay'); + $data = encrypt_data(['status' => 0, 'message' => 'Khởi tạo thanh toán thất bại: ' . $errMsg]); + return json(['Success' => 1, 'Data' => $data]); + } + + // epay 的 jump url 形如 https://pay.g7g7.top/pay/leader/2026041623400011168/ + $payUrl = $apiResult['url']; + $trade_no = ''; + if (preg_match('#/pay/leader/(\d+)/?#', $payUrl, $m)) { + $trade_no = $m[1]; + } + + // 默认返回结构(若后续读取 usdtpro 失败仍可回退跳转) $qrcode = null; - if ($pay_type === 'usdt' && $merchant_id > 0) { - $qrcode = $this->epay_create_usdt_pre_order( - $pay_orderid, - $money, - $goods_name, - $notify_url, - $return_url, - $merchant_id, - 'uid:' . $user_id + + if ($pay_type === 'usdt' && $trade_no) { + // 从 epay.pre_order 读 epay 已经算好的 usdtpro 指纹金额 + 通道地址 + $preOrder = Db::query( + "SELECT o.`trade_no`, o.`usdtpro`, o.`realmoney`, o.`addtime`, c.`config` + FROM `epay`.`pre_order` o + LEFT JOIN `epay`.`pre_channel` c ON c.`id` = o.`channel` + WHERE o.`trade_no` = :tn LIMIT 1", + ['tn' => $trade_no] ); + + if (!empty($preOrder) && !empty($preOrder[0]['usdtpro'])) { + $row = $preOrder[0]; + $cfg = json_decode($row['config'] ?? '{}', true) ?: []; + $timeout = intval($cfg['timeout'] ?? 600); + $expiresAt = strtotime($row['addtime']) + $timeout; + + $qrcode = [ + 'order_sn' => $pay_orderid, + 'trade_no' => $row['trade_no'], + 'usdt_address' => $cfg['address'] ?? '', + 'usdt_amount' => rtrim(rtrim(sprintf('%.5f', floatval($row['usdtpro'])), '0'), '.'), + 'vnd_amount' => $row['realmoney'], + 'rate' => strval($cfg['rate'] ?? ''), + 'expires_at' => $expiresAt, + 'timeout_sec' => $timeout, + ]; + addLogToFile('epay 下单读取 usdtpro 成功: order=' . $pay_orderid . ' trade_no=' . $trade_no . ' usdt=' . $qrcode['usdt_amount'], 'epay_request', 'epay'); + } else { + addLogToFile('epay 下单 pre_order 未取到 usdtpro: order=' . $pay_orderid . ' trade_no=' . $trade_no, 'epay_error', 'epay'); + } } $data = encrypt_data([ 'status' => 1, - 'message' => '发起支付成功', + 'message' => 'Khởi tạo thanh toán thành công', 'url' => $payUrl, // 兼容老前端 - 'qrcode' => $qrcode, // 新前端内嵌渲染用 + 'qrcode' => $qrcode, // 新前端内嵌渲染用(usdtpro 由 epay 权威给出) ]); return json(['Success' => 1, 'Data' => $data]); } catch (\Exception $e) { addLogToFile('epay 下单异常:' . $e->getMessage() . ' | file:' . $e->getFile() . ':' . $e->getLine(), 'epay_error', 'epay'); - $data = encrypt_data(['status' => 0, 'message' => '支付发起失败[' . $e->getMessage() . ']']); + $data = encrypt_data(['status' => 0, 'message' => 'Khởi tạo thanh toán thất bại: ' . $e->getMessage()]); return json(['Success' => 1, 'Data' => $data]); } } - /** - * 跨库创建 epay.pre_order 并算 usdtpro 指纹金额 - * - * 算法对齐 pay.g7g7.top/plugins/usdtpro/usdtpro_plugin.php::submit(): - * - 指纹金额 = round(realmoney / rate, 4) - * - 同通道+同金额+未超时订单存在则 +0.0001 递增错开 - */ - private function epay_create_usdt_pre_order($orderNo, $money, $goodsName, $notifyUrl, $returnUrl, $pid, $param = '') - { - // 查 usdtpro 通道(写死 plugin=usdtpro,status=1) - $channel = Db::query("SELECT `id`, `config`, `rate` FROM `epay`.`pre_channel` WHERE `plugin`='usdtpro' AND `status`=1 LIMIT 1"); - if (empty($channel)) { - addLogToFile('epay USDT 通道未启用:order=' . $orderNo, 'epay_error', 'epay'); - return null; - } - $channel = $channel[0]; - $channel_config = json_decode($channel['config'], true); - if (!$channel_config || empty($channel_config['address'])) { - addLogToFile('epay USDT 通道配置缺失 address:order=' . $orderNo, 'epay_error', 'epay'); - return null; - } - $address = $channel_config['address']; - $rate = floatval($channel_config['rate'] ?? 100000); - $timeout = intval($channel_config['timeout'] ?? 600); - - // usdt type id(按插件约定 usdt -> pre_type.id=7,但直接查一下更稳) - $typeRow = Db::query("SELECT `id` FROM `epay`.`pre_type` WHERE `name`='usdt' AND `status`=1 LIMIT 1"); - if (empty($typeRow)) { - addLogToFile('epay pre_type usdt 未启用', 'epay_error', 'epay'); - return null; - } - $type_id = intval($typeRow[0]['id']); - - // 算指纹金额(碰撞检测) - $unique_usdt = round($money / $rate, 4); - $max_try = 100; - while ($max_try-- > 0) { - $same = Db::query( - "SELECT 1 FROM `epay`.`pre_order` WHERE `channel`=:ch AND `usdtpro`=:amt AND UNIX_TIMESTAMP(`addtime`) + :win >= :now LIMIT 1", - [ - 'ch' => $channel['id'], - 'amt' => $unique_usdt, - 'win' => $timeout * 3, - 'now' => time(), - ] - ); - if (empty($same)) { - break; - } - $unique_usdt = round($unique_usdt + 0.0001, 4); - } - - // epay 侧的 trade_no(YmdHis + 5 随机) - $trade_no = date('YmdHis') . rand(11111, 99999); - $realmoney = sprintf('%.2f', $money); - $domain = parse_url($notifyUrl, PHP_URL_HOST) ?: ''; - - Db::execute( - "INSERT INTO `epay`.`pre_order` - (`trade_no`, `out_trade_no`, `uid`, `type`, `channel`, `name`, `money`, `realmoney`, `getmoney`, - `notify_url`, `return_url`, `param`, `addtime`, `date`, `domain`, `ip`, `status`, `version`, `usdtpro`) - VALUES - (:trade_no, :out_trade_no, :uid, :type, :channel, :name, :money, :realmoney, :getmoney, - :notify_url, :return_url, :param, NOW(), CURDATE(), :domain, :ip, 0, 1, :usdtpro)", - [ - 'trade_no' => $trade_no, - 'out_trade_no' => $orderNo, - 'uid' => $pid, - 'type' => $type_id, - 'channel' => $channel['id'], - 'name' => $goodsName, - 'money' => $realmoney, - 'realmoney' => $realmoney, - 'getmoney' => $realmoney, - 'notify_url' => $notifyUrl, - 'return_url' => $returnUrl, - 'param' => $param, - 'domain' => $domain, - 'ip' => Request::instance()->ip(), - 'usdtpro' => $unique_usdt, - ] - ); - - $expires_at = time() + $timeout; - addLogToFile('epay USDT 内嵌下单成功: order=' . $orderNo . ' trade_no=' . $trade_no . ' usdt=' . $unique_usdt, 'epay_request', 'epay'); - - return [ - 'order_sn' => $orderNo, - 'trade_no' => $trade_no, - 'usdt_address' => $address, - 'usdt_amount' => sprintf('%.4f', $unique_usdt), - 'vnd_amount' => $realmoney, - 'rate' => (string) $rate, - 'expires_at' => $expires_at, - 'timeout_sec' => $timeout, - ]; - } - /** * 易支付 - 订单状态轮询 * From 9ca6c646db49f2fbeb63d0b171371a2bc014aa37 Mon Sep 17 00:00:00 2001 From: testadmin Date: Thu, 16 Apr 2026 23:49:52 +0800 Subject: [PATCH 06/32] =?UTF-8?q?fix(epay):=20createOrderApi=20=E8=A1=A5?= =?UTF-8?q?=E4=BC=A0=20clientip=20=E5=8F=82=E6=95=B0=EF=BC=88mapi.php=20?= =?UTF-8?q?=E5=BF=85=E5=A1=AB=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extend/pay/Epay.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/extend/pay/Epay.php b/extend/pay/Epay.php index 9de924b..521349a 100644 --- a/extend/pay/Epay.php +++ b/extend/pay/Epay.php @@ -131,10 +131,14 @@ class Epay /** * API 模式下单(mapi.php) * + * @param string $clientIp 下单用户的 IP(mapi.php 必填,否则报 "用户IP地址(clientip)不能为空") * @return array|null */ - public function createOrderApi($orderNo, $type, $amount, $name, $notifyUrl, $returnUrl = '', $param = '') + public function createOrderApi($orderNo, $type, $amount, $name, $notifyUrl, $returnUrl = '', $param = '', $clientIp = '') { + if ($clientIp === '' || $clientIp === null) { + $clientIp = \think\Request::instance()->ip(); + } $params = [ 'pid' => strval($this->config['pid'] ?? ''), 'type' => $type, @@ -144,6 +148,7 @@ class Epay 'name' => $name, 'money' => strval($amount), 'param' => $param, + 'clientip' => strval($clientIp), 'sign_type' => 'MD5', ]; $params['sign'] = $this->generateSign($params); From ffc77b4f3fea99d09abab60edc4cdaffe993fb2a Mon Sep 17 00:00:00 2001 From: testadmin Date: Thu, 16 Apr 2026 23:53:00 +0800 Subject: [PATCH 07/32] =?UTF-8?q?fix(epay):=20=E8=A1=A5=E5=8F=91=20/pay/su?= =?UTF-8?q?bmit=20=E8=AF=B7=E6=B1=82=E8=A7=A6=E5=8F=91=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=20submit()=20=E5=86=99=E5=85=A5=20usdtpro=20=E9=87=91=E9=A2=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onlinechip/controller/traits/epayPay.php | 52 ++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/application/onlinechip/controller/traits/epayPay.php b/application/onlinechip/controller/traits/epayPay.php index e51e38b..ced541f 100644 --- a/application/onlinechip/controller/traits/epayPay.php +++ b/application/onlinechip/controller/traits/epayPay.php @@ -175,19 +175,33 @@ trait epayPay 'uid:' . $user_id ); - if (!is_array($apiResult) || empty($apiResult['url'])) { + // mapi.php 返回格式: + // {code:0, trade_no, pay_type:'jump', pay_info:'/pay/submit/TRADE_NO/'} 或 + // {code:0, trade_no, payurl:'/pay/submit/TRADE_NO/'} (default 分支) + // {code:1, trade_no, payurl:'...'} (部分旧版) + $submitUrl = ''; + $trade_no = ''; + if (is_array($apiResult)) { + if (!empty($apiResult['trade_no'])) $trade_no = strval($apiResult['trade_no']); + if (!empty($apiResult['payurl'])) $submitUrl = $apiResult['payurl']; + elseif (!empty($apiResult['pay_info'])) $submitUrl = $apiResult['pay_info']; + elseif (!empty($apiResult['url'])) $submitUrl = $apiResult['url']; + } + + if (!$submitUrl || !$trade_no) { $errMsg = is_array($apiResult) ? (isset($apiResult['msg']) ? $apiResult['msg'] : json_encode($apiResult, JSON_UNESCAPED_UNICODE)) : 'mapi 无响应'; addLogToFile('epay mapi 下单失败:order=' . $pay_orderid . ' err=' . $errMsg, 'epay_error', 'epay'); $data = encrypt_data(['status' => 0, 'message' => 'Khởi tạo thanh toán thất bại: ' . $errMsg]); return json(['Success' => 1, 'Data' => $data]); } - // epay 的 jump url 形如 https://pay.g7g7.top/pay/leader/2026041623400011168/ - $payUrl = $apiResult['url']; - $trade_no = ''; - if (preg_match('#/pay/leader/(\d+)/?#', $payUrl, $m)) { - $trade_no = $m[1]; - } + // 触发 plugin::submit() 把 usdtpro 指纹金额写入 pre_order + // mapi 模式 Plugin::loadForSubmit 只调 mapi() 方法,usdtpro 插件没这个方法, + // 所以 usdtpro 不会被写入。必须再访问一次 /pay/submit/TRADE_NO/ 让插件 submit() 跑一次 + $this->epay_trigger_plugin_submit($submitUrl); + + // 跳转到用户看的页面(pay/leader/TRADE_NO/) + $payUrl = str_replace('/pay/submit/', '/pay/leader/', $submitUrl); // 默认返回结构(若后续读取 usdtpro 失败仍可回退跳转) $qrcode = null; @@ -238,6 +252,30 @@ trait epayPay } } + /** + * 触发 epay plugin::submit() 写入 usdtpro 指纹金额 + * 只请求不处理响应(epay 会返回 302 或 HTML,我们只要副作用) + */ + private function epay_trigger_plugin_submit($submitUrl) + { + try { + $ch = curl_init($submitUrl); + curl_setopt_array($ch, [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_FOLLOWLOCATION => false, + CURLOPT_CONNECTTIMEOUT => 3, + CURLOPT_TIMEOUT => 6, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_SSL_VERIFYHOST => false, + CURLOPT_USERAGENT => 'OG-EpayInternal/1.0', + ]); + curl_exec($ch); + curl_close($ch); + } catch (\Exception $e) { + addLogToFile('epay_trigger_plugin_submit 异常:' . $e->getMessage(), 'epay_error', 'epay'); + } + } + /** * 易支付 - 订单状态轮询 * From 2e9462d7a3ca3ea629c369d56f5f1fdce00ca223 Mon Sep 17 00:00:00 2001 From: testadmin Date: Mon, 20 Apr 2026 11:15:16 +0800 Subject: [PATCH 08/32] =?UTF-8?q?feat:=20=E6=8E=A5=E5=85=A5=20CCpay=20?= =?UTF-8?q?=E7=AC=AC=E4=B8=89=E6=94=AF=E4=BB=98=E9=80=9A=E9=81=93=EF=BC=88?= =?UTF-8?q?=E8=B6=8A=E5=8D=97=E9=93=B6=E8=A1=8CQR=E4=BB=A3=E6=94=B6?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - extend/pay/Ccpay.php: SDK封装(签名/验签/下单/查询) - traits/ccpayPay.php: 下单/回调/结算/轮询,pay_channel_id=9 - config.php: pay_list 加 ccpay 配置 - Pcapi/Order: 注册 ccpayPay trait --- application/config.php | 10 + application/onlinechip/controller/Order.php | 1 + application/onlinechip/controller/Pcapi.php | 1 + .../onlinechip/controller/traits/ccpayPay.php | 411 ++++++++++++++++++ extend/pay/Ccpay.php | 132 ++++++ 5 files changed, 555 insertions(+) create mode 100644 application/onlinechip/controller/traits/ccpayPay.php create mode 100644 extend/pay/Ccpay.php diff --git a/application/config.php b/application/config.php index 2438492..1f0adab 100644 --- a/application/config.php +++ b/application/config.php @@ -373,5 +373,15 @@ return [ // 'wxpay' => '微信支付', ] ], + 'ccpay' => [//CCmerchant越南银行代收 + 'online_order_fac' => 'ccpay_online_order', + 'notify_url' => 'https://api.g7g7.top/order/ccpay_recharge_callback', + 'callback_url' => '', + 'api_url' => 'https://c.gmobvfxllc.com/gateway/api/trade', + 'mch_no' => 'M8822026041910000352', + 'pay_secret' => '820281b0d0b24a6bb701d8fc1c31a197', + 'timeout' => 600, + 'type' => ['pay' => 'CCpay越南银行'], + ], ] ]; diff --git a/application/onlinechip/controller/Order.php b/application/onlinechip/controller/Order.php index 2b35bab..185d145 100644 --- a/application/onlinechip/controller/Order.php +++ b/application/onlinechip/controller/Order.php @@ -15,6 +15,7 @@ class Order Extends Controller{ use traits\hengfuPay; use traits\alinPay; use traits\epayPay; + use traits\ccpayPay; public function __construct() { diff --git a/application/onlinechip/controller/Pcapi.php b/application/onlinechip/controller/Pcapi.php index 37b9beb..d88c117 100755 --- a/application/onlinechip/controller/Pcapi.php +++ b/application/onlinechip/controller/Pcapi.php @@ -18,6 +18,7 @@ use Waybill\WaybillRoulette; class Pcapi extends Controller{ use traits\alinPay; use traits\epayPay; + use traits\ccpayPay; public function __construct(){ parent::__construct(); // CORS headers diff --git a/application/onlinechip/controller/traits/ccpayPay.php b/application/onlinechip/controller/traits/ccpayPay.php new file mode 100644 index 0000000..9a59939 --- /dev/null +++ b/application/onlinechip/controller/traits/ccpayPay.php @@ -0,0 +1,411 @@ +post(); + if (isset($post['encryptData'])) { + $post = decrypt_data($post); + if (!$post) { + $data = encrypt_data(['status' => 0, 'message' => 'Dữ liệu không hợp lệ']); + return json(['Success' => 1, 'Data' => $data]); + } + } + + $user_id = intval($post['user_id'] ?? 0); + $money = intval($post['price'] ?? 0); + $client = intval($post['client'] ?? 0); + $username = trim($post['username'] ?? ''); + + $user = Db::name('user')->where([ + 'id' => $user_id, + 'status' => 1, + 'is_delete' => 0, + 'agent' => 0, + ])->find(); + + if (!$user || $user_id <= 0 || $money <= 0 || $client <= 0) { + $data = encrypt_data(['status' => 0, 'message' => 'Tham số không hợp lệ, vui lòng thử lại']); + return json(['Success' => 1, 'Data' => $data]); + } + + $zdlIdArr = explode(',', $user['agent_parent_id_path']); + $area_list = config('area_list'); + + if (!isset($area_list[$user['area_id']])) { + $data = encrypt_data(['status' => 0, 'message' => 'Khu vực hiện chưa hỗ trợ nạp tiền']); + return json(['Success' => 1, 'Data' => $data]); + } + + $isAllow = false; + foreach ($area_list[$user['area_id']]['limit_agent'] as $allowAgentId) { + if (in_array($allowAgentId, $zdlIdArr)) { + $isAllow = true; + } + } + if (!$isAllow) { + $data = encrypt_data(['status' => 0, 'message' => 'Tài khoản này chưa được phép nạp online']); + return json(['Success' => 1, 'Data' => $data]); + } + + $zdlId = $zdlIdArr[0]; + $zdl = Db::name('user')->where([ + 'id' => $zdlId, + 'status' => 1, + 'is_delete' => 0, + 'agent' => 1, + ])->find(); + + if (!$zdl) { + $data = encrypt_data(['status' => 0, 'message' => 'Tài khoản đại lý có vấn đề, không thể nạp']); + return json(['Success' => 1, 'Data' => $data]); + } + if ($zdl['money'] < $money) { + $maxAllowed = intval($zdl['money']); + $data = encrypt_data([ + 'status' => 0, + 'code' => 'AGENT_LIMIT', + 'message' => 'Hạn mức nạp mỗi lần hiện tại là ' . number_format($maxAllowed, 0, '.', ',') . ' VND. Vui lòng nhập số tiền nhỏ hơn hoặc bằng mức trên.', + 'max_amount' => $maxAllowed, + ]); + return json(['Success' => 1, 'Data' => $data]); + } + + $pay_list = config('pay_list'); + $pay_orderid = 'C' . date('YmdHis') . rand(100000, 999999); + $notify_url = $pay_list['ccpay']['notify_url'] ?? ''; + $timeout = intval($pay_list['ccpay']['timeout'] ?? 600); + + try { + $ccpay = new \pay\Ccpay(); + $result = $ccpay->createOrder( + $pay_orderid, + sprintf('%.0f', $money), + $notify_url, + 'uid_' . $user_id + ); + + if (!is_array($result)) { + addLogToFile('ccpay 下单: API 无响应', 'ccpay_error', 'ccpay'); + $data = encrypt_data(['status' => 0, 'message' => 'Kênh thanh toán không phản hồi, vui lòng thử lại']); + return json(['Success' => 1, 'Data' => $data]); + } + + $status = intval($result['status'] ?? -1); + $resultCode = intval($result['resultCode'] ?? -1); + + if ($status !== 0 || $resultCode !== 0) { + $errMsg = $result['errMsg'] ?? 'Lỗi không xác định'; + addLogToFile('ccpay 下单失败: order=' . $pay_orderid . ' err=' . $errMsg . ' raw=' . json_encode($result, JSON_UNESCAPED_UNICODE), 'ccpay_error', 'ccpay'); + $data = encrypt_data(['status' => 0, 'message' => 'Khởi tạo thanh toán thất bại: ' . $errMsg]); + return json(['Success' => 1, 'Data' => $data]); + } + + $order_id = Db::name('order_record')->insertGetId([ + 'pay_channel_id' => 9, + 'pay_channel_name' => 'ccpay', + 'user_id' => $user_id, + 'order_sn' => $pay_orderid, + 'appid' => $ccpay->getConfigInfo()['mch_no'] ?? '', + 'api_key' => '', + 'money' => $money, + 'sign' => '', + 'create_time' => time(), + 'back_order_sn' => $result['cpOrderNo'] ?? '', + 'client' => $client, + ]); + + Db::name('order_log')->insert([ + 'pay_channel_id' => 9, + 'pay_channel_name' => 'ccpay', + 'money' => $money, + 'create_time' => time(), + 'remake' => 'user_id:' . $user_id . ',用户名:' . $username . ',CCpay发起充值:' . $money . ',时间:' . date('Y-m-d H:i:s'), + 'order_id' => $order_id, + 'client' => $client, + ]); + + $codeUrl = $result['codeUrl'] ?? ''; + $qrcode = null; + + $msgJson = $result['message'] ?? ''; + if ($msgJson) { + $bankInfo = json_decode($msgJson, true); + if (is_array($bankInfo) && !empty($bankInfo['AccNo'])) { + $expiresAt = time() + $timeout; + $qrcode = [ + 'order_sn' => $pay_orderid, + 'bank_account' => $bankInfo['AccNo'] ?? '', + 'bank_name' => $bankInfo['AccName'] ?? '', + 'bank_branch' => $bankInfo['Branch'] ?? '', + 'bank_short' => $bankInfo['BankShortName'] ?? '', + 'qr_data' => $bankInfo['qrcode'] ?? '', + 'remark' => $bankInfo['remark'] ?? '', + 'amount' => $money, + 'expires_at' => $expiresAt, + 'timeout_sec' => $timeout, + ]; + } + } + + addLogToFile('ccpay 下单成功: order=' . $pay_orderid . ' cp=' . ($result['cpOrderNo'] ?? ''), 'ccpay_request', 'ccpay'); + + $data = encrypt_data([ + 'status' => 1, + 'message' => 'Khởi tạo thanh toán thành công', + 'url' => $codeUrl, + 'qrcode' => $qrcode, + ]); + return json(['Success' => 1, 'Data' => $data]); + } catch (\Exception $e) { + addLogToFile('ccpay 下单异常: ' . $e->getMessage() . ' | file:' . $e->getFile() . ':' . $e->getLine(), 'ccpay_error', 'ccpay'); + $data = encrypt_data(['status' => 0, 'message' => 'Khởi tạo thanh toán thất bại: ' . $e->getMessage()]); + return json(['Success' => 1, 'Data' => $data]); + } + } + + public function ccpay_order_status() + { + $post = Request::instance()->post(); + if (isset($post['encryptData'])) { + $post = decrypt_data($post); + if (!$post) { + return json(['status' => 0, 'message' => '数据解密失败']); + } + } + + $order_sn = trim($post['order_sn'] ?? ''); + $user_id = intval($post['user_id'] ?? 0); + + if ($order_sn === '' || $user_id <= 0) { + $data = encrypt_data(['status' => 0, 'message' => '参数错误']); + return json(['Success' => 1, 'Data' => $data]); + } + + $order = Db::name('order_record') + ->where([ + 'order_sn' => $order_sn, + 'user_id' => $user_id, + 'pay_channel_id' => 9, + ]) + ->find(); + + if (!$order) { + $data = encrypt_data(['status' => 0, 'message' => '订单不存在']); + return json(['Success' => 1, 'Data' => $data]); + } + + if (intval($order['status']) == 3) { + $data = encrypt_data([ + 'status' => 1, + 'message' => 'Nạp tiền thành công', + 'money' => $order['money'], + 'paid_time' => $order['back_time'], + ]); + return json(['Success' => 1, 'Data' => $data]); + } + + $pay_list = config('pay_list'); + $timeout = intval($pay_list['ccpay']['timeout'] ?? 600); + if (time() - intval($order['create_time']) > $timeout) { + $data = encrypt_data([ + 'status' => 2, + 'message' => 'Đơn hàng đã hết hạn', + 'money' => $order['money'], + ]); + return json(['Success' => 1, 'Data' => $data]); + } + + $data = encrypt_data([ + 'status' => 0, + 'message' => 'Đang chờ thanh toán', + 'money' => $order['money'], + ]); + return json(['Success' => 1, 'Data' => $data]); + } + + public function ccpay_recharge_callback() + { + $raw = file_get_contents('php://input'); + $post = json_decode($raw, true); + if (!$post) { + $post = Request::instance()->post(); + } + + $json = json_encode($post, JSON_UNESCAPED_UNICODE); + addLogToFile('ccpay 回调原始数据: ' . $json, 'ccpay_callback', 'ccpay'); + + if (!is_array($post) || empty($post['mchOrderNo']) || empty($post['sign'])) { + Log::record($post, 'ccpay_error_callback'); + exit('fail'); + } + + $logId = Db::name('pay_callback_log')->insertGetId([ + 'pay_channel' => 'CCPAY_RECHARGE', + 'type' => 'recharge', + 'json' => $json, + 'create_time' => date('Y-m-d H:i:s'), + ]); + + try { + $ccpay = new \pay\Ccpay(); + + $verifyData = []; + $verifyData['status'] = strval($post['status'] ?? ''); + $verifyData['mchNo'] = $post['mchNo'] ?? ''; + $verifyData['resultCode'] = strval($post['resultCode'] ?? ''); + $verifyData['cpOrderNo'] = $post['cpOrderNo'] ?? ''; + $verifyData['mchOrderNo'] = $post['mchOrderNo'] ?? ''; + $verifyData['amount'] = strval($post['amount'] ?? ''); + $verifyData['payResult'] = $post['payResult'] ?? ''; + $verifyData['traceTime'] = $post['traceTime'] ?? ''; + $verifyData['message'] = $post['message'] ?? ''; + + $signData = array_filter($verifyData, function ($v) { + return $v !== '' && $v !== null; + }); + $signData['sign'] = $post['sign']; + + if (!$ccpay->verifySign($signData)) { + addLogToFile('ccpay 回调验签失败: ' . $json, 'ccpay_callback_error', 'ccpay'); + exit('fail'); + } + + if ($logId && !empty($post['mchOrderNo'])) { + Db::name('pay_callback_log')->where('id', $logId)->update(['unique_no' => $post['mchOrderNo']]); + } + + $payResult = strval($post['payResult'] ?? ''); + + if ($payResult === '0') { + $this->ccpay_recharge_settle($post); + addLogToFile('ccpay 回调成功: order=' . $post['mchOrderNo'], 'ccpay_callback', 'ccpay'); + exit('success'); + } else { + addLogToFile('ccpay 回调非成功状态: payResult=' . $payResult . ' order=' . $post['mchOrderNo'], 'ccpay_callback', 'ccpay'); + exit('success'); + } + } catch (\Exception $e) { + addLogToFile('ccpay 回调异常: ' . $e->getMessage(), 'ccpay_callback_error', 'ccpay'); + exit('fail'); + } + } + + private function ccpay_recharge_settle($data) + { + $orderNo = $data['mchOrderNo']; + + Db::startTrans(); + try { + $order = Db::name('order_record')->where('order_sn', $orderNo)->lock(true)->find(); + if (!$order || $order['status'] == 3) { + Db::rollback(); + return; + } + + $user = Db::name('user')->where([ + 'id' => $order['user_id'], + 'status' => 1, + 'is_delete' => 0, + 'agent' => 0, + ])->lock(true)->find(); + if (!$user) { + Db::rollback(); + return; + } + + $zdlIdArr = explode(',', $user['agent_parent_id_path']); + $zdlId = $zdlIdArr[0]; + + $zdl = Db::name('user')->where([ + 'id' => $zdlId, + 'status' => 1, + 'is_delete' => 0, + 'agent' => 1, + ])->lock(true)->find(); + + if (!$zdl || $zdl['money'] < $order['money']) { + Db::rollback(); + addLogToFile('ccpay 结算失败: 代理余额不足 order=' . $orderNo, 'ccpay_callback_error', 'ccpay'); + return; + } + + $actualMoney = isset($data['amount']) ? intval($data['amount']) : $order['money']; + + Db::name('order_record')->where('id', $order['id'])->update([ + 'back_money' => $actualMoney, + 'back_time' => time(), + 'status' => 3, + 'agent_parent_id' => $user['agent_parent_id'], + 'agent_parent_username' => $user['agent_parent_username'], + 'zdl_id' => $zdl['id'], + 'zdl_username' => $zdl['username'], + 'zdl_money_before' => $zdl['money'], + 'zdl_money_after' => $zdl['money'] - $order['money'], + 'money_before' => $user['money'], + 'money_after' => $user['money'] + $order['money'], + ]); + + Db::name('order_log')->insert([ + 'pay_channel_id' => 9, + 'pay_channel_name' => 'ccpay', + 'money' => $order['money'], + 'create_time' => time(), + 'remake' => 'CCpay回调成功 cp=' . ($data['cpOrderNo'] ?? '') . ' payer=' . ($data['message'] ?? ''), + 'order_id' => $order['id'], + ]); + + Db::name('recharge')->insert([ + 'type' => 4, + 'amount' => $order['money'], + 'mode' => 1, + 'agent_or_admin' => 3, + 'controller_id' => $zdl['id'], + 'controller_username' => $zdl['username'], + 'controller_nickname' => $zdl['nickname'], + 'controller_type' => 'CCpay越南银行第三方充值,扣取总代理余分', + 'controller_old_money' => $zdl['money'], + 'controller_new_money' => $zdl['money'] - $order['money'], + 'user_id' => $order['user_id'], + 'user_type' => $user['agent'], + 'user_agent_level' => 0, + 'username_for' => $user['username'], + 'nickname_for' => $user['nickname'], + 'user_parent_id' => $user['agent_parent_id'], + 'create_time' => time(), + 'old_money' => $user['money'], + 'new_money' => $user['money'] + $order['money'], + 'controller_system' => 3, + 'remake' => 'CCpay越南银行第三方充值成功', + ]); + + Db::name('user')->where('id', $zdl['id'])->update([ + 'money' => $zdl['money'] - $order['money'], + 'last_recharge_out' => $order['money'], + 'last_recharge_out_time' => time(), + 'recharge_out_count' => $zdl['recharge_out_count'] + 1, + 'recharge_out_total_amount' => $zdl['recharge_out_total_amount'] + $order['money'], + ]); + + Db::name('user')->where('id', $order['user_id'])->update([ + 'money' => $user['money'] + $order['money'], + 'last_recharge' => $order['money'], + 'last_recharge_time' => time(), + 'recharge_count' => $user['recharge_count'] + 1, + 'recharge_total_amount' => $user['recharge_total_amount'] + $order['money'], + ]); + + Db::commit(); + addLogToFile('ccpay 结算成功: order=' . $orderNo . ' money=' . $order['money'], 'ccpay_callback', 'ccpay'); + } catch (\Exception $e) { + Db::rollback(); + addLogToFile('ccpay 结算异常: ' . $e->getMessage(), 'ccpay_callback_error', 'ccpay'); + } + } +} diff --git a/extend/pay/Ccpay.php b/extend/pay/Ccpay.php new file mode 100644 index 0000000..447f3c3 --- /dev/null +++ b/extend/pay/Ccpay.php @@ -0,0 +1,132 @@ +config = config('pay_list.ccpay') ?: []; + $this->apiUrl = $this->config['api_url'] ?? ''; + $this->mchNo = $this->config['mch_no'] ?? ''; + $this->paySecret = $this->config['pay_secret'] ?? ''; + } + + public function getConfigInfo() + { + return $this->config; + } + + public function generateSign(array $params) + { + unset($params['sign']); + ksort($params); + $str = ''; + foreach ($params as $k => $v) { + if (is_string($v) && strlen($v) > 0) { + $str .= "{$k}={$v}&"; + } + } + $str = substr($str, 0, -1) . '&paySecret=' . $this->paySecret; + return strtoupper(md5($str)); + } + + public function verifySign(array $params) + { + $received = $params['sign'] ?? ''; + if (!$received) return false; + $calculated = $this->generateSign($params); + return hash_equals($calculated, $received); + } + + public function createOrder($orderNo, $amount, $notifyUrl, $memberId = 'og_user', $callbackUrl = '') + { + $extra = [ + 'bankType' => 'OFFLINE', + 'cardType' => '0', + 'orderPeriod' => '30', + 'memberId' => $memberId, + 'merchantName' => 'OG', + 'notifyUrl' => $notifyUrl, + 'callbackUrl' => $callbackUrl, + ]; + + $data = [ + 'tradeType' => 'cs.pay.submit', + 'version' => '2.0', + 'channel' => 'union_pay', + 'mchNo' => $this->mchNo, + 'body' => 'online_pay', + 'mchOrderNo' => $orderNo, + 'amount' => strval(intval($amount)), + 'currency' => 'VND', + 'timePaid' => date('YmdHis'), + 'remark' => 'online-pay', + ]; + + $signParams = array_merge($data, $extra); + $data['sign'] = $this->generateSign($signParams); + $data['extra'] = json_encode($extra); + + addLogToFile('ccpay 下单请求: order=' . $orderNo . ' amount=' . $amount . ' params=' . json_encode($data, JSON_UNESCAPED_UNICODE), 'ccpay_request', 'ccpay'); + + $result = $this->postForm($this->apiUrl, $data); + + addLogToFile('ccpay 下单返回: ' . json_encode($result, JSON_UNESCAPED_UNICODE), 'ccpay_response', 'ccpay'); + + return $result; + } + + public function queryOrder($orderNo) + { + $data = [ + 'tradeType' => 'cs.order.query', + 'version' => '2.0', + 'mchNo' => $this->mchNo, + 'mchOrderNo' => $orderNo, + ]; + $data['sign'] = $this->generateSign($data); + + return $this->postForm($this->apiUrl, $data); + } + + private function postForm($url, $params) + { + $ch = curl_init($url); + $body = ''; + foreach ($params as $k => $v) { + if (!is_string($v)) continue; + $body .= $k . '=' . urlencode($v) . '&'; + } + $body = rtrim($body, '&'); + + curl_setopt_array($ch, [ + CURLOPT_RETURNTRANSFER => true, + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => $body, + CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded; charset=UTF-8'], + CURLOPT_CONNECTTIMEOUT => 10, + CURLOPT_TIMEOUT => 30, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_SSL_VERIFYHOST => false, + ]); + + $resp = curl_exec($ch); + $err = curl_error($ch); + $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($resp === false) { + addLogToFile("ccpay curl 失败: code={$code} err={$err}", 'ccpay_error', 'ccpay'); + return null; + } + + return json_decode($resp, true); + } +} From a7edf5347d083631e375fe75f2636c2b939df189 Mon Sep 17 00:00:00 2001 From: testadmin Date: Sun, 26 Apr 2026 13:29:47 +0800 Subject: [PATCH 09/32] =?UTF-8?q?fix:=20=E6=96=B0=E5=BB=BA=E4=BB=A3?= =?UTF-8?q?=E7=90=86=E9=BB=98=E8=AE=A4=20area=5Fid=3D3=EF=BC=88=E8=B6=8A?= =?UTF-8?q?=E5=8D=97=EF=BC=89=EF=BC=8C=E4=BF=AE=E5=A4=8D=E6=97=A0=E5=9C=B0?= =?UTF-8?q?=E5=8C=BA=E4=BB=A3=E7=90=86=E4=B8=8B=E4=BC=9A=E5=91=98=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E5=85=85=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/admin/controller/Agent.php | 1 + 1 file changed, 1 insertion(+) diff --git a/application/admin/controller/Agent.php b/application/admin/controller/Agent.php index 911d240..e224bd1 100755 --- a/application/admin/controller/Agent.php +++ b/application/admin/controller/Agent.php @@ -433,6 +433,7 @@ class Agent extends Common{ $data['price_tc_ths'] = $price_tc_ths; $data['price_tc_hjths'] = $price_tc_hjths; + $data['area_id'] = 3; $data['referral_code'] = getRandCode(); // $data['agent_commission_tc'] = $agent_commission_tc; // $data['agent_commission_tc_banker'] = $agent_commission_tc_banker; From 13cd0cbea42a4dd9b59e72998f3e7e1bef462417 Mon Sep 17 00:00:00 2001 From: testadmin Date: Sun, 26 Apr 2026 20:10:26 +0800 Subject: [PATCH 10/32] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=20limit=5Fagent?= =?UTF-8?q?=20=E7=99=BD=E5=90=8D=E5=8D=95=E9=99=90=E5=88=B6=EF=BC=8C?= =?UTF-8?q?=E6=89=80=E6=9C=89=E4=BB=A3=E7=90=86=E4=B8=8B=E4=BC=9A=E5=91=98?= =?UTF-8?q?=E5=9D=87=E5=8F=AF=E5=85=85=E5=80=BC/=E6=8F=90=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - config.php: area_id=3 的 limit_agent 改为空数组 - Order.php/epayPay.php/ccpayPay.php: 空数组时跳过白名单检查 --- application/config.php | 2 +- application/onlinechip/controller/Order.php | 12 +++++++----- .../onlinechip/controller/traits/ccpayPay.php | 5 +++-- application/onlinechip/controller/traits/epayPay.php | 5 +++-- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/application/config.php b/application/config.php index 1f0adab..441330a 100644 --- a/application/config.php +++ b/application/config.php @@ -286,7 +286,7 @@ return [ 'pay' => 'alinPay', 'default_agent' => 111, 'default_wt_agent' => 111, - 'limit_agent' => [111], + 'limit_agent' => [], ], ], diff --git a/application/onlinechip/controller/Order.php b/application/onlinechip/controller/Order.php index 185d145..8a83f58 100644 --- a/application/onlinechip/controller/Order.php +++ b/application/onlinechip/controller/Order.php @@ -114,8 +114,9 @@ class Order Extends Controller{ $zdlIdArr = explode(',',$user['agent_parent_id_path']); $area_list = config('area_list'); //判断是否金流支线,如果不是的话,不允许充值 - $isAllow = false; - foreach($area_list[$user['area_id']]['limit_agent'] as $allowAgentId){ + $limitAgents = $area_list[$user['area_id']]['limit_agent']; + $isAllow = empty($limitAgents); + foreach($limitAgents as $allowAgentId){ if(in_array($allowAgentId,$zdlIdArr)){ $isAllow = true; } @@ -184,9 +185,10 @@ class Order Extends Controller{ $user = Db::name('user')->where(array('id' => $user_id))->find(); $zdlIdArr = explode(',',$user['agent_parent_id_path']); $area_list = config('area_list'); - //判断是否金流支线,如果不是的话,不允许充值 - $isAllow = false; - foreach($area_list[$user['area_id']]['limit_agent'] as $allowAgentId){ + //判断是否金流支线,如果不是的话,不允许提现 + $limitAgents = $area_list[$user['area_id']]['limit_agent']; + $isAllow = empty($limitAgents); + foreach($limitAgents as $allowAgentId){ if(in_array($allowAgentId,$zdlIdArr)){ $isAllow = true; } diff --git a/application/onlinechip/controller/traits/ccpayPay.php b/application/onlinechip/controller/traits/ccpayPay.php index 9a59939..3a56d52 100644 --- a/application/onlinechip/controller/traits/ccpayPay.php +++ b/application/onlinechip/controller/traits/ccpayPay.php @@ -43,8 +43,9 @@ trait ccpayPay return json(['Success' => 1, 'Data' => $data]); } - $isAllow = false; - foreach ($area_list[$user['area_id']]['limit_agent'] as $allowAgentId) { + $limitAgents = $area_list[$user['area_id']]['limit_agent']; + $isAllow = empty($limitAgents); + foreach ($limitAgents as $allowAgentId) { if (in_array($allowAgentId, $zdlIdArr)) { $isAllow = true; } diff --git a/application/onlinechip/controller/traits/epayPay.php b/application/onlinechip/controller/traits/epayPay.php index ced541f..a0425b6 100644 --- a/application/onlinechip/controller/traits/epayPay.php +++ b/application/onlinechip/controller/traits/epayPay.php @@ -88,8 +88,9 @@ trait epayPay return json(['Success' => 1, 'Data' => $data]); } - $isAllow = false; - foreach ($area_list[$user['area_id']]['limit_agent'] as $allowAgentId) { + $limitAgents = $area_list[$user['area_id']]['limit_agent']; + $isAllow = empty($limitAgents); + foreach ($limitAgents as $allowAgentId) { if (in_array($allowAgentId, $zdlIdArr)) { $isAllow = true; } From c2fa69ddcb8a05bdd006655a3ea95f5350ba4eac Mon Sep 17 00:00:00 2001 From: testadmin Date: Sun, 26 Apr 2026 20:23:51 +0800 Subject: [PATCH 11/32] =?UTF-8?q?fix:=20=E6=A0=A1=E9=AA=8C=20agent=5Ftype?= =?UTF-8?q?=20=E4=B8=8E=20pay=5Fchannel=20=E4=B8=80=E8=87=B4=E6=80=A7?= =?UTF-8?q?=EF=BC=8C=E9=98=B2=E6=AD=A2=E4=BA=BA=E5=B7=A5=E4=B8=8A=E5=88=86?= =?UTF-8?q?+=E5=9C=A8=E7=BA=BF=E6=B8=A0=E9=81=93=E9=94=99=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/admin/controller/Agent.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/application/admin/controller/Agent.php b/application/admin/controller/Agent.php index e224bd1..a0b751e 100755 --- a/application/admin/controller/Agent.php +++ b/application/admin/controller/Agent.php @@ -200,6 +200,9 @@ class Agent extends Common{ if( empty($pay_channel) ){ die(json_encode(['code'=>0,'msg'=>'请选择支付渠道'])); } + if( $agent_type == 2 && $pay_channel != 'OPR' ){ + die(json_encode(['code'=>0,'msg'=>'人工上分模式只能选OPR渠道'])); + } if( !in_array($type_xima,[1,2]) ){ die(json_encode(['code'=>0,'msg'=>'洗码方式错误'])); } From 3997bbd3cbac4cfd2d4e03c139c82f38c5bde614 Mon Sep 17 00:00:00 2001 From: testadmin Date: Sun, 26 Apr 2026 20:32:45 +0800 Subject: [PATCH 12/32] =?UTF-8?q?fix:=20alinPay.php=20=E8=A1=A5=E6=BC=8F?= =?UTF-8?q?=20limit=5Fagent=20=E7=A9=BA=E6=95=B0=E7=BB=84=E6=94=BE?= =?UTF-8?q?=E8=A1=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/onlinechip/controller/traits/alinPay.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/application/onlinechip/controller/traits/alinPay.php b/application/onlinechip/controller/traits/alinPay.php index c41c3e9..0c92fb3 100644 --- a/application/onlinechip/controller/traits/alinPay.php +++ b/application/onlinechip/controller/traits/alinPay.php @@ -50,8 +50,9 @@ trait alinPay return json(['status' => 0, 'message' => '所在地区暂不支持充值']); } - $isAllow = false; - foreach ($area_list[$user['area_id']]['limit_agent'] as $allowAgentId) { + $limitAgents = $area_list[$user['area_id']]['limit_agent']; + $isAllow = empty($limitAgents); + foreach ($limitAgents as $allowAgentId) { if (in_array($allowAgentId, $zdlIdArr)) { $isAllow = true; } From 0186f561c4ed016da8ef848485d171da21004b9d Mon Sep 17 00:00:00 2001 From: testadmin Date: Sat, 2 May 2026 00:06:07 +0800 Subject: [PATCH 13/32] =?UTF-8?q?fix:=20Pro=20=E8=B7=AF=E5=8D=95=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E8=A1=A5=E6=9F=A5=20luck=5Fsix/dragon=5Fseven/panda?= =?UTF-8?q?=5Feight?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PC/Game 前端路单走的是 Pro 的 deal/waybill API,不是 Socket 的 --- application/deal/controller/Index.php | 2 +- application/helper.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/application/deal/controller/Index.php b/application/deal/controller/Index.php index c100080..9f3eba8 100644 --- a/application/deal/controller/Index.php +++ b/application/deal/controller/Index.php @@ -245,7 +245,7 @@ class Index Extends Common{ // 验证靴ID if($boot_id > 0){ - $ns = Db::name($numberTabTable)->where(array('game_id' => $game_id, 'boot_id' => $boot_id, 'bet_status' => 3))->field('result,pair')->order('start_time ASC,id ASC')->select(); + $ns = Db::name($numberTabTable)->where(array('game_id' => $game_id, 'boot_id' => $boot_id, 'bet_status' => 3))->field('result,pair,luck_six,dragon_seven,panda_eight')->order('start_time ASC,id ASC')->select(); if($forecast == 1){ // 庄问路 $ns[] = array('result'=>1,'pair'=>0); diff --git a/application/helper.php b/application/helper.php index 96b2c8c..2a2c1f7 100644 --- a/application/helper.php +++ b/application/helper.php @@ -275,7 +275,7 @@ function waybill($ns){ $showRoadLocation = array(); foreach($showRoad as $k => $v){ foreach($v as $key => $val){ - $pushData = array('show_x' => $k + 1, 'show_y' =>$key + 1, 'result' => $val['result'], 'pair' => $val['pair']); + $pushData = array('show_x' => $k + 1, 'show_y' =>$key + 1, 'result' => $val['result'], 'pair' => $val['pair'], 'luck_six' => $val['luck_six'] ?? 0, 'dragon_seven' => $val['dragon_seven'] ?? 0, 'panda_eight' => $val['panda_eight'] ?? 0); array_push($showRoadLocation,$pushData); } } From 0bf387f7d5daf03cfcbdb960278eb2be8f0ec27e Mon Sep 17 00:00:00 2001 From: li Date: Sun, 24 May 2026 19:25:05 +0800 Subject: [PATCH 14/32] =?UTF-8?q?feat:=20=E7=BA=BF=E4=B8=8A=E8=87=AA?= =?UTF-8?q?=E5=8A=A9=E5=85=85=E5=80=BC=E4=B8=8D=E5=86=8D=E6=89=A3=E4=BB=A3?= =?UTF-8?q?=E7=90=86=E4=BD=99=E9=A2=9D=EF=BC=88=E7=B3=BB=E7=BB=9F=E7=9B=B4?= =?UTF-8?q?=E5=85=85=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 会员通过第三方支付通道线上充值时,不再检查/扣减总代理余额。 真金白银从支付通道进来,直接加分给会员。 改动覆盖全部9个支付通道trait: - 删除下单时的代理余额检查(不再拦截"余额不足") - 回调时只检查代理是否存在,不检查余额 - 不扣减代理money字段 - 充值记录标记为"系统直充"而非"扣取总代理余分" 代理手动给会员上分(信用盘模式)不受影响,仍然扣代理自己的分。 --- .../onlinechip/controller/traits/alinPay.php | 17 +++++-------- .../onlinechip/controller/traits/ccpayPay.php | 22 ++++------------- .../onlinechip/controller/traits/epayPay.php | 24 +++++-------------- .../onlinechip/controller/traits/happyPay.php | 16 +++++-------- .../controller/traits/hengfuPay.php | 16 +++++-------- .../onlinechip/controller/traits/hipPay.php | 16 +++++-------- .../onlinechip/controller/traits/oneGoPay.php | 16 +++++-------- .../onlinechip/controller/traits/tingPay.php | 16 +++++-------- .../controller/traits/yonghengPay.php | 16 +++++-------- 9 files changed, 53 insertions(+), 106 deletions(-) diff --git a/application/onlinechip/controller/traits/alinPay.php b/application/onlinechip/controller/traits/alinPay.php index 0c92fb3..0458b46 100644 --- a/application/onlinechip/controller/traits/alinPay.php +++ b/application/onlinechip/controller/traits/alinPay.php @@ -73,10 +73,6 @@ trait alinPay if (!$zdl) { return json(['status' => 0, 'message' => '所属代理账号异常,暂不能充值']); } - if ($zdl['money'] < $money) { - return json(['status' => 0, 'message' => '所属代理余额不足,暂不能充值']); - } - $pay_list = config('pay_list'); $pay_orderid = 'E' . date("YmdHis") . rand(100000, 999999); $notify_url = $pay_list['alinPay']['notify_url']; @@ -232,9 +228,9 @@ trait alinPay 'agent' => 1, ])->lock(true)->find(); - if (!$zdl || $zdl['money'] < $order['money']) { + if (!$zdl) { Db::rollback(); - addLogToFile('代收结算失败:代理余额不足 order=' . $orderNo, 'alin_callback_error', 'alin'); + addLogToFile('代收结算失败:无法找到总代理 order=' . $orderNo, 'alin_callback_error', 'alin'); return; } @@ -248,7 +244,7 @@ trait alinPay 'zdl_id' => $zdl['id'], 'zdl_username' => $zdl['username'], 'zdl_money_before' => $zdl['money'], - 'zdl_money_after' => $zdl['money'] - $order['money'], + 'zdl_money_after' => $zdl['money'], 'money_before' => $user['money'], 'money_after' => $user['money'] + $order['money'], ]); @@ -272,9 +268,9 @@ trait alinPay 'controller_id' => $zdl['id'], 'controller_username' => $zdl['username'], 'controller_nickname' => $zdl['nickname'], - 'controller_type' => '越南第三方充值平台充值,扣取总代理余分', + 'controller_type' => '越南第三方充值平台充值,系统直充', 'controller_old_money' => $zdl['money'], - 'controller_new_money' => $zdl['money'] - $order['money'], + 'controller_new_money' => $zdl['money'], 'user_id' => $order['user_id'], 'user_type' => $user['agent'], 'user_agent_level' => 0, @@ -288,9 +284,8 @@ trait alinPay 'remake' => '越南AlinPay第三方充值成功', ]); - // 4. 扣代理余额 + // 4. 更新代理统计(不扣余额) Db::name('user')->where('id', $zdl['id'])->update([ - 'money' => $zdl['money'] - $order['money'], 'last_recharge_out' => $order['money'], 'last_recharge_out_time' => time(), 'recharge_out_count' => $zdl['recharge_out_count'] + 1, diff --git a/application/onlinechip/controller/traits/ccpayPay.php b/application/onlinechip/controller/traits/ccpayPay.php index 3a56d52..3cfe73d 100644 --- a/application/onlinechip/controller/traits/ccpayPay.php +++ b/application/onlinechip/controller/traits/ccpayPay.php @@ -67,17 +67,6 @@ trait ccpayPay $data = encrypt_data(['status' => 0, 'message' => 'Tài khoản đại lý có vấn đề, không thể nạp']); return json(['Success' => 1, 'Data' => $data]); } - if ($zdl['money'] < $money) { - $maxAllowed = intval($zdl['money']); - $data = encrypt_data([ - 'status' => 0, - 'code' => 'AGENT_LIMIT', - 'message' => 'Hạn mức nạp mỗi lần hiện tại là ' . number_format($maxAllowed, 0, '.', ',') . ' VND. Vui lòng nhập số tiền nhỏ hơn hoặc bằng mức trên.', - 'max_amount' => $maxAllowed, - ]); - return json(['Success' => 1, 'Data' => $data]); - } - $pay_list = config('pay_list'); $pay_orderid = 'C' . date('YmdHis') . rand(100000, 999999); $notify_url = $pay_list['ccpay']['notify_url'] ?? ''; @@ -331,9 +320,9 @@ trait ccpayPay 'agent' => 1, ])->lock(true)->find(); - if (!$zdl || $zdl['money'] < $order['money']) { + if (!$zdl) { Db::rollback(); - addLogToFile('ccpay 结算失败: 代理余额不足 order=' . $orderNo, 'ccpay_callback_error', 'ccpay'); + addLogToFile('ccpay 结算失败: 无法找到总代理 order=' . $orderNo, 'ccpay_callback_error', 'ccpay'); return; } @@ -348,7 +337,7 @@ trait ccpayPay 'zdl_id' => $zdl['id'], 'zdl_username' => $zdl['username'], 'zdl_money_before' => $zdl['money'], - 'zdl_money_after' => $zdl['money'] - $order['money'], + 'zdl_money_after' => $zdl['money'], 'money_before' => $user['money'], 'money_after' => $user['money'] + $order['money'], ]); @@ -370,9 +359,9 @@ trait ccpayPay 'controller_id' => $zdl['id'], 'controller_username' => $zdl['username'], 'controller_nickname' => $zdl['nickname'], - 'controller_type' => 'CCpay越南银行第三方充值,扣取总代理余分', + 'controller_type' => 'CCpay越南银行第三方充值,系统直充', 'controller_old_money' => $zdl['money'], - 'controller_new_money' => $zdl['money'] - $order['money'], + 'controller_new_money' => $zdl['money'], 'user_id' => $order['user_id'], 'user_type' => $user['agent'], 'user_agent_level' => 0, @@ -387,7 +376,6 @@ trait ccpayPay ]); Db::name('user')->where('id', $zdl['id'])->update([ - 'money' => $zdl['money'] - $order['money'], 'last_recharge_out' => $order['money'], 'last_recharge_out_time' => time(), 'recharge_out_count' => $zdl['recharge_out_count'] + 1, diff --git a/application/onlinechip/controller/traits/epayPay.php b/application/onlinechip/controller/traits/epayPay.php index a0425b6..7465d4d 100644 --- a/application/onlinechip/controller/traits/epayPay.php +++ b/application/onlinechip/controller/traits/epayPay.php @@ -113,17 +113,6 @@ trait epayPay $data = encrypt_data(['status' => 0, 'message' => 'Tài khoản đại lý có vấn đề, không thể nạp']); return json(['Success' => 1, 'Data' => $data]); } - if ($zdl['money'] < $money) { - $maxAllowed = intval($zdl['money']); - $data = encrypt_data([ - 'status' => 0, - 'code' => 'AGENT_LIMIT', - 'message' => 'Hạn mức nạp mỗi lần hiện tại là ' . number_format($maxAllowed, 0, '.', ',') . ' VND. Vui lòng nhập số tiền nhỏ hơn hoặc bằng mức trên.', - 'max_amount' => $maxAllowed, - ]); - return json(['Success' => 1, 'Data' => $data]); - } - $pay_list = config('pay_list'); $pay_orderid = 'P' . date('YmdHis') . rand(100000, 999999); // P 前缀区分 AlinPay 的 E $notify_url = $pay_list['epay']['notify_url'] ?? ''; @@ -436,9 +425,9 @@ trait epayPay 'agent' => 1, ])->lock(true)->find(); - if (!$zdl || $zdl['money'] < $order['money']) { + if (!$zdl) { Db::rollback(); - addLogToFile('epay 结算失败:代理余额不足 order=' . $orderNo, 'epay_callback_error', 'epay'); + addLogToFile('epay 结算失败:无法找到总代理 order=' . $orderNo, 'epay_callback_error', 'epay'); return; } @@ -455,7 +444,7 @@ trait epayPay 'zdl_id' => $zdl['id'], 'zdl_username' => $zdl['username'], 'zdl_money_before' => $zdl['money'], - 'zdl_money_after' => $zdl['money'] - $order['money'], + 'zdl_money_after' => $zdl['money'], 'money_before' => $user['money'], 'money_after' => $user['money'] + $order['money'], ]); @@ -479,9 +468,9 @@ trait epayPay 'controller_id' => $zdl['id'], 'controller_username' => $zdl['username'], 'controller_nickname' => $zdl['nickname'], - 'controller_type' => '易支付第三方充值,扣取总代理余分', + 'controller_type' => '易支付第三方充值,系统直充', 'controller_old_money' => $zdl['money'], - 'controller_new_money' => $zdl['money'] - $order['money'], + 'controller_new_money' => $zdl['money'], 'user_id' => $order['user_id'], 'user_type' => $user['agent'], 'user_agent_level' => 0, @@ -495,9 +484,8 @@ trait epayPay 'remake' => '易支付第三方充值成功(' . ($data['type'] ?? '') . ')', ]); - // 4. 扣代理 + // 4. 更新代理统计(不扣余额) Db::name('user')->where('id', $zdl['id'])->update([ - 'money' => $zdl['money'] - $order['money'], 'last_recharge_out' => $order['money'], 'last_recharge_out_time' => time(), 'recharge_out_count' => $zdl['recharge_out_count'] + 1, diff --git a/application/onlinechip/controller/traits/happyPay.php b/application/onlinechip/controller/traits/happyPay.php index 4a035d2..19a46bc 100644 --- a/application/onlinechip/controller/traits/happyPay.php +++ b/application/onlinechip/controller/traits/happyPay.php @@ -30,9 +30,6 @@ trait happyPay{ if(!$zdl){ return json(array('status' => 0, 'message' => '所属代理账号异常,暂不能充值')); } - if($zdl['money'] < $money){ - return json(array('status' => 0, 'message' => '所属代理余额不足,暂不能充值')); - } $pay_list = config('pay_list'); if($user && $user_id > 0 && $money > 0 && $client > 0){ $pay_memberid = "API1362913582567500"; //商户CID @@ -227,16 +224,16 @@ trait happyPay{ $zdlIdArr = explode(',',$user['agent_parent_id_path']); $zdlId = $zdlIdArr[0]; $zdl = Db::name('user')->where(array('id' => $zdlId, 'status' => 1, 'is_delete' => 0, 'agent' => 1))->find(); - if(!$zdl || $zdl['money'] < $order['money']){ + if(!$zdl){ $update['status'] = 1; - $update['remake'] = '无法找到总代理,或者总代理账号余分不足,交易暂停'; + $update['remake'] = '无法找到总代理,交易暂停'; Db::name('order_record')->where('id',$order['id'])->update($update); $order_log = array(); $order_log['pay_channel_id'] = 5; $order_log['pay_channel_name'] = 'happyPay'; $order_log['money'] = $order['money']; $order_log['create_time'] = time(); - $order_log['remake'] = "无法找到总代理,或者总代理账号余分不足,回调内容:".$serializeData; + $order_log['remake'] = "无法找到总代理,回调内容:".$serializeData; $order_log['order_id'] = $order['id']; Db::name('order_log')->insert($order_log); exit('SUCCESS');//找不到总代理,回调失败 @@ -255,7 +252,7 @@ trait happyPay{ $call_back_data['zdl_id'] = $zdl['id']; $call_back_data['zdl_username'] = $zdl['username']; $call_back_data['zdl_money_before'] = $zdl['money']; - $call_back_data['zdl_money_after'] = $zdl['money'] - $order['money']; + $call_back_data['zdl_money_after'] = $zdl['money']; $call_back_data['money_before'] = $user['money']; $call_back_data['money_after'] = $user['money'] + $order['money']; Db::name('order_record')->where(array('id' => $order['id']))->update($call_back_data); @@ -278,9 +275,9 @@ trait happyPay{ $recharge['controller_id'] = $zdl['id']; $recharge['controller_username'] = $zdl['username']; $recharge['controller_nickname'] = $zdl['nickname']; - $recharge['controller_type'] = '第三方充值平台充值,扣取总代理余分'; + $recharge['controller_type'] = '第三方充值平台充值,系统直充'; $recharge['controller_old_money'] = $zdl['money']; - $recharge['controller_new_money'] = $zdl['money'] - $order['money']; + $recharge['controller_new_money'] = $zdl['money']; $recharge['user_id'] = $order['user_id']; $recharge['user_type'] = $user['agent']; $recharge['user_agent_level'] = 0; @@ -294,7 +291,6 @@ trait happyPay{ $recharge['remake'] = '第三方充值成功'; Db::name('recharge')->insert($recharge); $updateZdl = array(); - $updateZdl['money'] = $zdl['money'] - $order['money']; $updateZdl['last_recharge_out'] = $order['money']; $updateZdl['last_recharge_out_time'] = time(); $updateZdl['recharge_out_count'] = $zdl['recharge_out_count'] + 1; diff --git a/application/onlinechip/controller/traits/hengfuPay.php b/application/onlinechip/controller/traits/hengfuPay.php index 6fe4d26..850f1c7 100644 --- a/application/onlinechip/controller/traits/hengfuPay.php +++ b/application/onlinechip/controller/traits/hengfuPay.php @@ -28,9 +28,6 @@ trait hengfuPay{ if(!$zdl){ return json(array('status' => 0, 'message' => '所属代理账号异常,暂不能充值')); } - if($zdl['money'] < $money){ - return json(array('status' => 0, 'message' => '所属代理余额不足,暂不能充值')); - } $pay_list = config('pay_list'); if($user && $user_id > 0 && $money > 0 && $client > 0){ $sn = '1965312301'; @@ -168,17 +165,17 @@ trait hengfuPay{ $zdlIdArr = explode(',',$user['agent_parent_id_path']); $zdlId = $zdlIdArr[0]; $zdl = Db::name('user')->where(array('id' => $zdlId, 'status' => 1, 'is_delete' => 0, 'agent' => 1))->find(); - if(!$zdl || $zdl['money'] < $order['money']){ + if(!$zdl){ //找不到总代理,回调失败 $update['status'] = 1; - $update['remake'] = '无法找到总代理,或者总代理账号余分不足,交易暂停'; + $update['remake'] = '无法找到总代理,交易暂停'; Db::name('order_record')->where('id',$order['id'])->update($update); $order_log = array(); $order_log['pay_channel_id'] = 6; $order_log['pay_channel_name'] = 'hengfuPay'; $order_log['money'] = $order['money']; $order_log['create_time'] = time(); - $order_log['remake'] = "无法找到总代理,或者总代理账号余分不足,回调内容:".$serializeData; + $order_log['remake'] = "无法找到总代理,回调内容:".$serializeData; $order_log['order_id'] = $order['id']; Db::name('order_log')->insert($order_log); exit('success'); @@ -194,7 +191,7 @@ trait hengfuPay{ $call_back_data['zdl_id'] = $zdl['id']; $call_back_data['zdl_username'] = $zdl['username']; $call_back_data['zdl_money_before'] = $zdl['money']; - $call_back_data['zdl_money_after'] = $zdl['money'] - $order['money']; + $call_back_data['zdl_money_after'] = $zdl['money']; $call_back_data['money_before'] = $user['money']; $call_back_data['money_after'] = $user['money'] + $order['money']; Db::name('order_record')->where(array('id' => $order['id']))->update($call_back_data); @@ -217,9 +214,9 @@ trait hengfuPay{ $recharge['controller_id'] = $zdl['id']; $recharge['controller_username'] = $zdl['username']; $recharge['controller_nickname'] = $zdl['nickname']; - $recharge['controller_type'] = '第三方充值平台充值,扣取总代理余分'; + $recharge['controller_type'] = '第三方充值平台充值,系统直充'; $recharge['controller_old_money'] = $zdl['money']; - $recharge['controller_new_money'] = $zdl['money'] - $order['money']; + $recharge['controller_new_money'] = $zdl['money']; $recharge['user_id'] = $order['user_id']; $recharge['user_type'] = $user['agent']; $recharge['user_agent_level'] = 0; @@ -233,7 +230,6 @@ trait hengfuPay{ $recharge['remake'] = '第三方充值成功'; Db::name('recharge')->insert($recharge); $updateZdl = array(); - $updateZdl['money'] = $zdl['money'] - $order['money']; $updateZdl['last_recharge_out'] = $order['money']; $updateZdl['last_recharge_out_time'] = time(); $updateZdl['recharge_out_count'] = $zdl['recharge_out_count'] + 1; diff --git a/application/onlinechip/controller/traits/hipPay.php b/application/onlinechip/controller/traits/hipPay.php index 8b35bf2..962a390 100644 --- a/application/onlinechip/controller/traits/hipPay.php +++ b/application/onlinechip/controller/traits/hipPay.php @@ -36,9 +36,6 @@ trait hipPay{ if(!$zdl){ return json(array('status' => 0, 'message' => '所属代理账号异常,暂不能充值')); } - if($zdl['money'] < $money){ - return json(array('status' => 0, 'message' => '所属代理余额不足,暂不能充值')); - } $pay_list = config('pay_list'); if($user && $user_id > 0 && $money > 0 && $client > 0){ $pay_orderid = date("YmdHis").rand(10,99); //订单号 @@ -174,16 +171,16 @@ trait hipPay{ $zdlIdArr = explode(',',$user['agent_parent_id_path']); $zdlId = $zdlIdArr[0]; $zdl = Db::name('user')->where(array('id' => $zdlId, 'status' => 1, 'is_delete' => 0, 'agent' => 1))->find(); - if(!$zdl || $zdl['money'] < $order['money']){ + if(!$zdl){ $update['status'] = 1; - $update['remake'] = '无法找到总代理,或者总代理账号余分不足,交易暂停'; + $update['remake'] = '无法找到总代理,交易暂停'; Db::name('order_record')->where('id',$order['id'])->update($update); $order_log = array(); $order_log['pay_channel_id'] = 3; $order_log['pay_channel_name'] = 'hipPay'; $order_log['money'] = $order['money']; $order_log['create_time'] = time(); - $order_log['remake'] = "无法找到总代理,或者总代理账号余分不足,回调内容:".$serializeData; + $order_log['remake'] = "无法找到总代理,回调内容:".$serializeData; $order_log['order_id'] = $order['id']; Db::name('order_log')->insert($order_log); exit('OK');//找不到总代理,回调失败 @@ -200,7 +197,7 @@ trait hipPay{ $call_back_data['zdl_id'] = $zdl['id']; $call_back_data['zdl_username'] = $zdl['username']; $call_back_data['zdl_money_before'] = $zdl['money']; - $call_back_data['zdl_money_after'] = $zdl['money'] - $order['money']; + $call_back_data['zdl_money_after'] = $zdl['money']; $call_back_data['money_before'] = $user['money']; $call_back_data['money_after'] = $user['money'] + $order['money']; Db::name('order_record')->where(array('id' => $order['id']))->update($call_back_data); @@ -223,9 +220,9 @@ trait hipPay{ $recharge['controller_id'] = $zdl['id']; $recharge['controller_username'] = $zdl['username']; $recharge['controller_nickname'] = $zdl['nickname']; - $recharge['controller_type'] = '第三方充值平台充值,扣取总代理余分'; + $recharge['controller_type'] = '第三方充值平台充值,系统直充'; $recharge['controller_old_money'] = $zdl['money']; - $recharge['controller_new_money'] = $zdl['money'] - $order['money']; + $recharge['controller_new_money'] = $zdl['money']; $recharge['user_id'] = $order['user_id']; $recharge['user_type'] = $user['agent']; $recharge['user_agent_level'] = 0; @@ -239,7 +236,6 @@ trait hipPay{ $recharge['remake'] = '第三方充值成功'; Db::name('recharge')->insert($recharge); $updateZdl = array(); - $updateZdl['money'] = $zdl['money'] - $order['money']; $updateZdl['last_recharge_out'] = $order['money']; $updateZdl['last_recharge_out_time'] = time(); $updateZdl['recharge_out_count'] = $zdl['recharge_out_count'] + 1; diff --git a/application/onlinechip/controller/traits/oneGoPay.php b/application/onlinechip/controller/traits/oneGoPay.php index 9154188..998e7c6 100644 --- a/application/onlinechip/controller/traits/oneGoPay.php +++ b/application/onlinechip/controller/traits/oneGoPay.php @@ -36,9 +36,6 @@ trait oneGoPay{ if(!$zdl){ return json(array('status' => 0, 'message' => '所属代理账号异常,暂不能充值')); } - if($zdl['money'] < $money){ - return json(array('status' => 0, 'message' => '所属代理余额不足,暂不能充值')); - } $pay_list = config('pay_list'); if($user && $user_id > 0 && $money > 0 && $client > 0){ $pay_orderid = 'E'.date("YmdHis").rand(100000,999999); //订单号 @@ -155,16 +152,16 @@ trait oneGoPay{ $zdlIdArr = explode(',',$user['agent_parent_id_path']); $zdlId = $zdlIdArr[0]; $zdl = Db::name('user')->where(array('id' => $zdlId, 'status' => 1, 'is_delete' => 0, 'agent' => 1))->find(); - if(!$zdl || $zdl['money'] < $order['money']){ + if(!$zdl){ $update['status'] = 1; - $update['remake'] = '无法找到总代理,或者总代理账号余分不足,交易暂停'; + $update['remake'] = '无法找到总代理,交易暂停'; Db::name('order_record')->where('id',$order['id'])->update($update); $order_log = array(); $order_log['pay_channel_id'] = 2; $order_log['pay_channel_name'] = 'oneGoPay'; $order_log['money'] = $order['money']; $order_log['create_time'] = time(); - $order_log['remake'] = "无法找到总代理,或者总代理账号余分不足,回调内容:".$serializePost; + $order_log['remake'] = "无法找到总代理,回调内容:".$serializePost; $order_log['order_id'] = $order['id']; Db::name('order_log')->insert($order_log); exit('OK');//找不到总代理,回调失败 @@ -181,7 +178,7 @@ trait oneGoPay{ $call_back_data['zdl_id'] = $zdl['id']; $call_back_data['zdl_username'] = $zdl['username']; $call_back_data['zdl_money_before'] = $zdl['money']; - $call_back_data['zdl_money_after'] = $zdl['money'] - $order['money']; + $call_back_data['zdl_money_after'] = $zdl['money']; $call_back_data['money_before'] = $user['money']; $call_back_data['money_after'] = $user['money'] + $order['money']; Db::name('order_record')->where(array('id' => $order['id']))->update($call_back_data); @@ -204,9 +201,9 @@ trait oneGoPay{ $recharge['controller_id'] = $zdl['id']; $recharge['controller_username'] = $zdl['username']; $recharge['controller_nickname'] = $zdl['nickname']; - $recharge['controller_type'] = '第三方充值平台充值,扣取总代理余分'; + $recharge['controller_type'] = '第三方充值平台充值,系统直充'; $recharge['controller_old_money'] = $zdl['money']; - $recharge['controller_new_money'] = $zdl['money'] - $order['money']; + $recharge['controller_new_money'] = $zdl['money']; $recharge['user_id'] = $order['user_id']; $recharge['user_type'] = $user['agent']; $recharge['user_agent_level'] = 0; @@ -220,7 +217,6 @@ trait oneGoPay{ $recharge['remake'] = '第三方充值成功'; Db::name('recharge')->insert($recharge); $updateZdl = array(); - $updateZdl['money'] = $zdl['money'] - $order['money']; $updateZdl['last_recharge_out'] = $order['money']; $updateZdl['last_recharge_out_time'] = time(); $updateZdl['recharge_out_count'] = $zdl['recharge_out_count'] + 1; diff --git a/application/onlinechip/controller/traits/tingPay.php b/application/onlinechip/controller/traits/tingPay.php index 1f88313..6f6a0e1 100644 --- a/application/onlinechip/controller/traits/tingPay.php +++ b/application/onlinechip/controller/traits/tingPay.php @@ -30,9 +30,6 @@ trait tingPay{ if(!$zdl){ return json(array('status' => 0, 'message' => '所属代理账号异常,暂不能充值')); } - if($zdl['money'] < $money){ - return json(array('status' => 0, 'message' => '所属代理余额不足,暂不能充值')); - } $pay_list = config('pay_list'); if($user && $user_id > 0 && $money > 0 && $client > 0){ $pay_memberid = "3359"; //商户CID @@ -179,16 +176,16 @@ trait tingPay{ $zdlIdArr = explode(',',$user['agent_parent_id_path']); $zdlId = $zdlIdArr[0]; $zdl = Db::name('user')->where(array('id' => $zdlId, 'status' => 1, 'is_delete' => 0, 'agent' => 1))->find(); - if(!$zdl || $zdl['money'] < $order['money']){ + if(!$zdl){ $update['status'] = 1; - $update['remake'] = '无法找到总代理,或者总代理账号余分不足,交易暂停'; + $update['remake'] = '无法找到总代理,交易暂停'; Db::name('order_record')->where('id',$order['id'])->update($update); $order_log = array(); $order_log['pay_channel_id'] = 4; $order_log['pay_channel_name'] = 'tingPay'; $order_log['money'] = $order['money']; $order_log['create_time'] = time(); - $order_log['remake'] = "无法找到总代理,或者总代理账号余分不足,回调内容:".$serializeData; + $order_log['remake'] = "无法找到总代理,回调内容:".$serializeData; $order_log['order_id'] = $order['id']; Db::name('order_log')->insert($order_log); exit('success');//找不到总代理,回调失败 @@ -207,7 +204,7 @@ trait tingPay{ $call_back_data['zdl_id'] = $zdl['id']; $call_back_data['zdl_username'] = $zdl['username']; $call_back_data['zdl_money_before'] = $zdl['money']; - $call_back_data['zdl_money_after'] = $zdl['money'] - $order['money']; + $call_back_data['zdl_money_after'] = $zdl['money']; $call_back_data['money_before'] = $user['money']; $call_back_data['money_after'] = $user['money'] + $order['money']; Db::name('order_record')->where(array('id' => $order['id']))->update($call_back_data); @@ -230,9 +227,9 @@ trait tingPay{ $recharge['controller_id'] = $zdl['id']; $recharge['controller_username'] = $zdl['username']; $recharge['controller_nickname'] = $zdl['nickname']; - $recharge['controller_type'] = '第三方充值平台充值,扣取总代理余分'; + $recharge['controller_type'] = '第三方充值平台充值,系统直充'; $recharge['controller_old_money'] = $zdl['money']; - $recharge['controller_new_money'] = $zdl['money'] - $order['money']; + $recharge['controller_new_money'] = $zdl['money']; $recharge['user_id'] = $order['user_id']; $recharge['user_type'] = $user['agent']; $recharge['user_agent_level'] = 0; @@ -246,7 +243,6 @@ trait tingPay{ $recharge['remake'] = '第三方充值成功'; Db::name('recharge')->insert($recharge); $updateZdl = array(); - $updateZdl['money'] = $zdl['money'] - $order['money']; $updateZdl['last_recharge_out'] = $order['money']; $updateZdl['last_recharge_out_time'] = time(); $updateZdl['recharge_out_count'] = $zdl['recharge_out_count'] + 1; diff --git a/application/onlinechip/controller/traits/yonghengPay.php b/application/onlinechip/controller/traits/yonghengPay.php index b31bb0a..7781fcf 100644 --- a/application/onlinechip/controller/traits/yonghengPay.php +++ b/application/onlinechip/controller/traits/yonghengPay.php @@ -30,9 +30,6 @@ trait yonghengPay{ if(!$zdl){ return json(array('status' => 0, 'message' => '所属代理账号异常,暂不能充值')); } - if($zdl['money'] < $money){ - return json(array('status' => 0, 'message' => '所属代理余额不足,暂不能充值')); - } $pay_list = config('pay_list'); if($user && $user_id > 0 && $money > 0 && $client > 0){ $pay_memberid = "11319"; //商户ID @@ -227,16 +224,16 @@ trait yonghengPay{ $zdlIdArr = explode(',',$user['agent_parent_id_path']); $zdlId = $zdlIdArr[0]; $zdl = Db::name('user')->where(array('id' => $zdlId, 'status' => 1, 'is_delete' => 0, 'agent' => 1))->find(); - if(!$zdl || $zdl['money'] < $order['money']){ + if(!$zdl){ $update['status'] = 1; - $update['remake'] = '无法找到总代理,或者总代理账号余分不足,交易暂停'; + $update['remake'] = '无法找到总代理,交易暂停'; Db::name('order_record')->where('id',$order['id'])->update($update); $order_log = array(); $order_log['pay_channel_id'] = 1; $order_log['pay_channel_name'] = '永恒168'; $order_log['money'] = $order['money']; $order_log['create_time'] = time(); - $order_log['remake'] = "无法找到总代理,或者总代理账号余分不足,回调内容:".$serializePost; + $order_log['remake'] = "无法找到总代理,回调内容:".$serializePost; $order_log['order_id'] = $order['id']; Db::name('order_log')->insert($order_log); exit('OK');//找不到总代理,回调失败 @@ -254,7 +251,7 @@ trait yonghengPay{ $call_back_data['zdl_id'] = $zdl['id']; $call_back_data['zdl_username'] = $zdl['username']; $call_back_data['zdl_money_before'] = $zdl['money']; - $call_back_data['zdl_money_after'] = $zdl['money'] - $order['money']; + $call_back_data['zdl_money_after'] = $zdl['money']; $call_back_data['money_before'] = $user['money']; $call_back_data['money_after'] = $user['money'] + $order['money']; Db::name('order_record')->where(array('id' => $order['id']))->update($call_back_data); @@ -277,9 +274,9 @@ trait yonghengPay{ $recharge['controller_id'] = $zdl['id']; $recharge['controller_username'] = $zdl['username']; $recharge['controller_nickname'] = $zdl['nickname']; - $recharge['controller_type'] = '第三方充值平台充值,扣取总代理余分'; + $recharge['controller_type'] = '第三方充值平台充值,系统直充'; $recharge['controller_old_money'] = $zdl['money']; - $recharge['controller_new_money'] = $zdl['money'] - $order['money']; + $recharge['controller_new_money'] = $zdl['money']; $recharge['user_id'] = $order['user_id']; $recharge['user_type'] = $user['agent']; $recharge['user_agent_level'] = 0; @@ -293,7 +290,6 @@ trait yonghengPay{ $recharge['remake'] = '第三方充值成功'; Db::name('recharge')->insert($recharge); $updateZdl = array(); - $updateZdl['money'] = $zdl['money'] - $order['money']; $updateZdl['last_recharge_out'] = $order['money']; $updateZdl['last_recharge_out_time'] = time(); $updateZdl['recharge_out_count'] = $zdl['recharge_out_count'] + 1; From 24c71fa7a030232d798b887511c2b6b67b87fd13 Mon Sep 17 00:00:00 2001 From: li Date: Sun, 24 May 2026 20:55:06 +0800 Subject: [PATCH 15/32] =?UTF-8?q?Revert=20"feat:=20=E7=BA=BF=E4=B8=8A?= =?UTF-8?q?=E8=87=AA=E5=8A=A9=E5=85=85=E5=80=BC=E4=B8=8D=E5=86=8D=E6=89=A3?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E4=BD=99=E9=A2=9D=EF=BC=88=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E7=9B=B4=E5=85=85=EF=BC=89"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 0bf387f7d5daf03cfcbdb960278eb2be8f0ec27e. --- .../onlinechip/controller/traits/alinPay.php | 17 ++++++++----- .../onlinechip/controller/traits/ccpayPay.php | 22 +++++++++++++---- .../onlinechip/controller/traits/epayPay.php | 24 ++++++++++++++----- .../onlinechip/controller/traits/happyPay.php | 16 ++++++++----- .../controller/traits/hengfuPay.php | 16 ++++++++----- .../onlinechip/controller/traits/hipPay.php | 16 ++++++++----- .../onlinechip/controller/traits/oneGoPay.php | 16 ++++++++----- .../onlinechip/controller/traits/tingPay.php | 16 ++++++++----- .../controller/traits/yonghengPay.php | 16 ++++++++----- 9 files changed, 106 insertions(+), 53 deletions(-) diff --git a/application/onlinechip/controller/traits/alinPay.php b/application/onlinechip/controller/traits/alinPay.php index 0458b46..0c92fb3 100644 --- a/application/onlinechip/controller/traits/alinPay.php +++ b/application/onlinechip/controller/traits/alinPay.php @@ -73,6 +73,10 @@ trait alinPay if (!$zdl) { return json(['status' => 0, 'message' => '所属代理账号异常,暂不能充值']); } + if ($zdl['money'] < $money) { + return json(['status' => 0, 'message' => '所属代理余额不足,暂不能充值']); + } + $pay_list = config('pay_list'); $pay_orderid = 'E' . date("YmdHis") . rand(100000, 999999); $notify_url = $pay_list['alinPay']['notify_url']; @@ -228,9 +232,9 @@ trait alinPay 'agent' => 1, ])->lock(true)->find(); - if (!$zdl) { + if (!$zdl || $zdl['money'] < $order['money']) { Db::rollback(); - addLogToFile('代收结算失败:无法找到总代理 order=' . $orderNo, 'alin_callback_error', 'alin'); + addLogToFile('代收结算失败:代理余额不足 order=' . $orderNo, 'alin_callback_error', 'alin'); return; } @@ -244,7 +248,7 @@ trait alinPay 'zdl_id' => $zdl['id'], 'zdl_username' => $zdl['username'], 'zdl_money_before' => $zdl['money'], - 'zdl_money_after' => $zdl['money'], + 'zdl_money_after' => $zdl['money'] - $order['money'], 'money_before' => $user['money'], 'money_after' => $user['money'] + $order['money'], ]); @@ -268,9 +272,9 @@ trait alinPay 'controller_id' => $zdl['id'], 'controller_username' => $zdl['username'], 'controller_nickname' => $zdl['nickname'], - 'controller_type' => '越南第三方充值平台充值,系统直充', + 'controller_type' => '越南第三方充值平台充值,扣取总代理余分', 'controller_old_money' => $zdl['money'], - 'controller_new_money' => $zdl['money'], + 'controller_new_money' => $zdl['money'] - $order['money'], 'user_id' => $order['user_id'], 'user_type' => $user['agent'], 'user_agent_level' => 0, @@ -284,8 +288,9 @@ trait alinPay 'remake' => '越南AlinPay第三方充值成功', ]); - // 4. 更新代理统计(不扣余额) + // 4. 扣代理余额 Db::name('user')->where('id', $zdl['id'])->update([ + 'money' => $zdl['money'] - $order['money'], 'last_recharge_out' => $order['money'], 'last_recharge_out_time' => time(), 'recharge_out_count' => $zdl['recharge_out_count'] + 1, diff --git a/application/onlinechip/controller/traits/ccpayPay.php b/application/onlinechip/controller/traits/ccpayPay.php index 3cfe73d..3a56d52 100644 --- a/application/onlinechip/controller/traits/ccpayPay.php +++ b/application/onlinechip/controller/traits/ccpayPay.php @@ -67,6 +67,17 @@ trait ccpayPay $data = encrypt_data(['status' => 0, 'message' => 'Tài khoản đại lý có vấn đề, không thể nạp']); return json(['Success' => 1, 'Data' => $data]); } + if ($zdl['money'] < $money) { + $maxAllowed = intval($zdl['money']); + $data = encrypt_data([ + 'status' => 0, + 'code' => 'AGENT_LIMIT', + 'message' => 'Hạn mức nạp mỗi lần hiện tại là ' . number_format($maxAllowed, 0, '.', ',') . ' VND. Vui lòng nhập số tiền nhỏ hơn hoặc bằng mức trên.', + 'max_amount' => $maxAllowed, + ]); + return json(['Success' => 1, 'Data' => $data]); + } + $pay_list = config('pay_list'); $pay_orderid = 'C' . date('YmdHis') . rand(100000, 999999); $notify_url = $pay_list['ccpay']['notify_url'] ?? ''; @@ -320,9 +331,9 @@ trait ccpayPay 'agent' => 1, ])->lock(true)->find(); - if (!$zdl) { + if (!$zdl || $zdl['money'] < $order['money']) { Db::rollback(); - addLogToFile('ccpay 结算失败: 无法找到总代理 order=' . $orderNo, 'ccpay_callback_error', 'ccpay'); + addLogToFile('ccpay 结算失败: 代理余额不足 order=' . $orderNo, 'ccpay_callback_error', 'ccpay'); return; } @@ -337,7 +348,7 @@ trait ccpayPay 'zdl_id' => $zdl['id'], 'zdl_username' => $zdl['username'], 'zdl_money_before' => $zdl['money'], - 'zdl_money_after' => $zdl['money'], + 'zdl_money_after' => $zdl['money'] - $order['money'], 'money_before' => $user['money'], 'money_after' => $user['money'] + $order['money'], ]); @@ -359,9 +370,9 @@ trait ccpayPay 'controller_id' => $zdl['id'], 'controller_username' => $zdl['username'], 'controller_nickname' => $zdl['nickname'], - 'controller_type' => 'CCpay越南银行第三方充值,系统直充', + 'controller_type' => 'CCpay越南银行第三方充值,扣取总代理余分', 'controller_old_money' => $zdl['money'], - 'controller_new_money' => $zdl['money'], + 'controller_new_money' => $zdl['money'] - $order['money'], 'user_id' => $order['user_id'], 'user_type' => $user['agent'], 'user_agent_level' => 0, @@ -376,6 +387,7 @@ trait ccpayPay ]); Db::name('user')->where('id', $zdl['id'])->update([ + 'money' => $zdl['money'] - $order['money'], 'last_recharge_out' => $order['money'], 'last_recharge_out_time' => time(), 'recharge_out_count' => $zdl['recharge_out_count'] + 1, diff --git a/application/onlinechip/controller/traits/epayPay.php b/application/onlinechip/controller/traits/epayPay.php index 7465d4d..a0425b6 100644 --- a/application/onlinechip/controller/traits/epayPay.php +++ b/application/onlinechip/controller/traits/epayPay.php @@ -113,6 +113,17 @@ trait epayPay $data = encrypt_data(['status' => 0, 'message' => 'Tài khoản đại lý có vấn đề, không thể nạp']); return json(['Success' => 1, 'Data' => $data]); } + if ($zdl['money'] < $money) { + $maxAllowed = intval($zdl['money']); + $data = encrypt_data([ + 'status' => 0, + 'code' => 'AGENT_LIMIT', + 'message' => 'Hạn mức nạp mỗi lần hiện tại là ' . number_format($maxAllowed, 0, '.', ',') . ' VND. Vui lòng nhập số tiền nhỏ hơn hoặc bằng mức trên.', + 'max_amount' => $maxAllowed, + ]); + return json(['Success' => 1, 'Data' => $data]); + } + $pay_list = config('pay_list'); $pay_orderid = 'P' . date('YmdHis') . rand(100000, 999999); // P 前缀区分 AlinPay 的 E $notify_url = $pay_list['epay']['notify_url'] ?? ''; @@ -425,9 +436,9 @@ trait epayPay 'agent' => 1, ])->lock(true)->find(); - if (!$zdl) { + if (!$zdl || $zdl['money'] < $order['money']) { Db::rollback(); - addLogToFile('epay 结算失败:无法找到总代理 order=' . $orderNo, 'epay_callback_error', 'epay'); + addLogToFile('epay 结算失败:代理余额不足 order=' . $orderNo, 'epay_callback_error', 'epay'); return; } @@ -444,7 +455,7 @@ trait epayPay 'zdl_id' => $zdl['id'], 'zdl_username' => $zdl['username'], 'zdl_money_before' => $zdl['money'], - 'zdl_money_after' => $zdl['money'], + 'zdl_money_after' => $zdl['money'] - $order['money'], 'money_before' => $user['money'], 'money_after' => $user['money'] + $order['money'], ]); @@ -468,9 +479,9 @@ trait epayPay 'controller_id' => $zdl['id'], 'controller_username' => $zdl['username'], 'controller_nickname' => $zdl['nickname'], - 'controller_type' => '易支付第三方充值,系统直充', + 'controller_type' => '易支付第三方充值,扣取总代理余分', 'controller_old_money' => $zdl['money'], - 'controller_new_money' => $zdl['money'], + 'controller_new_money' => $zdl['money'] - $order['money'], 'user_id' => $order['user_id'], 'user_type' => $user['agent'], 'user_agent_level' => 0, @@ -484,8 +495,9 @@ trait epayPay 'remake' => '易支付第三方充值成功(' . ($data['type'] ?? '') . ')', ]); - // 4. 更新代理统计(不扣余额) + // 4. 扣代理 Db::name('user')->where('id', $zdl['id'])->update([ + 'money' => $zdl['money'] - $order['money'], 'last_recharge_out' => $order['money'], 'last_recharge_out_time' => time(), 'recharge_out_count' => $zdl['recharge_out_count'] + 1, diff --git a/application/onlinechip/controller/traits/happyPay.php b/application/onlinechip/controller/traits/happyPay.php index 19a46bc..4a035d2 100644 --- a/application/onlinechip/controller/traits/happyPay.php +++ b/application/onlinechip/controller/traits/happyPay.php @@ -30,6 +30,9 @@ trait happyPay{ if(!$zdl){ return json(array('status' => 0, 'message' => '所属代理账号异常,暂不能充值')); } + if($zdl['money'] < $money){ + return json(array('status' => 0, 'message' => '所属代理余额不足,暂不能充值')); + } $pay_list = config('pay_list'); if($user && $user_id > 0 && $money > 0 && $client > 0){ $pay_memberid = "API1362913582567500"; //商户CID @@ -224,16 +227,16 @@ trait happyPay{ $zdlIdArr = explode(',',$user['agent_parent_id_path']); $zdlId = $zdlIdArr[0]; $zdl = Db::name('user')->where(array('id' => $zdlId, 'status' => 1, 'is_delete' => 0, 'agent' => 1))->find(); - if(!$zdl){ + if(!$zdl || $zdl['money'] < $order['money']){ $update['status'] = 1; - $update['remake'] = '无法找到总代理,交易暂停'; + $update['remake'] = '无法找到总代理,或者总代理账号余分不足,交易暂停'; Db::name('order_record')->where('id',$order['id'])->update($update); $order_log = array(); $order_log['pay_channel_id'] = 5; $order_log['pay_channel_name'] = 'happyPay'; $order_log['money'] = $order['money']; $order_log['create_time'] = time(); - $order_log['remake'] = "无法找到总代理,回调内容:".$serializeData; + $order_log['remake'] = "无法找到总代理,或者总代理账号余分不足,回调内容:".$serializeData; $order_log['order_id'] = $order['id']; Db::name('order_log')->insert($order_log); exit('SUCCESS');//找不到总代理,回调失败 @@ -252,7 +255,7 @@ trait happyPay{ $call_back_data['zdl_id'] = $zdl['id']; $call_back_data['zdl_username'] = $zdl['username']; $call_back_data['zdl_money_before'] = $zdl['money']; - $call_back_data['zdl_money_after'] = $zdl['money']; + $call_back_data['zdl_money_after'] = $zdl['money'] - $order['money']; $call_back_data['money_before'] = $user['money']; $call_back_data['money_after'] = $user['money'] + $order['money']; Db::name('order_record')->where(array('id' => $order['id']))->update($call_back_data); @@ -275,9 +278,9 @@ trait happyPay{ $recharge['controller_id'] = $zdl['id']; $recharge['controller_username'] = $zdl['username']; $recharge['controller_nickname'] = $zdl['nickname']; - $recharge['controller_type'] = '第三方充值平台充值,系统直充'; + $recharge['controller_type'] = '第三方充值平台充值,扣取总代理余分'; $recharge['controller_old_money'] = $zdl['money']; - $recharge['controller_new_money'] = $zdl['money']; + $recharge['controller_new_money'] = $zdl['money'] - $order['money']; $recharge['user_id'] = $order['user_id']; $recharge['user_type'] = $user['agent']; $recharge['user_agent_level'] = 0; @@ -291,6 +294,7 @@ trait happyPay{ $recharge['remake'] = '第三方充值成功'; Db::name('recharge')->insert($recharge); $updateZdl = array(); + $updateZdl['money'] = $zdl['money'] - $order['money']; $updateZdl['last_recharge_out'] = $order['money']; $updateZdl['last_recharge_out_time'] = time(); $updateZdl['recharge_out_count'] = $zdl['recharge_out_count'] + 1; diff --git a/application/onlinechip/controller/traits/hengfuPay.php b/application/onlinechip/controller/traits/hengfuPay.php index 850f1c7..6fe4d26 100644 --- a/application/onlinechip/controller/traits/hengfuPay.php +++ b/application/onlinechip/controller/traits/hengfuPay.php @@ -28,6 +28,9 @@ trait hengfuPay{ if(!$zdl){ return json(array('status' => 0, 'message' => '所属代理账号异常,暂不能充值')); } + if($zdl['money'] < $money){ + return json(array('status' => 0, 'message' => '所属代理余额不足,暂不能充值')); + } $pay_list = config('pay_list'); if($user && $user_id > 0 && $money > 0 && $client > 0){ $sn = '1965312301'; @@ -165,17 +168,17 @@ trait hengfuPay{ $zdlIdArr = explode(',',$user['agent_parent_id_path']); $zdlId = $zdlIdArr[0]; $zdl = Db::name('user')->where(array('id' => $zdlId, 'status' => 1, 'is_delete' => 0, 'agent' => 1))->find(); - if(!$zdl){ + if(!$zdl || $zdl['money'] < $order['money']){ //找不到总代理,回调失败 $update['status'] = 1; - $update['remake'] = '无法找到总代理,交易暂停'; + $update['remake'] = '无法找到总代理,或者总代理账号余分不足,交易暂停'; Db::name('order_record')->where('id',$order['id'])->update($update); $order_log = array(); $order_log['pay_channel_id'] = 6; $order_log['pay_channel_name'] = 'hengfuPay'; $order_log['money'] = $order['money']; $order_log['create_time'] = time(); - $order_log['remake'] = "无法找到总代理,回调内容:".$serializeData; + $order_log['remake'] = "无法找到总代理,或者总代理账号余分不足,回调内容:".$serializeData; $order_log['order_id'] = $order['id']; Db::name('order_log')->insert($order_log); exit('success'); @@ -191,7 +194,7 @@ trait hengfuPay{ $call_back_data['zdl_id'] = $zdl['id']; $call_back_data['zdl_username'] = $zdl['username']; $call_back_data['zdl_money_before'] = $zdl['money']; - $call_back_data['zdl_money_after'] = $zdl['money']; + $call_back_data['zdl_money_after'] = $zdl['money'] - $order['money']; $call_back_data['money_before'] = $user['money']; $call_back_data['money_after'] = $user['money'] + $order['money']; Db::name('order_record')->where(array('id' => $order['id']))->update($call_back_data); @@ -214,9 +217,9 @@ trait hengfuPay{ $recharge['controller_id'] = $zdl['id']; $recharge['controller_username'] = $zdl['username']; $recharge['controller_nickname'] = $zdl['nickname']; - $recharge['controller_type'] = '第三方充值平台充值,系统直充'; + $recharge['controller_type'] = '第三方充值平台充值,扣取总代理余分'; $recharge['controller_old_money'] = $zdl['money']; - $recharge['controller_new_money'] = $zdl['money']; + $recharge['controller_new_money'] = $zdl['money'] - $order['money']; $recharge['user_id'] = $order['user_id']; $recharge['user_type'] = $user['agent']; $recharge['user_agent_level'] = 0; @@ -230,6 +233,7 @@ trait hengfuPay{ $recharge['remake'] = '第三方充值成功'; Db::name('recharge')->insert($recharge); $updateZdl = array(); + $updateZdl['money'] = $zdl['money'] - $order['money']; $updateZdl['last_recharge_out'] = $order['money']; $updateZdl['last_recharge_out_time'] = time(); $updateZdl['recharge_out_count'] = $zdl['recharge_out_count'] + 1; diff --git a/application/onlinechip/controller/traits/hipPay.php b/application/onlinechip/controller/traits/hipPay.php index 962a390..8b35bf2 100644 --- a/application/onlinechip/controller/traits/hipPay.php +++ b/application/onlinechip/controller/traits/hipPay.php @@ -36,6 +36,9 @@ trait hipPay{ if(!$zdl){ return json(array('status' => 0, 'message' => '所属代理账号异常,暂不能充值')); } + if($zdl['money'] < $money){ + return json(array('status' => 0, 'message' => '所属代理余额不足,暂不能充值')); + } $pay_list = config('pay_list'); if($user && $user_id > 0 && $money > 0 && $client > 0){ $pay_orderid = date("YmdHis").rand(10,99); //订单号 @@ -171,16 +174,16 @@ trait hipPay{ $zdlIdArr = explode(',',$user['agent_parent_id_path']); $zdlId = $zdlIdArr[0]; $zdl = Db::name('user')->where(array('id' => $zdlId, 'status' => 1, 'is_delete' => 0, 'agent' => 1))->find(); - if(!$zdl){ + if(!$zdl || $zdl['money'] < $order['money']){ $update['status'] = 1; - $update['remake'] = '无法找到总代理,交易暂停'; + $update['remake'] = '无法找到总代理,或者总代理账号余分不足,交易暂停'; Db::name('order_record')->where('id',$order['id'])->update($update); $order_log = array(); $order_log['pay_channel_id'] = 3; $order_log['pay_channel_name'] = 'hipPay'; $order_log['money'] = $order['money']; $order_log['create_time'] = time(); - $order_log['remake'] = "无法找到总代理,回调内容:".$serializeData; + $order_log['remake'] = "无法找到总代理,或者总代理账号余分不足,回调内容:".$serializeData; $order_log['order_id'] = $order['id']; Db::name('order_log')->insert($order_log); exit('OK');//找不到总代理,回调失败 @@ -197,7 +200,7 @@ trait hipPay{ $call_back_data['zdl_id'] = $zdl['id']; $call_back_data['zdl_username'] = $zdl['username']; $call_back_data['zdl_money_before'] = $zdl['money']; - $call_back_data['zdl_money_after'] = $zdl['money']; + $call_back_data['zdl_money_after'] = $zdl['money'] - $order['money']; $call_back_data['money_before'] = $user['money']; $call_back_data['money_after'] = $user['money'] + $order['money']; Db::name('order_record')->where(array('id' => $order['id']))->update($call_back_data); @@ -220,9 +223,9 @@ trait hipPay{ $recharge['controller_id'] = $zdl['id']; $recharge['controller_username'] = $zdl['username']; $recharge['controller_nickname'] = $zdl['nickname']; - $recharge['controller_type'] = '第三方充值平台充值,系统直充'; + $recharge['controller_type'] = '第三方充值平台充值,扣取总代理余分'; $recharge['controller_old_money'] = $zdl['money']; - $recharge['controller_new_money'] = $zdl['money']; + $recharge['controller_new_money'] = $zdl['money'] - $order['money']; $recharge['user_id'] = $order['user_id']; $recharge['user_type'] = $user['agent']; $recharge['user_agent_level'] = 0; @@ -236,6 +239,7 @@ trait hipPay{ $recharge['remake'] = '第三方充值成功'; Db::name('recharge')->insert($recharge); $updateZdl = array(); + $updateZdl['money'] = $zdl['money'] - $order['money']; $updateZdl['last_recharge_out'] = $order['money']; $updateZdl['last_recharge_out_time'] = time(); $updateZdl['recharge_out_count'] = $zdl['recharge_out_count'] + 1; diff --git a/application/onlinechip/controller/traits/oneGoPay.php b/application/onlinechip/controller/traits/oneGoPay.php index 998e7c6..9154188 100644 --- a/application/onlinechip/controller/traits/oneGoPay.php +++ b/application/onlinechip/controller/traits/oneGoPay.php @@ -36,6 +36,9 @@ trait oneGoPay{ if(!$zdl){ return json(array('status' => 0, 'message' => '所属代理账号异常,暂不能充值')); } + if($zdl['money'] < $money){ + return json(array('status' => 0, 'message' => '所属代理余额不足,暂不能充值')); + } $pay_list = config('pay_list'); if($user && $user_id > 0 && $money > 0 && $client > 0){ $pay_orderid = 'E'.date("YmdHis").rand(100000,999999); //订单号 @@ -152,16 +155,16 @@ trait oneGoPay{ $zdlIdArr = explode(',',$user['agent_parent_id_path']); $zdlId = $zdlIdArr[0]; $zdl = Db::name('user')->where(array('id' => $zdlId, 'status' => 1, 'is_delete' => 0, 'agent' => 1))->find(); - if(!$zdl){ + if(!$zdl || $zdl['money'] < $order['money']){ $update['status'] = 1; - $update['remake'] = '无法找到总代理,交易暂停'; + $update['remake'] = '无法找到总代理,或者总代理账号余分不足,交易暂停'; Db::name('order_record')->where('id',$order['id'])->update($update); $order_log = array(); $order_log['pay_channel_id'] = 2; $order_log['pay_channel_name'] = 'oneGoPay'; $order_log['money'] = $order['money']; $order_log['create_time'] = time(); - $order_log['remake'] = "无法找到总代理,回调内容:".$serializePost; + $order_log['remake'] = "无法找到总代理,或者总代理账号余分不足,回调内容:".$serializePost; $order_log['order_id'] = $order['id']; Db::name('order_log')->insert($order_log); exit('OK');//找不到总代理,回调失败 @@ -178,7 +181,7 @@ trait oneGoPay{ $call_back_data['zdl_id'] = $zdl['id']; $call_back_data['zdl_username'] = $zdl['username']; $call_back_data['zdl_money_before'] = $zdl['money']; - $call_back_data['zdl_money_after'] = $zdl['money']; + $call_back_data['zdl_money_after'] = $zdl['money'] - $order['money']; $call_back_data['money_before'] = $user['money']; $call_back_data['money_after'] = $user['money'] + $order['money']; Db::name('order_record')->where(array('id' => $order['id']))->update($call_back_data); @@ -201,9 +204,9 @@ trait oneGoPay{ $recharge['controller_id'] = $zdl['id']; $recharge['controller_username'] = $zdl['username']; $recharge['controller_nickname'] = $zdl['nickname']; - $recharge['controller_type'] = '第三方充值平台充值,系统直充'; + $recharge['controller_type'] = '第三方充值平台充值,扣取总代理余分'; $recharge['controller_old_money'] = $zdl['money']; - $recharge['controller_new_money'] = $zdl['money']; + $recharge['controller_new_money'] = $zdl['money'] - $order['money']; $recharge['user_id'] = $order['user_id']; $recharge['user_type'] = $user['agent']; $recharge['user_agent_level'] = 0; @@ -217,6 +220,7 @@ trait oneGoPay{ $recharge['remake'] = '第三方充值成功'; Db::name('recharge')->insert($recharge); $updateZdl = array(); + $updateZdl['money'] = $zdl['money'] - $order['money']; $updateZdl['last_recharge_out'] = $order['money']; $updateZdl['last_recharge_out_time'] = time(); $updateZdl['recharge_out_count'] = $zdl['recharge_out_count'] + 1; diff --git a/application/onlinechip/controller/traits/tingPay.php b/application/onlinechip/controller/traits/tingPay.php index 6f6a0e1..1f88313 100644 --- a/application/onlinechip/controller/traits/tingPay.php +++ b/application/onlinechip/controller/traits/tingPay.php @@ -30,6 +30,9 @@ trait tingPay{ if(!$zdl){ return json(array('status' => 0, 'message' => '所属代理账号异常,暂不能充值')); } + if($zdl['money'] < $money){ + return json(array('status' => 0, 'message' => '所属代理余额不足,暂不能充值')); + } $pay_list = config('pay_list'); if($user && $user_id > 0 && $money > 0 && $client > 0){ $pay_memberid = "3359"; //商户CID @@ -176,16 +179,16 @@ trait tingPay{ $zdlIdArr = explode(',',$user['agent_parent_id_path']); $zdlId = $zdlIdArr[0]; $zdl = Db::name('user')->where(array('id' => $zdlId, 'status' => 1, 'is_delete' => 0, 'agent' => 1))->find(); - if(!$zdl){ + if(!$zdl || $zdl['money'] < $order['money']){ $update['status'] = 1; - $update['remake'] = '无法找到总代理,交易暂停'; + $update['remake'] = '无法找到总代理,或者总代理账号余分不足,交易暂停'; Db::name('order_record')->where('id',$order['id'])->update($update); $order_log = array(); $order_log['pay_channel_id'] = 4; $order_log['pay_channel_name'] = 'tingPay'; $order_log['money'] = $order['money']; $order_log['create_time'] = time(); - $order_log['remake'] = "无法找到总代理,回调内容:".$serializeData; + $order_log['remake'] = "无法找到总代理,或者总代理账号余分不足,回调内容:".$serializeData; $order_log['order_id'] = $order['id']; Db::name('order_log')->insert($order_log); exit('success');//找不到总代理,回调失败 @@ -204,7 +207,7 @@ trait tingPay{ $call_back_data['zdl_id'] = $zdl['id']; $call_back_data['zdl_username'] = $zdl['username']; $call_back_data['zdl_money_before'] = $zdl['money']; - $call_back_data['zdl_money_after'] = $zdl['money']; + $call_back_data['zdl_money_after'] = $zdl['money'] - $order['money']; $call_back_data['money_before'] = $user['money']; $call_back_data['money_after'] = $user['money'] + $order['money']; Db::name('order_record')->where(array('id' => $order['id']))->update($call_back_data); @@ -227,9 +230,9 @@ trait tingPay{ $recharge['controller_id'] = $zdl['id']; $recharge['controller_username'] = $zdl['username']; $recharge['controller_nickname'] = $zdl['nickname']; - $recharge['controller_type'] = '第三方充值平台充值,系统直充'; + $recharge['controller_type'] = '第三方充值平台充值,扣取总代理余分'; $recharge['controller_old_money'] = $zdl['money']; - $recharge['controller_new_money'] = $zdl['money']; + $recharge['controller_new_money'] = $zdl['money'] - $order['money']; $recharge['user_id'] = $order['user_id']; $recharge['user_type'] = $user['agent']; $recharge['user_agent_level'] = 0; @@ -243,6 +246,7 @@ trait tingPay{ $recharge['remake'] = '第三方充值成功'; Db::name('recharge')->insert($recharge); $updateZdl = array(); + $updateZdl['money'] = $zdl['money'] - $order['money']; $updateZdl['last_recharge_out'] = $order['money']; $updateZdl['last_recharge_out_time'] = time(); $updateZdl['recharge_out_count'] = $zdl['recharge_out_count'] + 1; diff --git a/application/onlinechip/controller/traits/yonghengPay.php b/application/onlinechip/controller/traits/yonghengPay.php index 7781fcf..b31bb0a 100644 --- a/application/onlinechip/controller/traits/yonghengPay.php +++ b/application/onlinechip/controller/traits/yonghengPay.php @@ -30,6 +30,9 @@ trait yonghengPay{ if(!$zdl){ return json(array('status' => 0, 'message' => '所属代理账号异常,暂不能充值')); } + if($zdl['money'] < $money){ + return json(array('status' => 0, 'message' => '所属代理余额不足,暂不能充值')); + } $pay_list = config('pay_list'); if($user && $user_id > 0 && $money > 0 && $client > 0){ $pay_memberid = "11319"; //商户ID @@ -224,16 +227,16 @@ trait yonghengPay{ $zdlIdArr = explode(',',$user['agent_parent_id_path']); $zdlId = $zdlIdArr[0]; $zdl = Db::name('user')->where(array('id' => $zdlId, 'status' => 1, 'is_delete' => 0, 'agent' => 1))->find(); - if(!$zdl){ + if(!$zdl || $zdl['money'] < $order['money']){ $update['status'] = 1; - $update['remake'] = '无法找到总代理,交易暂停'; + $update['remake'] = '无法找到总代理,或者总代理账号余分不足,交易暂停'; Db::name('order_record')->where('id',$order['id'])->update($update); $order_log = array(); $order_log['pay_channel_id'] = 1; $order_log['pay_channel_name'] = '永恒168'; $order_log['money'] = $order['money']; $order_log['create_time'] = time(); - $order_log['remake'] = "无法找到总代理,回调内容:".$serializePost; + $order_log['remake'] = "无法找到总代理,或者总代理账号余分不足,回调内容:".$serializePost; $order_log['order_id'] = $order['id']; Db::name('order_log')->insert($order_log); exit('OK');//找不到总代理,回调失败 @@ -251,7 +254,7 @@ trait yonghengPay{ $call_back_data['zdl_id'] = $zdl['id']; $call_back_data['zdl_username'] = $zdl['username']; $call_back_data['zdl_money_before'] = $zdl['money']; - $call_back_data['zdl_money_after'] = $zdl['money']; + $call_back_data['zdl_money_after'] = $zdl['money'] - $order['money']; $call_back_data['money_before'] = $user['money']; $call_back_data['money_after'] = $user['money'] + $order['money']; Db::name('order_record')->where(array('id' => $order['id']))->update($call_back_data); @@ -274,9 +277,9 @@ trait yonghengPay{ $recharge['controller_id'] = $zdl['id']; $recharge['controller_username'] = $zdl['username']; $recharge['controller_nickname'] = $zdl['nickname']; - $recharge['controller_type'] = '第三方充值平台充值,系统直充'; + $recharge['controller_type'] = '第三方充值平台充值,扣取总代理余分'; $recharge['controller_old_money'] = $zdl['money']; - $recharge['controller_new_money'] = $zdl['money']; + $recharge['controller_new_money'] = $zdl['money'] - $order['money']; $recharge['user_id'] = $order['user_id']; $recharge['user_type'] = $user['agent']; $recharge['user_agent_level'] = 0; @@ -290,6 +293,7 @@ trait yonghengPay{ $recharge['remake'] = '第三方充值成功'; Db::name('recharge')->insert($recharge); $updateZdl = array(); + $updateZdl['money'] = $zdl['money'] - $order['money']; $updateZdl['last_recharge_out'] = $order['money']; $updateZdl['last_recharge_out_time'] = time(); $updateZdl['recharge_out_count'] = $zdl['recharge_out_count'] + 1; From 0f952a36a534e5e4a7f83fc6ee5377a49fe1b43b Mon Sep 17 00:00:00 2001 From: li Date: Thu, 28 May 2026 14:29:43 +0800 Subject: [PATCH 16/32] =?UTF-8?q?fix:=20CORS=E5=A4=B4=E5=86=B2=E7=AA=81?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20=E2=80=94=20=E5=88=A0=E9=99=A4=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E7=BA=A7=E9=87=8D=E5=A4=8Dheader=EF=BC=8C=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E7=94=B1=E6=9E=84=E9=80=A0=E5=87=BD=E6=95=B0=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:构造函数设 Access-Control-Allow-Origin: 具体域名 + Credentials: true, 但每个方法又覆盖成 Origin: *,导致 Credentials+通配符冲突,浏览器拒绝请求。 删除全部41处方法级CORS头,只保留构造函数的白名单机制。 --- application/onlinechip/controller/Pcapi.php | 125 -------------------- 1 file changed, 125 deletions(-) diff --git a/application/onlinechip/controller/Pcapi.php b/application/onlinechip/controller/Pcapi.php index d88c117..925e39d 100755 --- a/application/onlinechip/controller/Pcapi.php +++ b/application/onlinechip/controller/Pcapi.php @@ -50,9 +50,6 @@ class Pcapi extends Controller{ } public function get_version(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); return json(config('app_version')); } public function get_system_info(){ @@ -66,9 +63,6 @@ class Pcapi extends Controller{ } //试玩登录 public function demologin(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -121,9 +115,6 @@ class Pcapi extends Controller{ //保持在线--心跳 public function keepOnline(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -147,9 +138,6 @@ class Pcapi extends Controller{ } //登录optimum public function login(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -255,9 +243,6 @@ class Pcapi extends Controller{ } // 获取用户信息 public function get_user_info(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -324,9 +309,6 @@ class Pcapi extends Controller{ } //用户钱 public function user_money(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -350,9 +332,6 @@ class Pcapi extends Controller{ } //修改密码 public function update_password(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -390,9 +369,6 @@ class Pcapi extends Controller{ } //打赏 public function to_tip(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -436,9 +412,6 @@ class Pcapi extends Controller{ } //好路 public function good_road(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -474,9 +447,6 @@ class Pcapi extends Controller{ } //返回全部桌子 public function all_table(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -1219,9 +1189,6 @@ class Pcapi extends Controller{ } //返回单张桌子 public function singletable(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); // $json_arr = Request::instance()->post(); @@ -1770,9 +1737,6 @@ class Pcapi extends Controller{ } //今日最佳 public function optimum(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -1798,9 +1762,6 @@ class Pcapi extends Controller{ } //游戏记录 public function get_user_bets(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -2318,9 +2279,6 @@ class Pcapi extends Controller{ } //上下分记录 public function recharge_record(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -2387,9 +2345,6 @@ class Pcapi extends Controller{ } //上下分记录 public function tip_record(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -2449,9 +2404,6 @@ class Pcapi extends Controller{ } //开结果后获取会员的下注信息及计算其输赢数目 public function user_bet_baccarat(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -2608,9 +2560,6 @@ class Pcapi extends Controller{ } //开结果后获取会员的下注信息及计算其输赢数目 public function user_bet_dt(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -2699,9 +2648,6 @@ class Pcapi extends Controller{ //开结果后获取会员的下注信息及计算其输赢数目 public function user_bet_nn(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -2734,9 +2680,6 @@ class Pcapi extends Controller{ } //开结果后获取会员的下注信息及计算其输赢数目 public function user_bet_tc(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -2769,9 +2712,6 @@ class Pcapi extends Controller{ } //开结果后获取会员的下注信息及计算其输赢数目 public function user_bet_toning(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -2803,9 +2743,6 @@ class Pcapi extends Controller{ } //开结果后获取会员的下注信息及计算其输赢数目 public function user_bet_dice(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -2836,9 +2773,6 @@ class Pcapi extends Controller{ } } public function user_bet_roulette(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -2870,9 +2804,6 @@ class Pcapi extends Controller{ } //快速提现 public function show_withdrawal(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -2900,9 +2831,6 @@ class Pcapi extends Controller{ } //确认提现 public function withdrawal(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -2983,9 +2911,6 @@ class Pcapi extends Controller{ } //充值信息 public function show_recharge(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -3022,9 +2947,6 @@ class Pcapi extends Controller{ } //确认充值 public function recharge(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -3081,9 +3003,6 @@ class Pcapi extends Controller{ } //游戏记录 public function get_rob_bet(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -3299,9 +3218,6 @@ class Pcapi extends Controller{ //电话呼入 public function online_call(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); $phone = Request::instance()->post('phone'); if($phone){ $table_info = Db::name('table')->where('phone',$phone)->find(); @@ -3331,9 +3247,6 @@ class Pcapi extends Controller{ * DateTime: 2019/12/12 12:53 */ public function doRegister(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST'); if($data = Request::instance()->post()){ $data = decrypt_data($data); $username = isset($data['username'])?$data['username']:''; @@ -3687,9 +3600,6 @@ class Pcapi extends Controller{ //登录 public function lineLogin(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -3762,9 +3672,6 @@ class Pcapi extends Controller{ } public function app_entrance(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $entrance = array(); $entrance['HallUrl'] = HallUrl; @@ -3780,9 +3687,6 @@ class Pcapi extends Controller{ } //api用户通过接口获取铺信息 public function api_get_info(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $appId = intval(Request::instance()->post("appId")); $nonceStr = trim(Request::instance()->post("nonceStr")); @@ -3831,9 +3735,6 @@ class Pcapi extends Controller{ // 用户充值记录 public function user_recharge() { - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()) { $json_arr = decrypt_data(Request::instance()->post()); if ($json_arr) { @@ -3869,9 +3770,6 @@ class Pcapi extends Controller{ // 用户提现记录 public function user_withdraw() { - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()) { $json_arr = decrypt_data(Request::instance()->post()); if ($json_arr) { @@ -3907,9 +3805,6 @@ class Pcapi extends Controller{ //申请提现 public function apply_withdraw(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -3983,9 +3878,6 @@ class Pcapi extends Controller{ // 申请银行卡提现(越南AlinPay) public function apply_withdraw_bank(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr){ @@ -4079,9 +3971,6 @@ class Pcapi extends Controller{ // 获取越南银行列表 public function get_bank_list_vn(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); $banks = \pay\AlinPay::getBankCodes(); $list = []; @@ -4099,9 +3988,6 @@ class Pcapi extends Controller{ // 取消提现 public function cancel_withdraw(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr) { @@ -4157,9 +4043,6 @@ class Pcapi extends Controller{ */ public function deposit() { - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr) { @@ -4221,9 +4104,6 @@ class Pcapi extends Controller{ */ public function get_free_seat(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE'); if(Request::instance()->isPost()){ $json_arr = decrypt_data(Request::instance()->post()); if($json_arr) { @@ -4265,11 +4145,6 @@ class Pcapi extends Controller{ * 无需鉴权,游客可访问 */ public function get_lobby_data(){ - header('Access-Control-Allow-Origin: *'); - header("Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization"); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE,OPTIONS'); - header('Access-Control-Max-Age: 86400'); - // 处理 OPTIONS 预检请求 if(Request::instance()->isOptions()){ return response('', 200); From bcf604dc0aeae226617bbf1903c756c3ba412beb Mon Sep 17 00:00:00 2001 From: li Date: Thu, 28 May 2026 14:37:33 +0800 Subject: [PATCH 17/32] =?UTF-8?q?fix:=20CORS=E6=94=B9=E4=B8=BA=E5=9B=9E?= =?UTF-8?q?=E6=98=BEOrigin=EF=BC=8C=E5=8E=BB=E6=8E=89=E7=99=BD=E5=90=8D?= =?UTF-8?q?=E5=8D=95=E9=99=90=E5=88=B6=E5=92=8Ccredentials?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/onlinechip/controller/Pcapi.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/application/onlinechip/controller/Pcapi.php b/application/onlinechip/controller/Pcapi.php index 925e39d..76b8ac8 100755 --- a/application/onlinechip/controller/Pcapi.php +++ b/application/onlinechip/controller/Pcapi.php @@ -23,13 +23,13 @@ class Pcapi extends Controller{ parent::__construct(); // CORS headers $origin = Request::instance()->header('origin'); - $allowed = ['https://ww1.g7g7.top','https://m.g7g7.top','https://m1.g7g7.top','https://m3.g7g7.top','https://p.g7g7.top']; - if($origin && in_array($origin, $allowed)){ + if($origin){ header('Access-Control-Allow-Origin: '.$origin); - header('Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization'); - header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE,OPTIONS'); - header('Access-Control-Allow-Credentials: true'); + } else { + header('Access-Control-Allow-Origin: *'); } + header('Access-Control-Allow-Headers: token, Origin, X-Requested-With, Content-Type, Accept, Authorization'); + header('Access-Control-Allow-Methods: POST,GET,PUT,DELETE,OPTIONS'); if(Request::instance()->isOptions()){ exit(); } From 50d131aa7559747e237aad68158222dcd597d5d3 Mon Sep 17 00:00:00 2001 From: li Date: Fri, 29 May 2026 05:44:17 +0800 Subject: [PATCH 18/32] =?UTF-8?q?fix:=20=E4=BC=9A=E5=91=98=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E4=BF=9D=E5=AD=98=E5=90=8E=E5=AD=97=E6=AE=B5=E8=A2=AB?= =?UTF-8?q?=E6=B8=85=E9=9B=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. JS里agent_commission系列字段被注释掉,每次编辑保存抽水率被重置为0 2. rebate_rate为0时PHP不保存,导致无法设为0 --- application/agent/controller/Player.php | 4 +--- application/agent/view/player/edit.html | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/application/agent/controller/Player.php b/application/agent/controller/Player.php index f076c97..d8cbe76 100755 --- a/application/agent/controller/Player.php +++ b/application/agent/controller/Player.php @@ -760,9 +760,7 @@ class Player Extends Common{ $user_data['agent_ximalv_nn'] = $agent_ximalv_nn; $user_data['agent_ximalv_tc'] = $agent_ximalv_tc; $user_data['manager_id'] = $manager_id; - if ($rebate_rate){ - $user_data['rebate_rate'] = $rebate_rate; - } + $user_data['rebate_rate'] = $rebate_rate ?: 0; $user_data['update_time'] = time(); $user_data['remarks'] = $remark; $result = Db::name('user')->where('id',$user_id)->update($user_data); diff --git a/application/agent/view/player/edit.html b/application/agent/view/player/edit.html index 64c06a6..ec33a61 100755 --- a/application/agent/view/player/edit.html +++ b/application/agent/view/player/edit.html @@ -644,13 +644,11 @@ //query.mobile = $('#mobile').val(); //query.bet_type = $('#bet_type').val(); query.win_limit = $('#win_limit').val(); - /* query.agent_commission = $('#agent_commission').val(); query.agent_commission_dt = $('#agent_commission_dt').val(); query.agent_commission_nn = $('#agent_commission_nn').val(); query.agent_commission_tc = $('#agent_commission_tc').val(); query.agent_commission_tc_banker = $('#agent_commission_tc_banker').val(); - */ query.limit_low = $('#limit_low').val(); query.limit_high = $('#limit_high').val(); query.limit_low_tie = $('#limit_low_tie').val(); From 020dd802d69ef3d91ba347baa7bb139b23e22f4e Mon Sep 17 00:00:00 2001 From: li Date: Fri, 29 May 2026 06:43:21 +0800 Subject: [PATCH 19/32] =?UTF-8?q?feat(agent):=20=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E4=BB=A3=E7=90=86=E8=B4=B9=E7=8E=87=E6=97=B6=E6=A3=80=E6=B5=8B?= =?UTF-8?q?=E4=B8=8B=E7=BA=A7=E6=9C=AA=E7=BB=93=E7=AE=97=E6=B3=A8=E5=8D=95?= =?UTF-8?q?=E5=B9=B6=E4=BA=8C=E6=AC=A1=E7=A1=AE=E8=AE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 洗码率/返水率/占成率在下注未结算期间被修改, 结算(openingBet)会按新值 参与代理分账, 导致本局佣金与下注时预期不符。新增编辑时检测: 费率确有 变动且下级存在近1小时内 is_end=0 的注单时返回 code=2, 前端弹框二次 确认, 确认后带 confirm_pending 重提。纯增量护栏, 不改结算逻辑。 --- application/agent/controller/Agent.php | 32 ++++++++++++++++++++++++++ application/agent/view/agent/edit.html | 27 ++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/application/agent/controller/Agent.php b/application/agent/controller/Agent.php index 4de06d1..11ee619 100755 --- a/application/agent/controller/Agent.php +++ b/application/agent/controller/Agent.php @@ -682,6 +682,38 @@ class Agent Extends Common{ die(json_encode(['code'=>0,'msg'=>$lang['rebate_cannot_lower_agent'].' '.$childMaxRebateRate.'%'])); } + // —— 时序风险检测 —— + // 洗码率/返水率/占成率在「下注未结算」期间被修改,结算(openingBet)会按新值参与代理分账, + // 导致本局佣金与下注时预期不符。仅当上述费率确有变化、且该代理下级存在未结算注单时,要求二次确认。 + // 限红(limit_*)不参与结算、赔率(price_*)代理端只读,故不在检测范围。 + $confirm_pending = Request::instance()->post('confirm_pending'); + $rateChanged = ( + abs($agent_ximalv - (float)$user['agent_ximalv']) > 0.001 || + abs($agent_ximalv_dt - (float)$user['agent_ximalv_dt']) > 0.001 || + abs($agent_ximalv_nn - (float)$user['agent_ximalv_nn']) > 0.001 || + abs($agent_ximalv_tc - (float)$user['agent_ximalv_tc']) > 0.001 || + abs($agent_cs - (float)$user['agent_cs']) > 0.001 || + abs((float)$rebate_rate - (float)$user['rebate_rate']) > 0.001 + ); + if($rateChanged && !$confirm_pending){ + // bet 表位于 DB2 连接(与 Report 模块一致);下级注单路径匹配沿用全站约定的两段 LIKE。 + // create_time 限定近 1 小时,规避历史异常残留的 is_end=0 注单造成的误报。 + $pendingCount = Db::connect('DB2')->name('bet') + ->where('is_end', 0) + ->where('create_time', '>=', time() - 3600) + ->where(function($q) use ($user_id){ + $q->where('agent_parent_id_path', 'like', '%,'.$user_id.',%') + ->whereOr('agent_parent_id_path', 'like', $user_id.',%'); + }) + ->count(); + if($pendingCount > 0){ + die(json_encode([ + 'code' => 2, + 'pending' => $pendingCount, + 'msg' => '该代理下级当前有 '.$pendingCount.' 笔注单尚未结算。本次修改的洗码率 / 返水率 / 占成率将按新值参与这些注单的代理分账,可能使本局佣金与下注时预期不符。确定仍要立即保存吗?', + ])); + } + } // 拼装数据创建代理 $user_data = array(); diff --git a/application/agent/view/agent/edit.html b/application/agent/view/agent/edit.html index 07b279d..08f692b 100755 --- a/application/agent/view/agent/edit.html +++ b/application/agent/view/agent/edit.html @@ -277,6 +277,33 @@ x_admin_close(); parent.location.reload(); }); + } else if (data.code == 2) { + // 时序风险:下级有未结算注单,二次确认后带 confirm_pending 重新提交 + layer.confirm(data.msg, { + title: lang.message, + btn: ['确定保存', '取消'] + }, function (idx) { + layer.close(idx); + query.confirm_pending = 1; + $.ajax({ + url: '/agent/do_edit', + data: query, + type: 'POST', + dataType: 'JSON', + success: function (d) { + if (d.code == 0) { + layer.msg(d.msg); + } else if (d.code == 1) { + layer.alert(d.msg, { + title: lang.message + }, function () { + x_admin_close(); + parent.location.reload(); + }); + } + } + }); + }); } } }) From 3ac1c2bf42081508b984d5782600e8a255e110eb Mon Sep 17 00:00:00 2001 From: li Date: Fri, 29 May 2026 11:44:46 +0800 Subject: [PATCH 20/32] =?UTF-8?q?fix(agent):=20=E4=BB=A3=E7=90=86=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E6=A0=A1=E9=AA=8C=E5=A4=B1=E8=B4=A5=E6=94=B9=E7=94=A8?= =?UTF-8?q?=E5=BF=85=E9=A1=BB=E7=A1=AE=E8=AE=A4=E7=9A=84=E5=BC=B9=E7=AA=97?= =?UTF-8?q?,=20=E8=AE=A9=E6=93=8D=E4=BD=9C=E5=91=98=E7=9C=8B=E6=B8=85?= =?UTF-8?q?=E5=8E=9F=E5=9B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 返水率/码率/占股超过上级上限时后端已返回具体原因(含上级上限值), 但前端用 layer.msg 一闪而过易被忽略, 误以为'改不动'。改为 layer.alert 必须点确认, 确保看清失败原因(如'返水率不能超过所属代理的返水率 0!')。 --- application/agent/view/agent/edit.html | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/application/agent/view/agent/edit.html b/application/agent/view/agent/edit.html index 08f692b..87f43b6 100755 --- a/application/agent/view/agent/edit.html +++ b/application/agent/view/agent/edit.html @@ -269,7 +269,12 @@ dataType: 'JSON', success: function (data) { if (data.code == 0) { - layer.msg(data.msg); + // 校验未通过:用必须点确认的弹窗代替一闪而过的 toast,确保操作员看清失败原因 + // (如返水率/码率/占股超过上级上限时,后端会返回具体上限值) + layer.alert(data.msg, { + title: lang.message, + icon: 0 + }); } else if (data.code == 1) { layer.alert(data.msg,{ title:lang.message, @@ -292,7 +297,10 @@ dataType: 'JSON', success: function (d) { if (d.code == 0) { - layer.msg(d.msg); + layer.alert(d.msg, { + title: lang.message, + icon: 0 + }); } else if (d.code == 1) { layer.alert(d.msg, { title: lang.message From e763c561f17497398b35d861d72c44d02b7b6837 Mon Sep 17 00:00:00 2001 From: li Date: Fri, 29 May 2026 21:04:21 +0800 Subject: [PATCH 21/32] =?UTF-8?q?feat(agent-report):=20=E7=BB=93=E7=AE=97?= =?UTF-8?q?=E6=8A=A5=E8=A1=A8=E9=BB=98=E8=AE=A4=E6=97=B6=E9=97=B4=E6=94=B9?= =?UTF-8?q?=E4=B8=BA08:00~=E6=AC=A1=E6=97=A507:59:59,=20=E7=A0=81=E9=87=8F?= =?UTF-8?q?=E5=88=97=E6=94=B9=E5=90=8D=E7=A0=81=E7=B2=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Report::settle 默认日期边界 07:00/06:59:59 → 08:00/07:59:59(博彩日) - code_amount 翻译 码量/碼量/Code amount → 码粮/碼糧/Rebate(代理后台全局) --- application/agent/controller/Report.php | 6 +++--- application/agent/lang/en-us.php | 2 +- application/agent/lang/zh-cn.php | 2 +- application/agent/lang/zh-tw.php | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/application/agent/controller/Report.php b/application/agent/controller/Report.php index af89f64..02a76b4 100755 --- a/application/agent/controller/Report.php +++ b/application/agent/controller/Report.php @@ -36,17 +36,17 @@ class Report Extends Common{ $game_id = intval(Request::instance()->get('game_id')); $export = intval(Request::instance()->get('export')); - // 转换日期时间(默认:今天07:00:00 ~ 明天06:59:59) + // 转换日期时间(默认:今天08:00:00 ~ 明天07:59:59) if ($startDate) { $startTime = strtotime($startDate); } else { - $startTime = strtotime(date('Y-m-d') . ' 07:00:00'); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s', $startTime); } if ($endDate) { $endTime = strtotime($endDate); } else { - $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 06:59:59'); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s', $endTime); } diff --git a/application/agent/lang/en-us.php b/application/agent/lang/en-us.php index da56127..bdcd99f 100755 --- a/application/agent/lang/en-us.php +++ b/application/agent/lang/en-us.php @@ -301,7 +301,7 @@ return [ 'betting_money' => 'Bet money', 'code_washing_amount' => 'Code washing amount', 'odd_code_fee' => 'Odd code fee', - 'code_amount' => 'Code amount', + 'code_amount' => 'Rebate', 'settled_code_amount' => 'Settled code amount', 'unsettled_code_amount' => 'Unsettled code amount', 'unsettled_rebate_amount' => 'Unsettled rebate amount', diff --git a/application/agent/lang/zh-cn.php b/application/agent/lang/zh-cn.php index 56d4511..3039190 100755 --- a/application/agent/lang/zh-cn.php +++ b/application/agent/lang/zh-cn.php @@ -301,7 +301,7 @@ return [ 'betting_money' => '下注金额', 'code_washing_amount' => '洗码量', 'odd_code_fee' => '注单码费', - 'code_amount' => '码量', + 'code_amount' => '码粮', 'settled_code_amount' => '已结码量', 'unsettled_code_amount' => '未结码量', 'unsettled_rebate_amount' => '未结返水', diff --git a/application/agent/lang/zh-tw.php b/application/agent/lang/zh-tw.php index 657041b..e7937f9 100755 --- a/application/agent/lang/zh-tw.php +++ b/application/agent/lang/zh-tw.php @@ -301,7 +301,7 @@ return [ 'betting_money' => '下注金額', 'code_washing_amount' => '洗碼量', 'odd_code_fee' => '注單碼費', - 'code_amount' => '碼量', + 'code_amount' => '碼糧', 'settled_code_amount' => '已結碼量', 'unsettled_code_amount' => '未結碼量', 'unsettled_rebate_amount' => '未結返水', From 2d7b15c1ad8424e29196b01eb6e4ba9d783b129f Mon Sep 17 00:00:00 2001 From: li Date: Fri, 29 May 2026 21:15:24 +0800 Subject: [PATCH 22/32] =?UTF-8?q?feat(agent-report):=20=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E5=85=A8=E9=83=A8=E6=8A=A5=E8=A1=A8=E9=BB=98=E8=AE=A4=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E4=B8=BA=20=E4=BB=8A=E5=A4=A908:00:00~=E6=AC=A1?= =?UTF-8?q?=E6=97=A507:59:59?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Report.php 中 18 个报表(上下水/游戏/注单/上下分/台桌/棋牌等)默认时间 从 今天00:00~此刻 统一为 今天08:00:00~次日07:59:59(博彩日), 与结算报表一致。 保留2个默认'全部时间'(startTime=0)的查询不变。 --- application/agent/controller/Report.php | 72 ++++++++++++------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/application/agent/controller/Report.php b/application/agent/controller/Report.php index 02a76b4..ac1292e 100755 --- a/application/agent/controller/Report.php +++ b/application/agent/controller/Report.php @@ -309,14 +309,14 @@ class Report Extends Common{ if($startDate){ $startTime = strtotime($startDate); }else{ - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s',$startTime); $this->assign('get',$get); } if($endDate){ $endTime = strtotime($endDate); }else{ - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s',$endTime); $this->assign('get',$get); } @@ -505,13 +505,13 @@ class Report Extends Common{ if($startDate){ $startTime = strtotime($startDate); }else{ - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s',$startTime); } if($endDate){ $endTime = strtotime($endDate); }else{ - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s',$endTime); } @@ -1032,13 +1032,13 @@ class Report Extends Common{ if($startDate){ $startTime = strtotime($startDate); }else{ - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s',$startTime); } if($endDate){ $endTime = strtotime($endDate); }else{ - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s',$endTime); } @@ -2054,14 +2054,14 @@ class Report Extends Common{ if($startDate){ $startTime = strtotime($startDate); }else{ - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s',$startTime); $this->assign('get',$get); } if($endDate){ $endTime = strtotime($endDate); }else{ - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s',$endTime); $this->assign('get',$get); } @@ -2172,14 +2172,14 @@ class Report Extends Common{ if($startDate){ $startTime = strtotime($startDate); }else{ - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s',$startTime); $this->assign('get',$get); } if($endDate){ $endTime = strtotime($endDate); }else{ - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s',$endTime); $this->assign('get',$get); } @@ -2269,14 +2269,14 @@ class Report Extends Common{ if($startDate){ $startTime = strtotime($startDate); }else{ - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s',$startTime); $this->assign('get',$get); } if($endDate){ $endTime = strtotime($endDate); }else{ - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s',$endTime); $this->assign('get',$get); } @@ -2819,14 +2819,14 @@ class Report Extends Common{ if($startDate){ $startTime = strtotime($startDate); }else{ - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s',$startTime); $this->assign('get',$get); } if($endDate){ $endTime = strtotime($endDate); }else{ - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s',$endTime); $this->assign('get',$get); } @@ -2869,13 +2869,13 @@ class Report Extends Common{ if ($startDate) { $startTime = strtotime($startDate); } else { - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s', $startTime); } if ($endDate) { $endTime = strtotime($endDate); } else { - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s', $endTime); } @@ -3075,14 +3075,14 @@ class Report Extends Common{ if ($startDate) { $startTime = strtotime($startDate); } else { - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s', $startTime); $this->assign('get', $get); } if ($endDate) { $endTime = strtotime($endDate); } else { - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s', $endTime); $this->assign('get', $get); } @@ -3168,14 +3168,14 @@ class Report Extends Common{ if ($startDate) { $startTime = strtotime($startDate); } else { - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s', $startTime); $this->assign('get', $get); } if ($endDate) { $endTime = strtotime($endDate); } else { - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s', $endTime); $this->assign('get', $get); } @@ -3275,14 +3275,14 @@ class Report Extends Common{ if ($startDate) { $startTime = strtotime($startDate); } else { - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s', $startTime); $this->assign('get', $get); } if ($endDate) { $endTime = strtotime($endDate); } else { - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s', $endTime); $this->assign('get', $get); } @@ -3366,14 +3366,14 @@ class Report Extends Common{ if ($startDate) { $startTime = strtotime($startDate); } else { - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s', $startTime); $this->assign('get', $get); } if ($endDate) { $endTime = strtotime($endDate); } else { - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s', $endTime); $this->assign('get', $get); } @@ -3479,14 +3479,14 @@ class Report Extends Common{ if ($startDate) { $startTime = strtotime($startDate); } else { - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s', $startTime); $this->assign('get', $get); } if ($endDate) { $endTime = strtotime($endDate); } else { - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s', $endTime); $this->assign('get', $get); } @@ -3574,14 +3574,14 @@ class Report Extends Common{ if ($startDate) { $startTime = strtotime($startDate); } else { - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s', $startTime); $this->assign('get', $get); } if ($endDate) { $endTime = strtotime($endDate); } else { - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s', $endTime); $this->assign('get', $get); } @@ -3683,14 +3683,14 @@ class Report Extends Common{ if($startDate){ $startTime = strtotime($startDate); }else{ - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s',$startTime); $this->assign('get',$get); } if($endDate){ $endTime = strtotime($endDate); }else{ - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s',$endTime); $this->assign('get',$get); } @@ -3895,14 +3895,14 @@ class Report Extends Common{ if($startDate){ $startTime = strtotime($startDate); }else{ - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s',$startTime); $this->assign('get',$get); } if($endDate){ $endTime = strtotime($endDate); }else{ - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s',$endTime); $this->assign('get',$get); } @@ -3994,14 +3994,14 @@ class Report Extends Common{ if($startDate){ $startTime = strtotime($startDate); }else{ - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s',$startTime); $this->assign('get',$get); } if($endDate){ $endTime = strtotime($endDate); }else{ - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s',$endTime); $this->assign('get',$get); } @@ -4100,14 +4100,14 @@ class Report Extends Common{ if($startDate){ $startTime = strtotime($startDate); }else{ - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s',$startTime); $this->assign('get',$get); } if($endDate){ $endTime = strtotime($endDate); }else{ - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s',$endTime); $this->assign('get',$get); } From ca2513bb7a2a93c51083baae67e7533bf9b983b2 Mon Sep 17 00:00:00 2001 From: li Date: Fri, 29 May 2026 21:17:13 +0800 Subject: [PATCH 23/32] =?UTF-8?q?feat(agent-home):=20=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E4=BB=8A=E6=97=A5=E6=8A=95=E6=B3=A8=E7=BB=9F=E8=AE=A1(tpbet)?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E6=97=B6=E9=97=B4=E7=BB=9F=E4=B8=80=E4=B8=BA?= =?UTF-8?q?=2008:00:00~=E6=AC=A1=E6=97=A507:59:59?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/agent/controller/Login.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application/agent/controller/Login.php b/application/agent/controller/Login.php index 765b7bb..c1a616f 100755 --- a/application/agent/controller/Login.php +++ b/application/agent/controller/Login.php @@ -260,13 +260,13 @@ class Login extends Controller { if($startDate){ $startTime = strtotime($startDate); }else{ - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 08:00:00'); $get['startDate'] = date('Y-m-d H:i:s',$startTime); } if($endDate){ $endTime = strtotime($endDate); }else{ - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 07:59:59'); $get['endDate'] = date('Y-m-d H:i:s',$endTime); } $where = array(); From 750a5472fa20bbd7cbb0f5b50af7b363f619ce15 Mon Sep 17 00:00:00 2001 From: li Date: Fri, 29 May 2026 21:35:01 +0800 Subject: [PATCH 24/32] =?UTF-8?q?fix(alinpay):=20=E7=BD=91=E5=85=B3?= =?UTF-8?q?=E5=9F=9F=E5=90=8D=20fallback=20=E7=94=B1=20fantianchuangshi.co?= =?UTF-8?q?m=20=E8=BF=81=E8=87=B3=20hypayment.net?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 第三方支付网关改版迁移域名。DB配置已补 domain 字段, 同步更新代码回退默认值。 appid/secret/product_id/请求格式不变, 经账户查询验证新网关可用。 --- extend/pay/AlinPay.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extend/pay/AlinPay.php b/extend/pay/AlinPay.php index f7dd384..6eb3cb5 100644 --- a/extend/pay/AlinPay.php +++ b/extend/pay/AlinPay.php @@ -64,8 +64,8 @@ class AlinPay $config = json_decode($config, true); $this->config = $config; - // 域名从配置读取,回退默认值 - $this->domain = $config['domain'] ?? 'https://alinintermon-api.fantianchuangshi.com'; + // 域名从配置读取,回退默认值(2026-05 第三方网关由 fantianchuangshi.com 迁至 hypayment.net) + $this->domain = $config['domain'] ?? 'https://alinintermon-api.hypayment.net'; } /** From fbeb9787dc5cfc280b3f0dd67b161d2e8c725766 Mon Sep 17 00:00:00 2001 From: li Date: Sat, 30 May 2026 22:27:51 +0800 Subject: [PATCH 25/32] =?UTF-8?q?feat(agent-report):=20=E6=B3=A8=E5=8D=95?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E6=96=B0=E5=A2=9E=E4=BB=8A=E6=97=A5=E6=B3=A8?= =?UTF-8?q?=E5=8D=95=E8=87=AA=E5=8A=A8=E5=88=B7=E6=96=B0=E5=BC=80=E5=85=B3?= =?UTF-8?q?(=E9=BB=98=E8=AE=A4=E5=BC=80,10=E7=A7=92=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E6=9F=A5=E8=AF=A2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原自动刷新仅在线管理(online=1)进入时生效;现普通注单查询页也支持, 带开关(localStorage持久化)+倒计时显示,免手动点刷新。 --- application/agent/view/report/bet.html | 47 +++++++++++++++++++++----- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/application/agent/view/report/bet.html b/application/agent/view/report/bet.html index 5be4e0a..fa372a7 100644 --- a/application/agent/view/report/bet.html +++ b/application/agent/view/report/bet.html @@ -77,7 +77,10 @@
{$lang['refresh']} - + +
@@ -187,16 +190,44 @@ $(function(){ var online = $('#online').val(); var refreshUrl = $('#refreshUrl').val(); - var countDown = 10; - if(online == 1){ - $('.countDown').show(); - setInterval(function(){ + var INTERVAL = 10; // 自动刷新间隔(秒) + var countDown = INTERVAL; + var autoTimer = null; + + function startAuto(reloadFn){ + countDown = INTERVAL; + $('.countDown').show().html(countDown); + autoTimer = setInterval(function(){ countDown = countDown - 1; $('.countDown').html(countDown); - if(countDown == 0){ - location.href = refreshUrl; + if(countDown <= 0){ + reloadFn(); } - },1000); + }, 1000); + } + function stopAuto(){ + if(autoTimer){ clearInterval(autoTimer); autoTimer = null; } + $('.countDown').hide(); + } + + if(online == 1){ + // 从“在线管理”进入:保持原有自动刷新行为 + startAuto(function(){ location.href = refreshUrl; }); + }else{ + // 注单查询:可开关的今日实时自动刷新(默认开,刷新当前查询条件) + var saved = localStorage.getItem('bet_auto_refresh'); + var enabled = (saved === null) ? true : (saved === '1'); + $('#autoRefresh').prop('checked', enabled); + if(enabled){ startAuto(function(){ location.replace(location.href); }); } + $('#autoRefresh').on('change', function(){ + if($(this).is(':checked')){ + localStorage.setItem('bet_auto_refresh','1'); + startAuto(function(){ location.replace(location.href); }); + }else{ + localStorage.setItem('bet_auto_refresh','0'); + stopAuto(); + } + }); } }) From a94b9f7fcc9f753d08ad370fae738a15471c1f14 Mon Sep 17 00:00:00 2001 From: li Date: Sun, 31 May 2026 20:09:18 +0800 Subject: [PATCH 26/32] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BC=9A?= =?UTF-8?q?=E5=91=98=E8=AE=B0=E5=BD=95/=E6=8A=A5=E8=A1=A8=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2'=E6=9C=AC=E5=91=A8'=E5=9C=A8=E5=91=A8=E6=97=A5(date(w?= =?UTF-8?q?)=3D0)=E6=97=B6=E9=97=B4=E8=8C=83=E5=9B=B4=E7=AE=97=E6=88=90?= =?UTF-8?q?=E4=B8=8B=E5=91=A8=E5=AF=BC=E8=87=B4=E6=9F=A5=E6=97=A0=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PHP date(w) 周日返回0, date(d)-date(w)+1 在周日会把本周一推到下周一, 整个本周区间变成未来时间, 注单/记录查询返回0条(仅周日触发, 周一~周六正常). 用 date(w)?:7 将周日按第7天计算, 对周一~周六零影响. 覆盖 onlinechip/Pcapi(会员端 get_user_bets 等3处) + admin/Pcapi(3处)。 --- application/admin/controller/Pcapi.php | 12 ++++++------ application/onlinechip/controller/Pcapi.php | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/application/admin/controller/Pcapi.php b/application/admin/controller/Pcapi.php index e48c724..d020a14 100755 --- a/application/admin/controller/Pcapi.php +++ b/application/admin/controller/Pcapi.php @@ -1240,8 +1240,8 @@ class Pcapi extends Controller{ $startTime = mktime(0,0,0,date('m'),date('d')-1,date('Y')); $endTime = mktime(0,0,0,date('m'),date('d'),date('Y'))-1; }elseif($time_interval == 3){ - $startTime = mktime(0,0,0,date("m"),date("d")-date("w")+1,date("Y")); - $endTime = mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y")); + $startTime = mktime(0,0,0,date("m"),date("d")-(date("w")?:7)+1,date("Y")); + $endTime = mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7,date("Y")); } $betWhere = array(); $betWhere['create_time'] = array('between',[$startTime,$endTime]); @@ -1571,8 +1571,8 @@ class Pcapi extends Controller{ $startTime = mktime(0,0,0,date('m'),date('d')-1,date('Y')); $endTime = mktime(0,0,0,date('m'),date('d'),date('Y'))-1; }elseif($time_interval == 3){ - $startTime = mktime(0,0,0,date("m"),date("d")-date("w")+1,date("Y")); - $endTime = mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y")); + $startTime = mktime(0,0,0,date("m"),date("d")-(date("w")?:7)+1,date("Y")); + $endTime = mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7,date("Y")); } $betWhere = array(); $betWhere['create_time'] = array('between',[$startTime,$endTime]); @@ -1639,8 +1639,8 @@ class Pcapi extends Controller{ $startTime = mktime(0,0,0,date('m'),date('d')-1,date('Y')); $endTime = mktime(0,0,0,date('m'),date('d'),date('Y'))-1; }elseif($time_interval == 3){ - $startTime = mktime(0,0,0,date("m"),date("d")-date("w")+1,date("Y")); - $endTime = mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y")); + $startTime = mktime(0,0,0,date("m"),date("d")-(date("w")?:7)+1,date("Y")); + $endTime = mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7,date("Y")); } $betWhere = array(); $betWhere['create_time'] = array('between',[$startTime,$endTime]); diff --git a/application/onlinechip/controller/Pcapi.php b/application/onlinechip/controller/Pcapi.php index 76b8ac8..d5a8a3d 100755 --- a/application/onlinechip/controller/Pcapi.php +++ b/application/onlinechip/controller/Pcapi.php @@ -1790,8 +1790,8 @@ class Pcapi extends Controller{ $startTime = mktime(0,0,0,date('m'),date('d')-1,date('Y')); $endTime = mktime(0,0,0,date('m'),date('d'),date('Y'))-1; }elseif($time_interval == 3){ - $startTime = mktime(0,0,0,date("m"),date("d")-date("w")+1,date("Y")); - $endTime = mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y")); + $startTime = mktime(0,0,0,date("m"),date("d")-(date("w")?:7)+1,date("Y")); + $endTime = mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7,date("Y")); } $betWhere = array(); $betWhere['create_time'] = array('between',[$startTime,$endTime]); @@ -2298,8 +2298,8 @@ class Pcapi extends Controller{ $startTime = mktime(0,0,0,date('m'),date('d')-1,date('Y')); $endTime = mktime(0,0,0,date('m'),date('d'),date('Y'))-1; }elseif($time_interval == 3){ - $startTime = mktime(0,0,0,date("m"),date("d")-date("w")+1,date("Y")); - $endTime = mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y")); + $startTime = mktime(0,0,0,date("m"),date("d")-(date("w")?:7)+1,date("Y")); + $endTime = mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7,date("Y")); } $betWhere = array(); $betWhere['create_time'] = array('between',[$startTime,$endTime]); @@ -2363,8 +2363,8 @@ class Pcapi extends Controller{ $startTime = mktime(0,0,0,date('m'),date('d')-1,date('Y')); $endTime = mktime(0,0,0,date('m'),date('d'),date('Y'))-1; }elseif($time_interval == 3){ - $startTime = mktime(0,0,0,date("m"),date("d")-date("w")+1,date("Y")); - $endTime = mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y")); + $startTime = mktime(0,0,0,date("m"),date("d")-(date("w")?:7)+1,date("Y")); + $endTime = mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7,date("Y")); } $betWhere = array(); $betWhere['create_time'] = array('between',[$startTime,$endTime]); From e56ce3b13276a9f68ad1e4fbc0e38714679c1956 Mon Sep 17 00:00:00 2001 From: li Date: Sun, 31 May 2026 20:15:42 +0800 Subject: [PATCH 27/32] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=BB=93?= =?UTF-8?q?=E7=AE=97(=E6=B4=97=E7=A0=81/=E8=BF=94=E6=B0=B4)=E5=91=A8?= =?UTF-8?q?=E7=95=8C=E6=9F=A5=E8=AF=A2=E5=9C=A8=E5=91=A8=E6=97=A5(date(w)?= =?UTF-8?q?=3D0)=E7=AE=97=E6=88=90=E4=B8=8B=E5=91=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Settle.php xima()/rebate() 的本周/上周周界同样受 date(w) 周日=0 影响, 周日会把本周算成下周、上周算成本周, 导致代理结算页查无未结数据或周次错位. 统一 date(w)->date(w)?:7, -7 上周偏移保留, 周一~周六零影响. --- application/agent/controller/Settle.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/application/agent/controller/Settle.php b/application/agent/controller/Settle.php index cacfca2..7c4b181 100644 --- a/application/agent/controller/Settle.php +++ b/application/agent/controller/Settle.php @@ -30,12 +30,12 @@ class Settle Extends Common{ if($timeLength == 1 || $timeLength == 2){ if($timeLength == 1){ //上周时间 - $weekStart = date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-date("w")+1-7,date("Y"))); - $weekEnd = date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-date("w")+7-7,date("Y"))); + $weekStart = date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-(date("w")?:7)+1-7,date("Y"))); + $weekEnd = date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7-7,date("Y"))); }elseif($timeLength == 2){ //本周时间 - $weekStart = date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-date("w")+1,date("Y"))); - $weekEnd = date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y"))); + $weekStart = date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-(date("w")?:7)+1,date("Y"))); + $weekEnd = date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7,date("Y"))); } $startTime = strtotime($weekStart); $endTime = strtotime($weekEnd); @@ -474,12 +474,12 @@ class Settle Extends Common{ if($timeLength == 1 || $timeLength == 2){ if($timeLength == 1){ //上周时间 - $weekStart = date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-date("w")+1-7,date("Y"))); - $weekEnd = date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-date("w")+7-7,date("Y"))); + $weekStart = date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-(date("w")?:7)+1-7,date("Y"))); + $weekEnd = date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7-7,date("Y"))); }elseif($timeLength == 2){ //本周时间 - $weekStart = date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-date("w")+1,date("Y"))); - $weekEnd = date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y"))); + $weekStart = date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-(date("w")?:7)+1,date("Y"))); + $weekEnd = date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7,date("Y"))); } $startTime = strtotime($weekStart); $endTime = strtotime($weekEnd); From 6012eff9949d6e1d72d2ec7e911bf1c211f04748 Mon Sep 17 00:00:00 2001 From: li Date: Mon, 1 Jun 2026 15:27:50 +0800 Subject: [PATCH 28/32] =?UTF-8?q?fix:=20'=E8=BF=91=E4=B8=80=E5=91=A8'?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E6=9F=A5=E8=AF=A2=E6=94=B9=E4=B8=BA=E6=9C=80?= =?UTF-8?q?=E8=BF=917=E5=A4=A9=E6=BB=9A=E5=8A=A8=E7=AA=97=E5=8F=A3(?= =?UTF-8?q?=E5=90=AB=E6=98=A8=E5=A4=A9),=E4=BF=AE=E5=A4=8D=E5=91=A8?= =?UTF-8?q?=E4=B8=80=E6=9F=A5=E4=B8=8D=E5=88=B0=E6=98=A8=E5=A4=A9=E8=AE=B0?= =?UTF-8?q?=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit time_interval=3 原为'本周自然周',周一时本周从今天起、昨天属上周故查无数据, 与前端'近一周/Gần một tuần'语义不符。改为 date(d)-6 ~ date(d) 最近7天滚动, 任意一天都含昨天且无星期边界问题。仅会员记录查询(onlinechip/admin Pcapi), 代理结算 Settle.php 的本周/上周保持自然周不变。 --- application/admin/controller/Pcapi.php | 12 ++++++------ application/onlinechip/controller/Pcapi.php | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/application/admin/controller/Pcapi.php b/application/admin/controller/Pcapi.php index d020a14..7f24d2d 100755 --- a/application/admin/controller/Pcapi.php +++ b/application/admin/controller/Pcapi.php @@ -1240,8 +1240,8 @@ class Pcapi extends Controller{ $startTime = mktime(0,0,0,date('m'),date('d')-1,date('Y')); $endTime = mktime(0,0,0,date('m'),date('d'),date('Y'))-1; }elseif($time_interval == 3){ - $startTime = mktime(0,0,0,date("m"),date("d")-(date("w")?:7)+1,date("Y")); - $endTime = mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7,date("Y")); + $startTime = mktime(0,0,0,date("m"),date("d")-6,date("Y")); + $endTime = mktime(23,59,59,date("m"),date("d"),date("Y")); } $betWhere = array(); $betWhere['create_time'] = array('between',[$startTime,$endTime]); @@ -1571,8 +1571,8 @@ class Pcapi extends Controller{ $startTime = mktime(0,0,0,date('m'),date('d')-1,date('Y')); $endTime = mktime(0,0,0,date('m'),date('d'),date('Y'))-1; }elseif($time_interval == 3){ - $startTime = mktime(0,0,0,date("m"),date("d")-(date("w")?:7)+1,date("Y")); - $endTime = mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7,date("Y")); + $startTime = mktime(0,0,0,date("m"),date("d")-6,date("Y")); + $endTime = mktime(23,59,59,date("m"),date("d"),date("Y")); } $betWhere = array(); $betWhere['create_time'] = array('between',[$startTime,$endTime]); @@ -1639,8 +1639,8 @@ class Pcapi extends Controller{ $startTime = mktime(0,0,0,date('m'),date('d')-1,date('Y')); $endTime = mktime(0,0,0,date('m'),date('d'),date('Y'))-1; }elseif($time_interval == 3){ - $startTime = mktime(0,0,0,date("m"),date("d")-(date("w")?:7)+1,date("Y")); - $endTime = mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7,date("Y")); + $startTime = mktime(0,0,0,date("m"),date("d")-6,date("Y")); + $endTime = mktime(23,59,59,date("m"),date("d"),date("Y")); } $betWhere = array(); $betWhere['create_time'] = array('between',[$startTime,$endTime]); diff --git a/application/onlinechip/controller/Pcapi.php b/application/onlinechip/controller/Pcapi.php index d5a8a3d..6855a3d 100755 --- a/application/onlinechip/controller/Pcapi.php +++ b/application/onlinechip/controller/Pcapi.php @@ -1790,8 +1790,8 @@ class Pcapi extends Controller{ $startTime = mktime(0,0,0,date('m'),date('d')-1,date('Y')); $endTime = mktime(0,0,0,date('m'),date('d'),date('Y'))-1; }elseif($time_interval == 3){ - $startTime = mktime(0,0,0,date("m"),date("d")-(date("w")?:7)+1,date("Y")); - $endTime = mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7,date("Y")); + $startTime = mktime(0,0,0,date("m"),date("d")-6,date("Y")); + $endTime = mktime(23,59,59,date("m"),date("d"),date("Y")); } $betWhere = array(); $betWhere['create_time'] = array('between',[$startTime,$endTime]); @@ -2298,8 +2298,8 @@ class Pcapi extends Controller{ $startTime = mktime(0,0,0,date('m'),date('d')-1,date('Y')); $endTime = mktime(0,0,0,date('m'),date('d'),date('Y'))-1; }elseif($time_interval == 3){ - $startTime = mktime(0,0,0,date("m"),date("d")-(date("w")?:7)+1,date("Y")); - $endTime = mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7,date("Y")); + $startTime = mktime(0,0,0,date("m"),date("d")-6,date("Y")); + $endTime = mktime(23,59,59,date("m"),date("d"),date("Y")); } $betWhere = array(); $betWhere['create_time'] = array('between',[$startTime,$endTime]); @@ -2363,8 +2363,8 @@ class Pcapi extends Controller{ $startTime = mktime(0,0,0,date('m'),date('d')-1,date('Y')); $endTime = mktime(0,0,0,date('m'),date('d'),date('Y'))-1; }elseif($time_interval == 3){ - $startTime = mktime(0,0,0,date("m"),date("d")-(date("w")?:7)+1,date("Y")); - $endTime = mktime(23,59,59,date("m"),date("d")-(date("w")?:7)+7,date("Y")); + $startTime = mktime(0,0,0,date("m"),date("d")-6,date("Y")); + $endTime = mktime(23,59,59,date("m"),date("d"),date("Y")); } $betWhere = array(); $betWhere['create_time'] = array('between',[$startTime,$endTime]); From f67439bfe2db70d8321771ce4fcb7fdee873b6c2 Mon Sep 17 00:00:00 2001 From: li Date: Mon, 1 Jun 2026 23:11:33 +0800 Subject: [PATCH 29/32] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E9=A1=B6?= =?UTF-8?q?=E7=BA=A7=E4=BB=A3=E7=90=86(agent=5Fparent=5Fid=3D0)=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E7=BC=96=E8=BE=91=E4=BF=9D=E5=AD=98(=E6=80=BB?= =?UTF-8?q?=E8=B4=A6=E5=8F=B7=E7=BB=99=E4=B8=80=E7=BA=A7=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E6=94=B9=E5=8F=82=E6=95=B0=E6=8A=A5'=E4=B8=8A=E7=BA=A7?= =?UTF-8?q?=E9=94=99=E8=AF=AF')?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit do_edit 原逻辑 parent_id<=0 直接 die(parent_error),且后续全程访问 agentParent 做封顶校验, 导致顶级代理(一级总代)永远无法编辑保存。改为:顶级代理构造不设限虚拟上级, 封顶校验自动放行,封底校验(不得低于下级最高费率)与写入逻辑保持不变。对非顶级代理零影响。 --- application/agent/controller/Agent.php | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/application/agent/controller/Agent.php b/application/agent/controller/Agent.php index 11ee619..6178550 100755 --- a/application/agent/controller/Agent.php +++ b/application/agent/controller/Agent.php @@ -565,12 +565,24 @@ class Agent Extends Common{ if(!$user || $user['agent'] == 0){ die(json_encode(['code'=>0,'msg'=>$lang['error_id']])); } + // 顶级代理(agent_parent_id=0)无真实上级:构造一个不设限的虚拟上级,使所有"不得高于上级"封顶校验自动放行; + // "不得低于下级"封底校验与写入逻辑保持不变(顶级代理仍受其下级最高费率约束)。 if($parent_id <= 0){ - die(json_encode(['code'=>0,'msg'=>$lang['parent_error']])); - } - $agentParent = Db::name('user')->where('id',$parent_id)->find(); - if(!$agentParent || $agentParent['agent'] == 0){ - die(json_encode(['code'=>0,'msg'=>$lang['parent_error']])); + $agentParent = [ + 'limit_low' => 0, 'limit_high' => 99999999999, + 'limit_low_tie' => 0, 'limit_high_tie' => 99999999999, + 'limit_low_pair' => 0, 'limit_high_pair' => 99999999999, + 'limit_low_nn' => 0, 'limit_high_nn' => 0, + 'agent_ximalv' => 100, 'agent_ximalv_dt' => 100, + 'agent_ximalv_nn' => 100, 'agent_ximalv_tc' => 100, + 'agent_cs' => 100, 'rebate_rate' => 100, + 'agent_parent_id' => 0, + ]; + }else{ + $agentParent = Db::name('user')->where('id',$parent_id)->find(); + if(!$agentParent || $agentParent['agent'] == 0){ + die(json_encode(['code'=>0,'msg'=>$lang['parent_error']])); + } } if(!$nickname){ die(json_encode(['code'=>0,'msg'=>$lang['empty_nickname']])); From dd84f674b0bd6843b3fdd02ef7080f6dd02ed489 Mon Sep 17 00:00:00 2001 From: li Date: Mon, 1 Jun 2026 23:45:15 +0800 Subject: [PATCH 30/32] =?UTF-8?q?fix:=20=E5=BD=BB=E5=BA=95=E8=A7=A3?= =?UTF-8?q?=E8=80=A6=E5=AD=98=E5=8F=96=E6=AC=BE=E6=98=BE=E9=9A=90=E4=B8=8E?= =?UTF-8?q?agent=5Ftype,=E5=8F=AA=E6=8C=89pay=5Fchannel=E4=B8=8B=E5=8F=91(?= =?UTF-8?q?=E9=98=B2=E9=94=99=E9=85=8D=E5=A4=8D=E5=8F=91)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:登录/用户信息接口死卡 agent_type==1 才下发支付渠道,靠运营手动保持 agent_type 与 pay_channel 一致,一改错(如人工线配在线通道)用户就没存取款。 改为只看 pay_channel:OPR=人工(下发收款信息),非空非OPR=在线(下发币种/链),空=隐藏。 顺带修复 get_user_info 此前缺 OPR 分支导致人工线用户刷新丢充值信息的隐患。 覆盖移动端(Portal)+PC,均走此接口。170 错配存量已单独 UPDATE 修复。 --- application/onlinechip/controller/Pcapi.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/application/onlinechip/controller/Pcapi.php b/application/onlinechip/controller/Pcapi.php index 6855a3d..1dea564 100755 --- a/application/onlinechip/controller/Pcapi.php +++ b/application/onlinechip/controller/Pcapi.php @@ -197,7 +197,7 @@ class Pcapi extends Controller{ $find['pay_channel'] = ''; $find['pay_channel_currency'] = []; $find['pay_channel_coin_chain'] = []; - if($topAgent['agent_type'] == 1){ + if($topAgent['pay_channel'] && $topAgent['pay_channel'] != 'OPR'){ // 现金线走支付渠道 $find['pay_channel'] = $topAgent['pay_channel']; $find['pay_channel_currency'] = []; @@ -211,7 +211,7 @@ class Pcapi extends Controller{ $find['pay_channel_coin_chain'] = json_decode($payChannelInfo['coin_chain'],true); } } - } elseif ($topAgent['agent_type'] == 2 && $topAgent['pay_channel'] == 'OPR') { // 人工转帐上分,前端显示充值信息 + } elseif ($topAgent['pay_channel'] == 'OPR') { // 人工转帐上分,前端显示充值信息(不依赖 agent_type,只看 pay_channel) $find['pay_channel'] = $topAgent['pay_channel']; $find['pay_channel_address'] = $topAgent['pay_channel_address']; } @@ -270,7 +270,7 @@ class Pcapi extends Controller{ $find['pay_channel'] = ''; $find['pay_channel_currency'] = []; $find['pay_channel_coin_chain'] = []; - if($topAgent['agent_type'] == 1){ + if($topAgent['pay_channel'] && $topAgent['pay_channel'] != 'OPR'){ // 现金线走支付渠道 $find['pay_channel'] = $topAgent['pay_channel']; $find['pay_channel_currency'] = []; @@ -284,6 +284,9 @@ class Pcapi extends Controller{ $find['pay_channel_coin_chain'] = json_decode($payChannelInfo['coin_chain'],true); } } + } elseif($topAgent['pay_channel'] == 'OPR'){ // 人工转帐上分:与 login 保持一致下发收款信息(此前 get_user_info 缺失,刷新会丢) + $find['pay_channel'] = 'OPR'; + $find['pay_channel_address'] = $topAgent['pay_channel_address']; } $find['manager'] = []; if($find['bet_type'] == 2){ From ccf0af4ed21a7066ad169308a01a5a0ca1cb7f9e Mon Sep 17 00:00:00 2001 From: li Date: Wed, 3 Jun 2026 19:12:26 +0800 Subject: [PATCH 31/32] =?UTF-8?q?fix:=20AlinPay=E5=85=85=E5=80=BC=E4=B8=8A?= =?UTF-8?q?=E5=88=86=E6=8C=89=E4=BB=A3=E6=94=B6=E6=89=8B=E7=BB=AD=E8=B4=B9?= =?UTF-8?q?=E7=8E=87=E6=8A=98=E7=AE=97,=E5=AE=A2=E6=88=B7=E6=89=BF?= =?UTF-8?q?=E6=8B=85=E6=89=8B=E7=BB=AD=E8=B4=B9,=E9=98=B2=E4=BB=A3?= =?UTF-8?q?=E4=BB=98=E8=B4=A6=E6=88=B7=E8=A2=AB=E6=8E=8F=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:AlinPay代收时从平台代付账户扣手续费(回调real_amount仍是充值全额), 但系统全额上分→客户余额>账户实收→提现必差手续费那块,账户越提越空。 改为按ALIN_VN配置collection_fee_rate(%)折算上分额:充100万→上分99万(1%费率), 上分/扣代理同步折算,使客户余额=账户实收,代付永远够。back_money仍记全额供审计。 --- application/onlinechip/controller/traits/alinPay.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/application/onlinechip/controller/traits/alinPay.php b/application/onlinechip/controller/traits/alinPay.php index 0c92fb3..b4404fa 100644 --- a/application/onlinechip/controller/traits/alinPay.php +++ b/application/onlinechip/controller/traits/alinPay.php @@ -232,6 +232,15 @@ trait alinPay 'agent' => 1, ])->lock(true)->find(); + // 代收手续费由客户承担:AlinPay 代收时从平台代付账户扣手续费(回调 real_amount 仍是充值全额), + // 若全额上分会导致代付账户被持续掏空(充100万→账户净收99万→提现100万必差)。 + // 故按 ALIN_VN 配置的 collection_fee_rate(百分比) 折算上分额,使"客户余额=账户实收"。 + $alinCfg = json_decode(Db::name('pay_channel')->where('key', 'ALIN_VN')->value('value'), true); + $alinFeeRate = isset($alinCfg['collection_fee_rate']) ? floatval($alinCfg['collection_fee_rate']) : 0; + if ($alinFeeRate > 0) { + $order['money'] = round($order['money'] * (1 - $alinFeeRate / 100), 2); + } + if (!$zdl || $zdl['money'] < $order['money']) { Db::rollback(); addLogToFile('代收结算失败:代理余额不足 order=' . $orderNo, 'alin_callback_error', 'alin'); From 788b8a0af3fe2e8dd5f7e674b4cae964e058cb2a Mon Sep 17 00:00:00 2001 From: li Date: Wed, 3 Jun 2026 19:31:14 +0800 Subject: [PATCH 32/32] =?UTF-8?q?revert+fix:=20=E5=9B=9E=E6=BB=9A=E5=85=85?= =?UTF-8?q?=E5=80=BC=E6=89=A3=E8=B4=B9=E6=8A=98=E7=AE=97(=E6=81=A2?= =?UTF-8?q?=E5=A4=8D=E5=85=A8=E9=A2=9D=E4=B8=8A=E5=88=86)+=E5=8F=96?= =?UTF-8?q?=E6=B6=88=E6=8F=90=E7=8E=B0=E6=89=8B=E7=BB=AD=E8=B4=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 业务调整:客户不让用户承担手续费,改为客户自行预存代付账户余额(全额上分全额提现)。 1) 回滚 alin_recharge_settle 的代收费率折算,恢复充值全额上分 2) apply_withdraw/apply_withdraw_bank 提现手续费默认值 1→0,取消提现手续费 --- application/onlinechip/controller/Pcapi.php | 4 ++-- application/onlinechip/controller/traits/alinPay.php | 9 --------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/application/onlinechip/controller/Pcapi.php b/application/onlinechip/controller/Pcapi.php index 1dea564..6c41cb8 100755 --- a/application/onlinechip/controller/Pcapi.php +++ b/application/onlinechip/controller/Pcapi.php @@ -3830,7 +3830,7 @@ class Pcapi extends Controller{ $system = Db::name('system')->find(); $money = $user['money']; $withdrawMoney = empty($system['withdraw_money']) ? 100 : $system['withdraw_money']; - $withdrawFee = empty($system['withdraw_fee']) ? 1 : $system['withdraw_fee']; + $withdrawFee = empty($system['withdraw_fee']) ? 0 : $system['withdraw_fee']; // 计算积分兑换 $amountMoney = $withdrawMoney/100*($amount); @@ -3912,7 +3912,7 @@ class Pcapi extends Controller{ $system = Db::name('system')->find(); $money = $user['money']; $withdrawMoney = empty($system['withdraw_money']) ? 100 : $system['withdraw_money']; - $withdrawFee = empty($system['withdraw_fee']) ? 1 : $system['withdraw_fee']; + $withdrawFee = empty($system['withdraw_fee']) ? 0 : $system['withdraw_fee']; // 计算积分兑换 $amountMoney = $withdrawMoney/100*($amount); diff --git a/application/onlinechip/controller/traits/alinPay.php b/application/onlinechip/controller/traits/alinPay.php index b4404fa..0c92fb3 100644 --- a/application/onlinechip/controller/traits/alinPay.php +++ b/application/onlinechip/controller/traits/alinPay.php @@ -232,15 +232,6 @@ trait alinPay 'agent' => 1, ])->lock(true)->find(); - // 代收手续费由客户承担:AlinPay 代收时从平台代付账户扣手续费(回调 real_amount 仍是充值全额), - // 若全额上分会导致代付账户被持续掏空(充100万→账户净收99万→提现100万必差)。 - // 故按 ALIN_VN 配置的 collection_fee_rate(百分比) 折算上分额,使"客户余额=账户实收"。 - $alinCfg = json_decode(Db::name('pay_channel')->where('key', 'ALIN_VN')->value('value'), true); - $alinFeeRate = isset($alinCfg['collection_fee_rate']) ? floatval($alinCfg['collection_fee_rate']) : 0; - if ($alinFeeRate > 0) { - $order['money'] = round($order['money'] * (1 - $alinFeeRate / 100), 2); - } - if (!$zdl || $zdl['money'] < $order['money']) { Db::rollback(); addLogToFile('代收结算失败:代理余额不足 order=' . $orderNo, 'alin_callback_error', 'alin');