銀行流水採集
本頁說明
講什麼:每家銀行的流水如何到達系統、流水表結構與分片策略、採集定時任務、流水類型碼 適合誰:需要理解"匹配引擎的輸入從哪來"的產品經理 前置閱讀:入金方式總覽預計閱讀:5 分鐘 負責人:入金產品經理
核心要點:銀行流水採集是匹配引擎的輸入源,不同銀行的採集方式差異極大——從秒級即時推送到每日 3 次批量拉取,直接決定用戶的入金等待時間。
快速跳轉 — 你可能想做的事:
- 用戶說"錢沒到",想查流水到了沒?→ 匯總對比表(看各銀行時效)
- 想了解某家銀行的流水怎麼進來的?→ 按銀行的流水採集方式
- 想知道流水表怎麼分片的?→ 流水表結構與分片
- 想接入新銀行的流水採集?→ 變更指南 § 新增銀行
- 想看流水採集的定時任務?→ 採集定時任務
為什麼需要這一頁
Push 模式(FPS、網銀、ATM 等)入金的核心前提:銀行流水必須先到達系統,匹配引擎才能工作。
不同銀行的流水到達方式差異極大——從秒級即時推送到每天僅 3 次的批量拉取。這直接決定了用戶從轉賬到看到"入金成功"的等待時間。理解流水採集機制,是診斷"錢沒到"問題和評估銀行接入方案的基礎。
eDDA/BST 不經過流水採集
Pull 模式(eDDA)和 Direct 模式(BST)的入金不依賴流水採集——系統自己發起扣款/轉賬指令,知道何時完成。本頁僅覆蓋 Push 模式的流水採集。
按銀行的流水採集方式
即時推送類
匯豐 HSBC — MT910 即時通知
| 維度 | 說明 |
|---|---|
| 協議 | SWIFT MT910 格式,通過 SFTP 傳輸 + GPG 加密 |
| 到達時效 | 秒級——銀行入賬後即推送 |
| 採集服務 | hsbc_bank_flow_service(Python) |
| TransType | 218(HSBC) |
| 去重機制 | Transaction Reference Number(:20: 字段)唯一約束 |
MT910 是 SWIFT 標準的"入賬確認"報文。系統定期從 SFTP 下載 GPG 加密文件,解密後解析 MT910 格式,提取交易參考號、金額、幣種、付款人姓名等字段。
關鍵解析字段:
:20:→ 交易參考號(去重標識):32A:→ 日期 + 幣種 + 金額(複合字段:YYMMDD + CCY + Amount):50K:→ 付款人姓名(用於姓名匹配):72:→ 附言資訊(補充資訊)
渣打 SCB / 廣發 CGB — FPS API 即時
| 維度 | 渣打 SCB | 廣發 CGB |
|---|---|---|
| 協議 | Webhook 回調 + REST API | REST API 批量/單筆 |
| 到達時效 | 秒級 | 秒級 |
| 採集服務 | scb_service(Go) | cgb_fps_service(Go) |
| TransType | 219(SC_SUBACC) | FPS 相關 |
| 隊列機制 | DB Queue(9 個 Job Handler) | DB Queue(4 個 Job Handler) |
渣打通過 Webhook 主動推送交易事件到系統,系統先持久化事件再入隊處理(ProcessWebhookEvent → 保存 → 入隊)。廣發通過 REST API 提交批量或單筆支付任務,系統通過查詢 Job 輪詢結果。
招行/民生 BST — Socket 雙向鏈路
| 維度 | 說明 |
|---|---|
| 協議 | 二進制 Socket 雙向鏈路,消息級加密 |
| 到達時效 | 秒級——事件驅動,銀行主動推送 |
| 採集服務 | cmb_stock_trans / ms_stock_bank_transaction |
| TransType | 101(民生 BST)、102(招行 BST)、304(天星 BST) |
BST(Bank-Securities Transfer)銀證轉賬通過長連接 Socket 通信。銀行側完成資金劃轉後,通過已建立的 Socket 鏈路主動推送結果。系統無需輪詢。
注意區分
BST 流水是 Direct 模式的一部分,不經過匹配引擎。但 BST 流水仍會寫入 flows 表,用於對賬和監控。
定時拉取類
中銀 BOCHK — B2E 批量拉取
| 維度 | 說明 |
|---|---|
| 協議 | B2E(Business-to-Enterprise)XML-RPC |
| 到達時效 | 每日 3 次拉取 + 約 2 小時轉換處理 |
| 採集服務 | bochk_flow_go(Go) |
| TransType | 301(BOC) |
| 去重機制 | 預查詢 DB 跳過已存在記錄 |
中銀 B2E 是最慢的流水來源。系統每日分 3 次主動拉取:
| 批次 | 時間 | 拉取內容 |
|---|---|---|
| TodayActivity | ~06:00 | 當日已結算交易 |
| AcctStatement | ~07:00 | 前一日對賬單 |
| AcctActivity | ~08:00 | 近 2 日交易明細(含對手方資訊) |
拉取後還需 ~2 小時的流水轉換(TrdRecordFlowConverter / TransactionRecordFlowConverter),將原始記錄標準化為 boc_bank_flow 格式後寫入 flows 表。
PM 關注點:中銀入金的"到賬慢"主要來自流水採集延遲,而非匹配引擎。這也是中銀匹配時間窗口為 -3~+4 天(比標準 -3~+2 寬 2 天)的原因。
工銀亞洲 ICBC — 銀企 API 輪詢
| 維度 | 說明 |
|---|---|
| 協議 | 銀企直連 REST API,RSA 驗簽 |
| 到達時效 | 分鐘級 |
| 採集服務 | icbc_be_relay(Python) |
| TransType | 202(ICBCASIA) |
工銀已知系統限制
工銀是入金量第二大來源(約 12.3%),但系統限制在所有銀行中最多。PM 和運營需特別注意以下已知問題:
| 限制 | 影響 | 應對措施 |
|---|---|---|
| 無唯一交易 ID | 流水去重只能依賴組合字段(金額+日期+卡號+備註),重複風險高於其他銀行 | 匹配引擎增加額外去重校驗邏輯 |
| T-1 遲到流水 | 部分流水在交易日次日才到達系統(非即時) | 匹配時間窗口額外放寬 1 天 |
| 退款/沖正餘額校驗缺失 | 沖正前無法自動校驗證券帳戶餘額是否充足 | 運營沖正前必須手動查詢餘額 |
| 流水格式不穩定 | 工銀偶爾調整流水報文格式,無事先通知 | 流水解析器保持兼容性冗餘 |
涉及工銀的變更需額外回歸
因為上述限制,任何涉及匹配規則或流水解析的變更,都需要額外針對工銀做回歸測試——特別是去重邏輯和 T-1 流水場景。排障時如遇工銀相關問題 → 入金排障 § 工銀流水重複
其他 API 輪詢
| 銀行 | 採集服務 | TransType | 到達時效 |
|---|---|---|---|
| 星展 DBS | dbs_service | 208 | 分鐘級 |
| 建銀亞洲 CCB | API 輪詢 | 206 | 分鐘級 |
| 眾安 ZA | API 輪詢 | 221 | 分鐘級 |
| 天星 Airstar | API 回調 | 304 | 秒級 |
手工上傳類
EWB — CSV + BAI2 文件
| 維度 | 說明 |
|---|---|
| 協議 | 運營手工上傳 CSV / BAI2 文件到 OA 後台 |
| 到達時效 | 取決於運營操作,通常每日 1-2 次 |
| TransType | 217(EWB_SUBACC) |
CSV 提供基礎交易資訊,BAI2 補充付款人姓名等匹配所需字段。上傳後系統自動解析、去重、寫入 flows 表。
匯總對比表
| 銀行 | 採集方式 | 協議 | 到達時效 |
|---|---|---|---|
| 匯豐 HSBC | 即時推送 | MT910 via SFTP | 秒級 |
| 渣打 SCB | 即時推送 | Webhook + API | 秒級 |
| 廣發 CGB | 即時推送 | FPS REST API | 秒級 |
| 招行/民生 | 即時推送 | Socket 雙向鏈路 | 秒級 |
| 天星 Airstar | API 回調 | REST API | 秒級 |
| 工銀 ICBC | 定時拉取 | 銀企 API | 分鐘級 |
| 星展 DBS | 定時拉取 | API | 分鐘級 |
| 建銀 CCB | 定時拉取 | API | 分鐘級 |
| 眾安 ZA | 定時拉取 | API | 分鐘級 |
| 中銀 BOCHK | 批量拉取 | B2E XML-RPC | 小時級 |
| 恒生 | 特殊介面 | — | 分鐘~小時 |
| EWB | 手工上傳 | CSV + BAI2 | 取決於運營 |
銀行到賬時效視覺化
從用戶轉賬到流水進入系統,各銀行的等待體驗差異極大:
| 時效等級 | 銀行 | 典型等待 | 用戶感知 |
|---|---|---|---|
| 秒級 | 匯豐(MT910)、渣打(Webhook)、廣發(FPS API)、天星(API) | <1 分鐘 | "剛轉完就看到了" |
| 分鐘級 | 工銀(銀企API)、星展(API)、建銀(API)、眾安(API) | 5~30 分鐘 | "過一會就到了" |
| 小時級 | 中銀(B2E 每日3次) | 2~6 小時 | "上午轉的,下午才到" |
| 不確定 | 恒生(特殊介面)、EWB(手工上傳) | 數小時~次日 | "要等運營處理" |
PM 關注:用戶投訴"錢沒到"時,先看是哪家銀行——如果是中銀,2~6 小時的等待是正常的,不是系統故障。
如果需求變更:流水採集相關
| 變更 | 改動位置 | 說明 |
|---|---|---|
| 新增銀行流水採集 | 新建 Go/Python 服務 + crontab 配置 | 參考 入金變更指南 § 場景七 |
| 修改 B2E 拉取頻率(中銀) | bochk_flow_go/conf/conf.toml | 調整 cron 表達式 |
| 修改匹配頻率 | deposit/doc/crontab.sh → 對應 match:* | 參考 入金變更指南 § 場景六 |
| 更換 SFTP/API 憑證 | 對應銀行採集服務的配置文件 | 通常需運維部署 |
| 修改 Flow Converter 頻率(中銀) | bochk_flow_go cron 配置 | 當前每 2 小時 |
流水採集異常排查
當流水不進來或處理異常時,按以下路徑排查。
快速診斷:流水為什麼沒到
分步 Runbook:收到"某銀行流水不進來"告警
第 1 分鐘 — 確認影響範圍
- 查看告警內容:哪家銀行?堆積了多少條待處理流水?
- 在 OA 流水列表篩選該銀行,查看最近一條流水的到達時間
- 如果最近流水是幾分鐘前 → 可能是虛警(流水正常進來,只是匹配延遲)
- 如果最近流水是幾小時前 → 確認是採集中斷
第 2~5 分鐘 — 定位採集服務 5. 檢查對應的採集服務進程是否存活:
- 匯豐:
hsbc_bank_flow_service(Python) - 渣打:
scb_service(Go) - 廣發:
cgb_fps_service(Go) - 中銀:
bochk_flow_go(Go) - 工銀:
icbc_be_relay(Python)
- 查看服務最近的日誌 → 是否有連接超時、鑑權失敗、解析異常
第 5~10 分鐘 — 嘗試恢復 7. 如果服務掛了 → 重啟服務,觀察 1~2 個週期是否有新流水進入 8. 如果鑑權/證書過期 → 需要更新憑證(聯繫銀行關係團隊獲取新憑證) 9. 如果銀行側沒推送數據 → 非系統故障,記錄後聯繫銀行關係團隊
第 10~15 分鐘 — 補償處理 10. 服務恢復後,檢查中斷期間是否有遺漏的流水(對比銀行對賬單) 11. 如果有遺漏 → 中銀可手動觸發補拉;其他銀行需聯繫銀行重推
超過 15 分鐘未恢復 → 升級到技術運維值班人員
分步 Runbook:匹配 Cron 任務未執行
第 1 分鐘 — 確認問題
- 檢查對應的
match:{bank}Cron 是否在運行 - 查看最近一次匹配任務的執行時間和結果
第 2~5 分鐘 — 排查原因 3. Cron 進程是否存活?如果 Cron 調度器本身掛了 → 所有銀行的匹配都會停 4. 檢查是否有某個匹配任務執行時間過長(超過 3 分鐘),導致下一輪被跳過 5. 檢查 DB 連接是否正常 — 匹配任務需要同時訪問 flows 和 applys 表
第 5~10 分鐘 — 恢復 6. 重啟 Cron 調度器 7. 手動觸發一次匹配任務,確認執行成功 8. 觀察下一個週期是否自動恢復
超過 10 分鐘未恢復 → 升級到技術運維
流水表結構與分片
分表策略
流水表按 銀行類型 + 月份 分片:
flows_{trans_type}_{YYYYMM}例如:flows_218_202604 = 2026 年 4 月匯豐 MT910 流水。
為什麼這樣分:
- 按
trans_type分:不同銀行的流水字段差異大,分開便於各銀行獨立優化索引 - 按月分:流水量大,按月歸檔,歷史月份可逐步凍結
配置位置
分表邏輯:deposit/src/app/Business/Flow.php:80 表不存在時自動創建:CREATE_WHEN_TABLE_NOT_FOUND 配置
流水狀態生命週期
| 狀態碼 | 含義 | 說明 |
|---|---|---|
| 0 | 待處理 | 流水已入庫,等待匹配引擎處理 |
| 1 | 已處理 | 已成功匹配並創建入金任務 |
| 2 | 標記失敗 | 需要人工介入解決的問題流水 |
| 3 | 標記鎖定 | 運營鎖定,暫不參與匹配(如等待用戶補充資訊) |
| 4 | 標記在途 | 已確認轉賬但流水資訊不完整,等待補全 |
| 9 | 軟刪除 | 標記刪除(非物理刪除) |
流水處置結果
當流水被處理時,系統記錄處置方式:
| 結果碼 | 含義 | 觸發場景 |
|---|---|---|
| 0 | 系統匹配 | 匹配引擎自動匹配成功 |
| 1 | 人工添加 | 運營在 OA 後台手動關聯 |
| 2 | 發起入金 | 運營直接從流水發起入金 |
| 3 | 退款 | 流水對應的資金需要退回(詳見 退款與沖正) |
| 4 | 其他 | 非入金類流水(如利息、手續費) |
| 5 | 已緊急處理 | 通過異常入金流程處理 |
| 6 | 自動入金 | 匹配引擎自動匹配 + 自動入賬 |
配置位置
狀態碼:deposit/src/app/Business/BankFlow.php:59-64 結果碼:deposit/src/app/Business/BankFlow.php:80-87
採集定時任務
匹配相關 Cron
匹配引擎每 3 分鐘掃描各銀行的待處理流水:
| 任務名 | 頻率 | 銀行 | 說明 |
|---|---|---|---|
match:ccbasia | 每 3 分鐘 | 建銀亞洲 | CCB 流水匹配 |
match:ewb | 每 3 分鐘 | EWB | East West Bank 匹配 |
match:boc | 每 3 分鐘 | 中銀 | BOCHK B2E 匹配 |
match:hangseng | 每 3 分鐘 | 恒生 | 恒生直連流水匹配 |
match:hsbc | 每 3 分鐘 | 匯豐 | HSBC MT910 匹配 |
match:main icbc-new | 每 3 分鐘 | 工銀 | ICBC 新版匹配 |
match:main za-sub-account | 每 3 分鐘 | 眾安 | ZA 子賬戶匹配 |
監控相關 Cron
| 任務名 | 頻率 | 說明 |
|---|---|---|
monitor:flow-monitor | 每 30 分鐘(07:00~23:00) | 檢測流水堆積——待處理流水超閾值告警 |
abnormal-deposit:search | 每 30 分鐘 | 掃描無匹配的孤立流水 |
abnormal-deposit:update-status | 每 3 分鐘 | 更新異常入金狀態 |
對賬相關 Cron
| 任務名 | 頻率 | 說明 |
|---|---|---|
bank_reconciliation:generate | 16:15 每日 | 生成當日對賬報告(CNH/HKD/USD) |
bank_reconciliation:generate --date=yesterday USD | 09:05 每日 | 生成昨日 USD 對賬(因美元 T+1 結算) |
crmbos_reconciliation:generate | 每小時整點 | CRM-BOS 系統間對賬 |
配置位置
所有 Cron 定義:deposit/doc/crontab.sh
銀行流水類型碼
不同銀行的流水攜帶不同的 type 字段,標識轉賬方式。匹配引擎會根據 type 選擇不同的匹配規則:
中銀 BOCHK
| Type | Remarks 關鍵詞 | 含義 | 匹配規則 |
|---|---|---|---|
| Transfer | FPS | FPS 轉賬 | 即時匹配窗口 |
| Transfer | E-BANKING TRANSFER | 網銀轉賬 | 標準匹配窗口 |
| Transfer | CHATS | CHATS 清算轉賬 | 標準匹配窗口 |
| Transfer | REMIT IN | 匯入匯款 | 跨區容差 |
| Transfer | CBS TRANSFER | CBS 系統轉賬 | 標準匹配窗口 |
| Clearing Cheque | — | 支票清算 | 標準匹配窗口 |
恒生 Hang Seng
| Type 代碼 | 含義 | 匹配規則 |
|---|---|---|
| ATM | ATM 存款/轉賬 | 標準匹配 |
| GT | 櫃台轉賬 | 標準匹配 |
| WY | 網銀轉賬 | 標準匹配 |
| ZP | 支票 | 標準匹配 |
| BP | Bill Payment 繳費 | 標準匹配 |
工銀 ICBC
| Type 關鍵詞 | 含義 |
|---|---|
| 匯款存入 | 匯款轉入 |
| FPS 轉賬 | FPS 轉賬 |
| 網上轉賬存款 | 網銀轉入 |
| 櫃員機跨行轉賬存款 | ATM 跨行轉入 |
| 支票 | 支票存入 |
與匹配引擎的銜接
流水一旦寫入 flows 表且 status = 0(PROCESSING),就會在下一個 3 分鐘匹配週期被掃描。
匹配引擎的詳細邏輯 → 匹配與自動入賬
常見誤解
| 誤解 | 事實 |
|---|---|
| "流水到了就會馬上入賬" | 流水到了只是第一步。還需要等匹配引擎下一個 3 分鐘週期掃描,匹配成功後才能入賬。最快也要等一個匹配週期 |
| "中銀入金慢是匹配引擎的問題" | 不是。中銀慢的原因是 B2E 每日只拉取 3 次 + 2 小時轉換時間。流水都沒進系統,匹配引擎無從匹配 |
| "EWB 流水是自動採集的" | 不是。EWB 需要運營手工上傳 CSV/BAI2 文件。如果運營沒上傳,系統裡就沒有流水 |
| "BST 和 eDDA 也需要流水採集" | 不需要。BST 和 eDDA 是系統主動發起的扣款,系統自己知道結果。本頁的流水採集僅針對 Push 模式 |
| "所有銀行的流水格式是一樣的" | 完全不一樣。每家銀行的字段、編碼、時間格式都不同,所以每家銀行都有獨立的採集服務和解析邏輯 |
讀完之後
| 我想... | 去看 |
|---|---|
| 了解流水到達後的匹配邏輯 | 匹配與自動入賬 |
| 排查"流水沒到系統"的問題 | 入金排障 |
| 查 TransType 和流水狀態碼 | 入金規則速查 |
| 看某家銀行的詳細對接規則 | 銀行能力矩陣 |
| 了解採集服務在架構中的位置 | 系統架構與數據流 |