fix: auto-cleanup stale payment orders and expired pending bindings

- closeStaleOrders: marks payment orders older than 24h as 'closed'
- closeExpiredPending: marks expired binding requests (bind_status=3) as cancelled
- Both run on app startup (SCF cold start), no cron needed
- countPendingByUser already filters to 2h window (previous commit)
这个提交包含在:
Guoguo
2026-05-18 03:52:03 -07:00
父节点 343eeca89a
当前提交 c21a0912c6
修改 3 个文件,包含 22 行新增1 行删除
+8
查看文件
@@ -80,4 +80,12 @@ app.use((err, req, res, _next) => {
res.status(500).json(fail(3001, 'server_error')) res.status(500).json(fail(3001, 'server_error'))
}) })
// Clean up stale records on startup (SCF cold start)
require('./dao/payment-order.dao').closeStaleOrders().catch(err => {
console.error('[STARTUP] closeStaleOrders failed:', err.message)
})
require('./dao/binding.dao').closeExpiredPending().catch(err => {
console.error('[STARTUP] closeExpiredPending failed:', err.message)
})
module.exports = app module.exports = app
+7
查看文件
@@ -202,11 +202,18 @@ async function countActiveByUser(userId) {
return rows[0].total return rows[0].total
} }
async function closeExpiredPending() {
return query(
'UPDATE bindings SET bind_status = 4 WHERE bind_status = 3 AND bind_expires < NOW()'
)
}
module.exports = { module.exports = {
findActiveByUser, findActiveByUser,
findDeviceExists, findDeviceExists,
cancelPending, cancelPending,
createPending, createPending,
closeExpiredPending,
confirmBind, confirmBind,
mockBind, mockBind,
unbindByUser, unbindByUser,
+7 -1
查看文件
@@ -84,4 +84,10 @@ async function countPendingByUser(userId) {
return rows[0].cnt return rows[0].cnt
} }
module.exports = { createOrder, findByOutTradeNo, markPrepay, markPaidAndActivateSubscription, markClosed, markFailed, countPendingByUser } async function closeStaleOrders() {
return query(
"UPDATE payment_orders SET status = 'closed', trade_state = 'EXPIRED' WHERE status IN ('created', 'paying') AND created_at < DATE_SUB(NOW(), INTERVAL 24 HOUR)"
)
}
module.exports = { createOrder, findByOutTradeNo, markPrepay, markPaidAndActivateSubscription, markClosed, markFailed, countPendingByUser, closeStaleOrders }