diff --git a/api/pay.php b/api/pay.php
index 06ebd14..ea53561 100644
--- a/api/pay.php
+++ b/api/pay.php
@@ -524,6 +524,7 @@ function queryOrder($token) {
'money' => $row['money'],
'bonds' => (int)$row['bond_amount'],
'paid_at' => $row['paid_at'],
+ 'created_at' => $row['created_at'],
], $message);
}
@@ -542,6 +543,9 @@ try {
case 'pay_redirect':
handlePayRedirect(); // 内部已 exit
break;
+ case 'sync_poller':
+ syncPoller(getParam('token'));
+ break;
case 'query_order':
queryOrder(getParam('token'));
break;
diff --git a/api/poller_online.php b/api/poller_online.php
index 6a5baa7..4b66ca6 100644
--- a/api/poller_online.php
+++ b/api/poller_online.php
@@ -85,11 +85,16 @@ function getSQLite() {
function getPlatformDB() {
static $pdo = null;
if ($pdo === null) {
- $dsn = "mysql:host={$GLOBALS['PLATFORM_DB_HOST']};dbname={$GLOBALS['PLATFORM_DB_NAME']};charset=utf8mb4";
- $pdo = new PDO($dsn, $GLOBALS['PLATFORM_DB_USER'], $GLOBALS['PLATFORM_DB_PASS'], [
- PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
- PDO::ATTR_TIMEOUT => 5,
- ]);
+ try {
+ $dsn = "mysql:host={$GLOBALS['PLATFORM_DB_HOST']};dbname={$GLOBALS['PLATFORM_DB_NAME']};charset=utf8mb4";
+ $pdo = new PDO($dsn, $GLOBALS['PLATFORM_DB_USER'], $GLOBALS['PLATFORM_DB_PASS'], [
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
+ PDO::ATTR_TIMEOUT => 5,
+ ]);
+ } catch (Exception $e) {
+ debugLog("Platform DB connection failed", ['error' => $e->getMessage()]);
+ throw $e; // re-throw to be caught by pollPaidOrders
+ }
}
return $pdo;
}
@@ -267,5 +272,10 @@ function markNotified($pdo, $tradeNo) {
// 不在此处自动执行补单(由调用方自行决定何时触发)。
if (!defined('POLLER_NO_AUTO_RUN')) {
header('Content-Type: application/json; charset=utf-8');
- pollPaidOrders();
+ try {
+ pollPaidOrders();
+ } catch (\Throwable $e) {
+ debugLog('[poller_online] 未捕获异常', ['error' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine()]);
+ echo json_encode(['error' => 'uncaught_exception', 'detail' => $e->getMessage()]);
+ }
}
diff --git a/player.php b/player.php
index 542c46a..6eae0b6 100644
--- a/player.php
+++ b/player.php
@@ -1113,6 +1113,17 @@ if ($currentVersion !== $BUILD_VERSION) {
btn.textContent = '✅ 支付完成';
btn.onclick = null;
} else if (res.data.status === 'created') {
+ // 检查订单是否已过期(5分钟)
+ const nowSec = Math.floor(Date.now() / 1000);
+ const createdAt = res.data.created_at || 0;
+ if (createdAt && (nowSec - createdAt) > 300) {
+ // 已过期:清除本地记录,重置按钮
+ localStorage.removeItem('sdf1_last_recharge_no');
+ st.innerHTML = '订单已过期(超过5分钟),请重新下单。';
+ btn.disabled = false;
+ btn.textContent = '🅰️ 支付宝支付 ¥0.01';
+ btn.onclick = startRecharge;
+ } else {
// 未支付:显示继续支付
btn.textContent = '🔄 继续支付 ¥' + (res.data.money || '0.01');
btn.onclick = async function() {
@@ -1140,6 +1151,7 @@ if ($currentVersion !== $BUILD_VERSION) {
};
st.innerHTML = '⚠️ 您有一笔未完成的订单,点此继续支付';
document.getElementById('rechargeQueryBtn').style.display = 'block';
+ }
}
// 如果是 expired 或其他状态,不处理,保持默认按钮
}