// 現行狀態:EgopayApprM.status const STATUS = { PENDING: 0, // 待執行 SUCCESS: 1, // 成功(人工點確認) FAILED: 2, // 失敗 }; // 問題:0→1 之間沒有中間狀態,無法區分「還沒匯」和「已匯未確認」
| 風險 | 發生位置 | 根因 |
|---|---|---|
| 重複匯款 | popup.js FillForm button |
無 status check,點兩次就填兩次。多人同帳號操作無 lock。 |
| 狀態斷層 | EgopayApprM status 欄位 |
只有 0/1/2,缺 3=匯款中。人工匯完到人工點確認之間是黑洞。 |
| 手動回填錯誤 | ApprC::update_status() |
transaction_time / bank / fee 全靠人工輸入,無 source of truth 可驗。 |
| 出帳無記錄 | AutoBankingC::receive_esun_bank() |
出帳交易被 if (!$in) continue; 過濾掉,不寫 DB。 |
auto_banking/ — Chrome Extension (MV3)background.js — Refresh (15s) + StateCheck (5s) 雙 alarm Extensionpopup.js — 撥款單列表 + FillForm 按鈕src/banks/{esun,first,fubon,taishin,sinopac,tcb,skbank,hwatai,tfcc}.js — 各銀行 content scriptsrc/content-main.js — 共用 message handler + StateCheck handlergamepp-web/ — Laravel HQ 後端 HQapp/Http/Controllers/AutoBankingC.php — 接收交易 + payment 配對app/Http/Controllers/ApprC.php — 撥款審核 + update_statusapp/Models/EgopayApprM.php — 撥款單 model (status 0/1/2)bank_transactions table — 已有 out, balance 欄位(schema 預留,未使用)
feat/ticket-state-management branch 半成品可用。
資料基礎層。Extension 上傳入帳+出帳所有交易,HQ 完整儲存,餘額連貫性驗證。
// 現行:只上傳入帳 if (tx.in > 0) records.push(tx); // 改為:全部上傳,加 direction 標記 tx.direction = tx.in > 0 ? 'in' : 'out'; records.push(tx);
// 現行去重 key(48h 滾動窗口) const dedupKey = `${date}_${time}_${account}_${amount}`; // 改為:入帳/出帳分開去重 const dedupKey = `${date}_${time}_${account}_${direction}_${direction === 'in' ? amount_in : amount_out}`;
src/banks/*.js — 移除 in_record 過濾 修改background.js — 去重 key 加 direction 修改
// AutoBankingC::receive_esun_bank() // 現行:出帳跳過 if (!$record['in']) continue; // 改為:出帳也寫入 bank_transactions if ($record['direction'] === 'out') { BankTransaction::create([ 'bank' => $bank, 'out' => $record['out'], 'account' => $record['account'], 'balance' => $record['balance'], 'accounting_datetime' => $record['datetime'], ]); continue; // 不進 payment 配對 }
-- bank_transactions 新增索引 ALTER TABLE bank_transactions ADD INDEX idx_bank_out_acctime (bank, out, accounting_datetime);
// 驗證邏輯(同帳戶按時間排序) // prev.balance + curr.in - curr.out == curr.balance // 不連貫 → 標記 balance_gap 警告(不硬擋)
AutoBankingC.php — 出帳寫入 + 餘額驗證 修改 HQbank_transactions — 加 index migration
控管層。撥款單五階段狀態追蹤 + 三道防重複閘門 + 出帳↔撥款自動配對。
// Extension 端 ticket 狀態(chrome.storage.local) const TICKET_STATE = { UNFILLED: 'unfilled', // 初始 → 5min 後 needs_speed → 15min 後 overdue FILLED: 'filled', // FillForm 填入後 RELEASING: 'releasing', // 放行確認頁偵測到 RELEASED: 'released', // 放行結果頁偵測到成功 CONFIRMED: 'confirmed', // 出帳 bank_tx 配對成功 }; // HQ 端 EgopayApprM.status const HQ_STATUS = { PENDING: 0, // 待執行 SUCCESS: 1, // 成功 FAILED: 2, // 失敗 FILLING: 3, // 匯款中(新增) };
| 閘門 | 觸發時機 | 檢查邏輯 | 行為 |
|---|---|---|---|
| 1. FillForm 鎖定 | popup.js 點擊填入 | ticket_state !== 'unfilled' |
隱藏按鈕,不可再填 |
| 2. Pre-check API | FillForm 執行前 | POST /api/auto_banking/pre_checkEgopayApprM.status === 0 |
status !== 0 → 拒絕,回傳目前狀態 |
| 3. 出帳比對 | 放行前 | 同帳號+同金額+近 10 min 出帳 | 彈出警告,需人員確認 |
| 銀行 | 偵測方式 | 狀態 |
|---|---|---|
| 玉山 E.SUN | 確認頁 DOM 解析 → 匹配 ticket → releasing結果頁輪詢成功 → released |
已完成 |
| 第一銀行 | 放行頁 DOM 偵測 | 已完成 |
| 富邦 / 台新 / 永豐 合庫 / 新光 |
各銀行放行確認頁 + 結果頁 DOM 結構待分析 需截圖 HTML 結構後實作 |
待開發 |
| 華泰 / 淡水一信 | 已有 API balance check,放行頁待分析 | 待開發 |
// background.js: matchOutRecordsToTickets() // 每 5 秒 StateCheck 觸發 for (const ticket of releasedTickets) { const match = outRecords.find(tx => tx.account === ticket.targetAccount && Math.abs(tx.out - ticket.amount) <= 30 && // 容許匯費差額 withinMinutes(tx.datetime, ticket.releaseTime, 30) ); if (match) { updateTicketState(ticket.id, 'confirmed'); // → 呼叫 HQ API 同步 status 3→1 } }
| Endpoint | Method | 用途 | Request | Response |
|---|---|---|---|---|
/api/auto_banking/pre_check |
POST | FillForm 前檢查 | {ticket_id} |
{ok, status, locked_by} |
/api/auto_banking/mark_filling |
POST | 標記匯款中 | {ticket_id} |
{ok} status→3 |
/api/auto_banking/confirm |
POST | 出帳配對確認 | {ticket_id, bank_tx_id} |
{ok} status→1 + 回填 |
src/banks/{fubon,taishin,sinopac,tcb,skbank,hwatai,tfcc}.js — 放行偵測 新增 Extensionpopup.js — 狀態標籤 + 鎖定 修改 Extensionbackground.js — matchOutRecords + API 呼叫 修改 ExtensionApprC.php — pre_check / mark_filling / confirm 新增 HQEgopayApprM.php — status=3 常數 修改 HQroutes/api.php — 3 條新 route 修改 HQfeat/ticket-state-management branch(玉山/第一已實作)
自動化層。出帳配對成功後,自動回填所有人工欄位。
// ApprC::confirm() 被呼叫時,自動回填 $bankTx = BankTransaction::find($bank_tx_id); $ticket->transaction_time = $bankTx->accounting_datetime; $ticket->bank = $bankTx->bank; $ticket->fee = $bankTx->out - $appr->amount; $ticket->operator_id = auth()->id(); // 獨立 HQ 帳號 $appr->status = 1; $appr->bank_transaction_id = $bankTx->id; // 建立連結 $appr->save(); $ticket->save();
| 欄位 | 現行 | 自動化來源 | 驗證方式 |
|---|---|---|---|
transaction_time |
人工複製貼上 | bank_transactions.accounting_datetime |
時間差 < 30 min |
bank |
人工下拉選擇 | bank_transactions.bank |
必須 match |
fee |
人工輸入 (通常 15) | bank_tx.out - appr.amount |
差額 0~30 合理範圍 |
operator_id |
人工下拉選擇 | auth()->id() |
— |
-- egopay_apprs 新增欄位:連結出帳記錄 ALTER TABLE egopay_apprs ADD COLUMN bank_transaction_id BIGINT UNSIGNED NULL AFTER status, ADD INDEX idx_bank_tx (bank_transaction_id);
ApprC.php — confirm() 加自動回填 修改 HQTicketM.php — transaction_time 等欄位更新 修改 HQEgopayApprM.php — 加 bank_transaction_id 欄位 migration HQ
偵測層。基於完整入帳+出帳資料,自動偵測異常交易。
| 異常類型 | 偵測條件 | 比對欄位 | 動作 |
|---|---|---|---|
| 重複匯款 | 同帳號+同金額 出帳 > 撥款單數 | account, out, datetime |
自動建立異常單 |
| 時間錯誤 | 金額+帳號+銀行 Match 時間 Unmatch (>30min) |
amount, account, bank, datetime |
標記待確認 |
| 銀行錯誤 | 金額+帳號+時間 Match 銀行欄位不一致 |
amount, account, datetime, bank |
標記待確認 |
| 未開單 | bank_tx 入帳無對應 payment | in, account, datetime |
列入未開單清單 |
| 餘額缺口 | prev.balance + in - out ≠ curr.balance |
balance, in, out |
標記帳戶缺口 |
// 偵測到重複匯款後的處置選項 enum DuplicateResolution { REFUND_BANK, // 匯回原帳號 SELL_ORDER_REFUND, // 賣單還款(客戶多賣一次幣) BUY_ORDER_REFUND, // 買單還款 + 開新賣單撮合 }
id 和分站單號開單時間和繳費時間篩選銀行帳號反查分站、會員其他損失、其他收入分類AnomalyDetectionService.php — 異常偵測引擎 新增 HQAnomalyController.php — 異常單 CRUD + Dashboard 新增 HQanomalies table — 異常單 migration
| Phase | Extension 端 | HQ 端 | DB Migration | 前置條件 |
|---|---|---|---|---|
| 1 | 9 banks content scriptbackground.js 去重 |
AutoBankingC.php |
加 index | 無 |
| 2 | 7 banks 放行偵測popup.js 狀態鎖定 |
ApprC.php 3 APIEgopayApprM.php |
— | Phase 1 |
| 3 | — | ApprC.php 回填TicketM.php |
加欄位 | Phase 2 + 獨立帳號 |
| 4 | — | 偵測引擎 + Dashboard | 新 table | Phase 1~3 |
| 風險 | 等級 | 緩解 |
|---|---|---|
| 銀行改版 → 放行偵測失效 | 中 | 偵測失敗 fallback 手動確認,不阻斷。DOM hash 變更時 console.warn。 |
| 出帳配對誤判(同金額同時間) | 中 | 帳號必須 match;多候選 → 不自動配對,標記人工確認。 |
| Extension 新舊版本並存 | 低 | HQ API 向後相容。舊版不送 direction,HQ 視為入帳(現行行為)。 |
ApprC::update_status() race condition |
中 | pre_check API 使用 SELECT ... FOR UPDATE,mark_filling 做 CAS。 |
| 餘額驗證誤報 | 低 | 警告不硬擋。缺口清單供人工確認。 |