匹配與自動入賬
本頁說明
講什麼:當用戶通過 FPS/網銀等方式轉賬後,系統如何識別"這筆錢是誰的",以及什麼情況下能全自動入賬 適合誰:需要理解入金核心機制的產品經理 前置閱讀:入金方式總覽預計閱讀:7 分鐘 負責人:入金產品經理
核心要點:匹配引擎通過五維比對(金額+幣種+姓名+日期+卡號)將銀行流水與用戶申請配對,每 3 分鐘自動執行一輪。兩級容差機制保障既能自動化又不誤匹配,約 95% 的入金可自動完成。
快速跳轉 — 你可能想做的事:
為什麼需要匹配引擎
想像這個場景:一筆 HKD 50,000 的 FPS 轉賬到達公司在渣打的帳戶。此刻系統只知道"有人轉了 5 萬塊進來",但不知道是哪個用戶。與此同時,可能有幾十個用戶的入金申請在等待——其中有人申請了 50,000,有人申請了 49,980(銀行扣了手續費),甚至可能有兩個人同時申請了 50,000。
匹配引擎的工作就是從這些候選申請中找出正確的那一個,把銀行流水(Flow)和入金申請(Apply)配對。
什麼時候不需要匹配?
eDDA 和 BST 不需要匹配引擎,因為這些方式是系統主動發起的扣款——系統在發扣款指令時就帶了"這是哪個用戶、哪筆申請"的資訊。錢到了天然就知道歸屬。匹配引擎在代碼中顯式跳過 eDDA 和 BST 的申請。
匹配引擎如何運轉
每家銀行有一個獨立的匹配任務,每 3 分鐘執行一次。每次運行時:
為什麼是 3 分鐘而不是即時?
匹配引擎採用資料庫輪詢模式:每次運行時全表掃描 flows 和 applys 表中所有 status=0 的記錄,逐條做五維比對。這種批處理模式在當前日均流水量下是效率最優的選擇——一次掃描處理所有待匹配記錄,比逐條即時觸發減少了大量資料庫連接和事務開銷。3 分鐘是"用戶感知時效"和"資料庫負載"的經驗平衡點。如果業務量顯著增長,可以考慮提頻或改為事件驅動架構,但需要評估 DB 負載。想調整頻率 → 入金變更指南 § 調整匹配頻率
- 從 Flow 表取所有待處理的銀行流水
- 從 Apply 表取所有待匹配的入金申請
- 逐條流水與候選申請做五維比對
- 根據匹配程度輸出三種結果
五個匹配維度
1. 幣種:必須完全一致
HKD 的流水只能匹配 HKD 的申請,不做跨幣種匹配。這是最基礎的過濾條件。
2. 金額:允許合理差額
銀行轉賬可能產生手續費,導致實際到賬低於申請金額。匹配引擎允許一定容差:
- 本地轉賬:HKD 允許差 20 元以內,USD 允許差 3 元以內
- 跨行/跨境:容差更大(HKD 最多 420 元),因為中轉行扣費不可控
- 不同銀行有不同標準:匯豐的自動入賬容差(HKD 65)比中銀(HKD 20)更寬鬆,因為匯豐流水中的手續費扣除模式不同
完整的各銀行容差規則 → 入金規則速查 § 匹配容差
為什麼是這些數字?
每一檔容差背後都有具體的業務原因:
- HKD ±20:本地銀行同行轉賬手續費上限約 HKD 15~20。這個容差覆蓋絕大多數 FPS 和本地轉賬場景——用戶申請 50,000 但到賬 49,982,差額就是銀行扣的本地手續費。
- HKD ±420:跨境/跨行轉賬(如 CHATS、電匯)會經過中轉行,中轉行扣費金額不可控且事先未知。HKD 420 是基於歷史數據的經驗值,能覆蓋絕大部分跨境中轉扣費場景。
- 匯豐自動入賬 -65:匯豐的流水比較特殊——手續費直接從到賬金額中扣除(而非像其他銀行一樣單獨列示)。也就是說,用戶轉 50,000 但匯豐流水顯示的到賬金額可能是 49,935。HKD 65 這個閾值覆蓋了匯豐大部分常規手續費場景。
- USD ±3 / ±60:與 HKD 容差按匯率等比例折算。USD 3 ≈ HKD 20,USD 60 ≈ HKD 420。
容差配置代碼位置
金額容差規則定義在以下文件中:
deposit/src/app/Business/Match/MatchRule.php— 通用匹配規則基類deposit/src/app/Business/Match/NewMatchRule.php— 新版匹配規則- 各銀行的 Match 類(如
BocMatch.php、HsbcMatch.php)中會覆寫或細化通用容差
3. 姓名:精確或模糊
系統將流水中的匯款人姓名與申請人的註冊姓名比對。支持兩個級別:
精確匹配:
- 中文名:字符級完全一致("陳大文" === "陳大文")
- 英文名:統一轉大寫後完全一致("Chan Tai Man" → "CHAN TAI MAN")
模糊匹配:
- 姓名順序顛倒處理:銀行流水中姓在前名在後(CHAN TAI MAN),而用戶註冊時可能填的是名在前姓在後(TAI MAN CHAN)。系統按空格分詞後排序再比較,
{CHAN, MAN, TAI}==={CHAN, MAN, TAI},視為匹配。 - 特殊字符歸一化:去除逗號(CHAN, TAI MAN → CHAN TAI MAN)、連字符(CHAN TAI-MAN → CHAN TAI MAN)、多餘空格,統一後再比較。
- 銀行編碼前綴去除:部分銀行在匯款人姓名前加 3 位行號前綴(如 "004CHAN TAI MAN"),系統自動識別並去除這類前綴。
為什麼不做更激進的模糊匹配? 例如只比較姓氏首字母、或用拼音匹配。原因是:寧可讓一筆入金降級為輔助匹配由運營人工確認,也不冒自動入錯賬的風險。入錯賬意味著 A 的錢進了 B 的證券帳戶——這比"慢一點"嚴重得多。當前的模糊策略已經覆蓋了 90%+ 的格式差異場景,剩餘少量邊緣 case 交給人工是最安全的選擇。
姓名匹配代碼位置
deposit/src/app/Business/Match/MatchRule.php:252-323— 姓名比對核心邏輯(精確 + 模糊)deposit/src/app/Business/Match/NewMatchRule.php:124-139— 新版姓名歸一化規則
4. 日期:在合理時間窗口內
申請日期和流水日期必須在一個合理範圍內。窗口大小取決於流水類型:
- 即時流水(FPS、MT910 等):流水到達時間附近,窗口較窄
- 批量流水(中銀 B2E 等):流水日期 ±3 天左右,窗口較寬
各時間窗口的設計依據:
- 標準窗口 -3 天 / +2 天:申請可能比流水早 3 天(用戶先在 App 提交申請,隔了兩三天才去銀行轉賬),也可能比流水晚 2 天(銀行流水先到,用戶後補提交申請)。這個窗口覆蓋了絕大部分正常操作時序。
- 中銀 B2E 用 +4 天(而非 +2 天):中銀的 B2E 流水每日僅拉取 3 次,加上 2 小時左右的格式轉換時間,流水進入系統可能比實際銀行交易晚 1~2 天。因此窗口向後額外放寬 2 天。
- FPS 用 -1 小時:FPS 是秒級結算。但實際場景中,用戶可能先在銀行 App 完成 FPS 轉賬,幾秒到幾十秒後才在 moomoo App 提交入金申請——此時流水到達時間會略早於申請時間。-1 小時的窗口覆蓋這種"先轉賬後申請"的常見操作順序。
- 即時流水使用到達時間(而非交易日期):MT910 和 BST 精確到秒,系統可以用更精準的時間窗口進行匹配,而不是像批量流水一樣只能按"天"粒度比較。這顯著降低了同金額同用戶多筆入金的誤匹配風險。
完整的時間窗口配置 → 入金規則速查 § 匹配時間窗口
時間窗口配置代碼位置
deposit/src/app/Business/Match/MatchRule.php:112-223— 各銀行、各流水類型的時間窗口定義
5. 卡號:精確匹配
流水中的匯款賬號與申請中的銀行卡號做精確比對(經過清洗:去除幣種標識位、排除信用卡號等)。
真實匹配案例
以下 5 個案例展示匹配引擎在不同場景下的行為,幫助理解匹配邏輯在實際中如何運作。
案例一:標準 FPS 完全匹配 ✅
| 維度 | 申請(Apply) | 流水(Flow) | 比對結果 |
|---|---|---|---|
| 幣種 | HKD | HKD | ✅ 一致 |
| 金額 | 50,000 | 50,000 | ✅ 差額=0,在容差內 |
| 姓名 | CHAN TAI MAN | CHAN TAI MAN | ✅ 精確匹配 |
| 日期 | 04-28 10:00 | 04-28 10:02 | ✅ 在窗口內(差 2 分鐘) |
| 卡號 | 012-***-8901 | 012-***-8901 | ✅ 一致 |
結果:完全匹配 → 自動入賬判定 → 通過 → 全自動入賬
案例二:姓名順序顛倒 → 模糊匹配成功 ⚠️
| 維度 | 申請(Apply) | 流水(Flow) | 比對結果 |
|---|---|---|---|
| 幣種 | HKD | HKD | ✅ 一致 |
| 金額 | 30,000 | 30,000 | ✅ 差額=0 |
| 姓名 | CHAN TAI MAN | TAI MAN CHAN | ⚠️ 精確不匹配,模糊匹配 ✅ |
| 日期 | 04-27 | 04-28 | ✅ 在 -3~+2 窗口內 |
| 卡號 | 012-***-5678 | 012-***-5678 | ✅ 一致 |
結果:姓名只能模糊匹配 → 輔助匹配,等運營確認。 解釋:銀行流水中"TAI MAN CHAN"和註冊名"CHAN TAI MAN",系統按空格分詞後排序比較:{CHAN, MAN, TAI} === {CHAN, MAN, TAI},判定為模糊匹配。
案例三:金額差異在容差邊界 ⚠️
| 維度 | 申請(Apply) | 流水(Flow) | 比對結果 |
|---|---|---|---|
| 幣種 | HKD | HKD | ✅ 一致 |
| 金額 | 100,000 | 99,980 | ✅ 差額=20,恰好等於容差 |
| 姓名 | WONG SIU MING | WONG SIU MING | ✅ 精確匹配 |
| 日期 | 04-28 | 04-28 | ✅ 在窗口內 |
| 卡號 | 024-***-3456 | 024-***-3456 | ✅ 一致 |
結果:差額恰好 = HKD 20(閉區間,等於容差仍算匹配)→ 完全匹配 → 自動入賬。 邊界說明:如果流水是 99,979(差額 21),就會降級為輔助匹配。
案例四:跨境匯入 + 大額手續費 ⚠️
| 維度 | 申請(Apply) | 流水(Flow) | 比對結果 |
|---|---|---|---|
| 幣種 | USD | USD | ✅ 一致 |
| 金額 | 50,000 | 49,955 | ⚠️ 差額=45,本地容差(3)不夠,跨區容差(60)夠 |
| 姓名 | LI WEI | LI WEI | ✅ 精確匹配 |
| 日期 | 04-25 | 04-28 | ✅ 在窗口內(差 3 天) |
| 卡號 | 無匹配數據 | 無 | ➖ 跳過 |
結果:金額走跨區容差(USD 60 內)→ 完全匹配 → 自動入賬判定。 PM 關注:USD 45 的差額來自中轉行扣費。Apply.real_amount 會記錄 49,955(實際到賬),用戶看到"入金成功 USD 49,955"。
案例五:同金額多用戶 → 系統拒絕自動入賬 ❌
| 維度 | 申請 A | 申請 B | 流水 |
|---|---|---|---|
| 用戶 | UID 1001 | UID 2002 | — |
| 幣種 | HKD | HKD | HKD |
| 金額 | 50,000 | 50,000 | 50,000 |
| 姓名 | CHAN TAI MAN | CHAN TAI MAN | CHAN TAI MAN |
結果:一條流水匹配到兩個不同用戶的申請 → 違反"一流水一用戶"規則 → 降級輔助匹配,運營人工判斷歸屬。 現實原因:兩個同名用戶碰巧同時申請了相同金額。雖然罕見,但系統必須防護這種情況。
三種匹配結果
| 結果 | 含義 | 後續 |
|---|---|---|
| 完全匹配 | 多個維度都吻合,置信度高 | → 進入自動入賬判定 |
| 輔助匹配 | 部分維度吻合,需要人工確認 | → 寫入匹配表,運營在 OA 審核後手動入賬 |
| 不匹配 | 無法配對 | → 流水等待下一輪匹配,或最終轉為異常流水 |
不同銀行達到"完全匹配"的標準不同。有的銀行要求幣種+金額+姓名+卡號全部吻合,有的只要幣種+金額+姓名即可。這些差異是因為各銀行流水中攜帶的資訊豐富程度不同——資訊越豐富,匹配維度越多,置信度越高。
輔助匹配不是失敗
輔助匹配意味著系統找到了"可能的匹配對"但不夠確定。運營人員審核後確認匹配,入金就會正常完成。大部分輔助匹配最終都是正確的——只是系統不敢完全自動處理。
銀行專屬匹配規則
每家銀行的流水格式和攜帶資訊差異很大:有的銀行流水包含完整的匯款人姓名、卡號、交易備註,有的只有金額和日期。因此,匹配引擎為每家銀行實現了獨立的 Matcher 類,在通用五維規則的基礎上疊加銀行專屬邏輯。
各銀行自動入賬能力一覽
| 銀行 | 能否自動入賬 | 自動入賬的流水類型 | 必須通過的維度 | 不能自動入賬的類型 |
|---|---|---|---|---|
| 中銀 BOCHK | 是(部分) | FPS、網銀、CHATS、匯入 | 幣種+金額+姓名精確+卡號+日期+限額 | 支票、CBS 內部轉賬、利息、ATM |
| 匯豐 HSBC | 是 | 所有(eDDA 除外) | 幣種+姓名精確+金額(HKD≤65/USD≤14)+卡號 | — |
| 恒生 HASE | 是(僅網銀) | WY(網銀轉入) | 幣種+金額精確+姓名精確+通知類型=普通 | ATM、GT、ZP、BP 均為輔助匹配 |
| 工銀 ICBC | 是(部分) | 匯款存入、FPS、網銀 | 幣種+金額+卡號+姓名(EN+CN) | 子賬戶路徑、ATM、支票 |
| 星展 DBS | 是 | 所有 | 幣種+姓名精確+金額(HKD≤350/USD≤50) | — |
| EWB 子賬戶 | 是 | 所有 | 幣種+姓名精確+金額(≤40) | — |
| 交行 BANKCOMM | 否 | — | — | 全部(僅輔助匹配) |
| 建銀 CCBASIA | 否 | — | — | 全部(僅輔助匹配) |
| 東亞 EWB | 否 | — | — | 全部(寬鬆容差輔助匹配) |
| 眾安子賬戶 | 否 | — | — | 全部(僅輔助匹配) |
| 新加坡工銀子賬戶 | 否 | — | — | 全部(僅輔助匹配) |
各銀行匹配規則詳解
中銀 BOCHK — 按 flow type 分組匹配
中銀流水資訊最豐富(姓名、卡號、備註、flow type 都有),匹配維度最多、自動匹配率最高。匹配引擎先根據 flow type 和 remarks 字段將流水分類,再對每類應用不同的規則集:
| Flow Type | 自動入賬條件 | 輔助匹配條件 | 金額容差 |
|---|---|---|---|
| FPS 轉賬 | 幣種+金額精確+姓名精確+卡號+日期+限額 | 幣種+姓名模糊+日期 | 自動: 0~20(HKD)/0~3(USD) |
| 網銀轉賬 | 同 FPS | 同 FPS | 同 FPS |
| CHATS 跨行 | 幣種+本地容差金額+姓名精確+卡號+日期+限額 | 幣種+姓名模糊+日期 | 自動: 0~20(HKD) |
| 境外匯入 REMIT IN | 幣種+跨區容差金額+姓名精確+卡號+日期+限額 | 幣種+姓名模糊+日期 | 自動: 0~420(HKD)/0~60(USD) |
| CBS 內部轉賬 | mustFalse(不能自動) | 幣種+本地容差金額+日期 | 輔助: 0~20(HKD) |
| 支票/利息/ATM | mustFalse(不能自動) | 幣種+本地容差金額+日期 | 輔助: 0~20(HKD) |
中銀 FPS 備註豁免
中銀流水中如果 remarks 包含 FPS 相關內容,會豁免區域檢查(bocFlowRemarksExemptFromRegionCheck)。這是因為 FPS 本身就是香港本地快速支付,不需要額外驗證匯款來源地區。
中銀卡號清洗規則:中銀流水中的銀行卡號可能帶有 / 前綴(如 /012345678901),匹配引擎在比對前會執行 ltrim($card_number, '/') 去除前綴。如果你在排查中銀匹配失敗時發現卡號"看起來一樣但不匹配",先檢查是否有 / 前綴問題。
B 系列金額規則詳解:中銀的金額匹配不是統一的容差,而是按流水來源細分為 4 個規則層級:
| 規則 | 適用流水類型 | 金額容差 | 說明 |
|---|---|---|---|
| B1 | 本地同行轉賬(FPS、同行網銀) | 精確匹配(差額=0) | 同行無手續費,金額應完全一致 |
| B2 | 跨境/跨行(CHATS、境外匯入) | HKD 0~420 / USD 0~60 | 中轉行扣費不可控,容差最寬 |
| B3 | 線上開戶首筆 | 精確匹配 + 最低限額校驗 | HKD ≥10,000 / USD ≥1,500 / CNY ≥10,000 |
| B4 | 本地雜項(ATM、繳費賬單等) | HKD 0~20 / USD 0~32 | 覆蓋小額手續費 |
B3 規則是特殊的——線上開戶用戶的首筆入金不僅要求金額精確匹配,還要求達到最低限額。不滿足最低限額的首筆入金會被攔截,降級為輔助匹配等運營確認。
匯豐 HSBC — 雙層容差 + 卡號校驗
匯豐 MT910 流水攜帶完整的匯款人資訊,匹配邏輯相對直接,但有雙層容差:
| 匹配級別 | 條件 | 金額容差 |
|---|---|---|
| 自動入賬 | 幣種+姓名精確+金額在自動容差內+卡號匹配 | HKD: 0~65 / USD: 0~14 |
| 輔助匹配 | 幣種+姓名模糊+金額在輔助容差內 | HKD: 0~420 / USD: 0~60 |
關鍵細節:
- eDDA 方式的申請被顯式排除(
deposit_method == HSBC_EDDA直接跳過) - 卡號校驗會排除 14 位的 BOC 智能賬戶號
- 匯豐的自動入賬容差(HKD 65)比中銀(HKD 20)寬鬆,因為匯豐跨行轉入時銀行側扣費模式不同
恒生 HASE — 按 flow type 六路分發
恒生流水格式較簡潔,匹配引擎按 flow type 代碼走六條不同的路徑:
| Flow Type | 匹配結果 | 匹配條件 | 說明 |
|---|---|---|---|
| ATM | 僅輔助 | 金額精確+創建批次日期 | ATM 存現不帶匯款人資訊 |
| GT(櫃台) | 僅輔助 | 金額精確+創建批次日期 | 櫃台交易資訊有限 |
| WY(網銀) | 可自動 | 通知類型=普通 + 姓名精確 + 金額精確 → 自動入賬 | 唯一可自動入賬的類型 |
| ZP(轉賬/支票) | 僅輔助 | 金額精確+日期+姓名模糊(HKD)+UID(可選) | — |
| BP(繳費) | 僅輔助 | 金額精確+BP 編號匹配 | 額外校驗繳費 ID |
| 預設 | 僅輔助 | 金額模糊+日期 | 兜底邏輯 |
關鍵細節:
- eDDA 方式的申請被顯式排除(
deposit_method == EDDA直接跳過) - WY(網銀)是恒生唯一可自動入賬的類型,且要求
notice_type = NORMAL - 日期維度比較特殊:ATM/GT 使用批次創建時間而非標準日期窗口,因為恒生流水按批次到達
工銀 ICBC — 雙路徑分發
工銀的匹配邏輯最複雜,分為子賬戶路徑和普通路徑兩條完全不同的鏈路:
| 路徑 | 觸發條件 | 自動入賬? | 金額容差 | 特殊要求 |
|---|---|---|---|---|
| 子賬戶 | 中文名="富途證劵國際(香港)有限公司" | 否(僅輔助) | HKD: 0~500 / USD: 0~70 | 子賬戶歷史驗證 |
| 普通-自動 | 通知類型=普通/大陸預開戶 | 是 | FPS: 精確(0) / 其他: 0~420/60 | 卡號+EN/CN姓名雙重匹配 |
| 普通-線上用戶 | 通知類型=綁卡 | 是 | 同上 | 最低金額: HKD≥10000, USD≥1500 |
| 兜底輔助 | 其他 | 否 | 0~420/60 或精確 | 按流水類型分支 |
關鍵細節:
- 普通路徑自動入賬要求 EN 和 CN 姓名都匹配——雙重校驗
- FPS 要求金額精確匹配(容差=0),其他方式允許 420/60 的跨區容差
- 只有
匯款存入、FPS 轉賬、網上轉賬存款三種流水類型可以觸發自動入賬 - 卡號校驗時會自動去除
00前綴(工銀卡號格式特殊)
其他銀行
| 銀行 | 模式 | 關鍵特徵 |
|---|---|---|
| 星展 DBS | 子賬戶+姓名 | 子賬戶驗證必須通過;姓名精確+金額(HKD≤350/USD≤50)可自動入賬 |
| EWB 子賬戶 | 雙層容差 | 自動入賬容差僅 40;輔助匹配容差 100;子賬戶必須驗證 |
| 交行 BANKCOMM | 僅輔助 | 需子賬戶歷史驗證;容差 HKD 300/USD 45;日期窗口更寬(-7~+4天) |
| 建銀 CCBASIA | 僅輔助 | 姓名精確匹配+容差 HKD 300/USD 45;不支持自動入賬 |
| 東亞 EWB | 僅輔助 | 常規轉賬容差 HKD 420/USD 60;"Other Deposit"僅金額精確匹配 |
| 眾安子賬戶 | 僅輔助 | 姓名精確+金額(HKD≤350/USD≤50);金額方向特殊(申請-流水) |
| 新加坡工銀子賬戶 | 僅輔助 | 僅驗證幣種+子賬戶+金額(HKD≤500/USD≤70),不驗證姓名 |
銀行 flow type 分組規則
中銀 BOCHK flow types(按 type + remarks 路由):
Transfer+ remarks 含FPS— FPS 轉賬Transfer+ remarks 含E-BANKING— 網銀轉賬Transfer+ remarks 含CHATS— CHATS 跨行轉賬Transfer+ remarks 含REMIT IN— 境外匯入Transfer+ remarks 含CBS TRANSFER— CBS 內部轉賬(不能自動入賬)Clearing Cheque— 支票清算(不能自動入賬)Interest/ATM Transfer— 利息/ATM(不能自動入賬)
恒生 Hang Seng flow types(按 type 代碼直接匹配):
ATM— ATM 現金存入(僅輔助匹配)GT— 櫃台交易(僅輔助匹配)WY— 網銀轉入(唯一可自動入賬)ZP— 轉賬/支票(僅輔助匹配)BP— 繳費/銀行匯入(僅輔助匹配,額外校驗 BP ID)
工銀 ICBC flow types(按 type 中文標籤匹配):
匯款存入— 可自動入賬FPS 轉賬— 可自動入賬(金額精確匹配)網上轉賬存款— 可自動入賬手機轉賬存款/網上轉賬存款— 可自動入賬(eBanking 路徑,需 CN 姓名)存款機/現金/他行票— 僅輔助匹配跨行轉賬轉入— 僅輔助匹配櫃員機跨行轉賬存款— ATM 特殊規則(容差僅 10)
詳見 銀行流水採集 中各銀行的 flow type 編碼說明。
如果需求變更:修改某銀行的匹配規則
代碼位置:deposit/src/app/Business/Match/{BankName}Match.php
每家銀行有獨立的 Match 類,繼承自 MatchBase。核心方法是 match($flow, $apply) 和 getRuleConfig()。
常見變更場景:
- 放寬某銀行的自動入賬容差 → 修改對應 Match 類中的金額比較參數。例如匯豐 HKD 從 65 放寬到 100:修改
HsbcMatch.php中amountSimilarForAuto的調用參數 - 讓某銀行從"僅輔助"升級為"可自動入賬" → 在該銀行的 Match 類中添加返回
RESULT_DEPOSIT的邏輯分支(參考 DBS 或 HSBC 的實現) - 讓某個 flow type 不再自動入賬 → 在
getRuleConfig()的對應路由中將deposit_rule改為mustFalse - 新增一家銀行的匹配規則 → 創建新的
{BankName}Match.php類,註冊到匹配調度器中
關鍵約束:
- 14 個 Match 類共用
MatchRule.php和NewMatchRule.php中的基礎規則函數。如果修改基礎規則(如isSameAmount),會影響所有銀行 - 每家銀行的匹配任務獨立運行(每 3 分鐘各跑一輪),互不干擾
如果需求變更:調整匹配容差
代碼位置:
- 標準容差:
deposit/src/app/Business/Match/MatchRule.php(約 30-110 行) - 新版路由引擎:
deposit/src/app/Business/Match/NewMatchRule.php
容差函數對照表(修改這些函數影響所有使用它的銀行):
| 函數名 | 含義 | 當前值 | 影響銀行 |
|---|---|---|---|
isSameAmount | 金額精確匹配 | 差額=0 | 中銀FPS/恒生WY/工銀FPS |
localTransferSimilarAmount | 本地轉賬容差 | HKD 20 / USD 3 | 中銀/工銀/建銀 |
isDifAreaSimilarAmount | 跨區轉賬容差 | HKD 420 / USD 60 | 中銀REMIT/匯豐輔助/EWB |
amountSimilarBoco | BANKCOMM/CCBASIA | HKD 300 / USD 45 | 交行/建銀 |
amountSimilarForAuto(HSBC) | 匯豐自動入賬 | HKD 65 / USD 14 | 僅匯豐 |
注意:修改通用容差函數(如 localTransferSimilarAmount)會同時影響多家銀行,需評估影響範圍。建議優先在銀行專屬 Match 類中覆寫,而非修改通用函數。
自動入賬的完整決策樹
完全匹配不等於自動入賬。系統還需要通過一系列安全檢查,全部通過才會全自動入賬。
5 個基本前提條件
條件 1: 金額在自動入賬限額內。 每種幣種有自動入賬上限(如 HKD 200 萬)。超過限額的入金需要人工確認——這是防止大額資金異常流入的安全閥。限額數字 → 入金規則速查 § 幣種限額
條件 2: 流水未被人工標記拒絕。 如果運營之前標記過這條流水"不要自動處理",系統會尊重這個決定。
條件 3: 在自動處理的營業時段內。 自動入賬只在工作時段執行。非工作時段的完全匹配會暫存為輔助匹配,等到工作時段再處理。具體時段 → 入金規則速查 § 處理時段
條件 4: 一條流水只對應一個用戶。 如果同一條流水匹配到了不同用戶的申請,系統無法自動判斷歸屬,需要人工介入。這種情況通常是兩個用戶碰巧轉了相同金額。
條件 5: 該用戶當天自動入賬不超過 10 筆。 防止異常情況下對單一用戶大量自動入賬。10 筆是安全上限——正常用戶極少一天入金超過 10 次。
營業時段暫停窗口(2412 規則)
即使在正常營業時段內,自動入賬也會在以下時間窗口暫停:
- 08:55 ~ 09:00:開盤前對賬窗口
- 16:05 ~ 16:10:收盤後對賬窗口
為什麼? 港股開盤和收盤時刻,系統需要對證券帳戶餘額進行對賬。如果此時正好有一筆自動入金在執行,可能導致帳戶餘額在對賬瞬間不一致。這 5 分鐘的暫停窗口確保對賬過程中不會有資金變動干擾。
2412 規則配置位置
deposit/src/app/Business/DepositConfigNew.php:603-641
線上開戶首筆入金最低限額
線上開戶用戶的首筆入金需滿足最低金額要求,這是風控要求——確保線上開戶用戶有足夠的初始資金:
| 幣種 | 最低限額 | 說明 |
|---|---|---|
| HKD | 10,000 | 約 1,300 USD |
| USD | 1,500 | — |
| CNY | 10,000 | 約 10,000 HKD |
不滿足最低限額的首筆入金會被降級為輔助匹配,由運營人工確認。後續入金沒有最低限額要求——只有線上開戶的首筆入金受此限制。
配置位置
最低限額校驗在各銀行 Matcher 的線上開戶分支中實現。以中銀為例,BocMatch.php 中線上開戶路徑會額外檢查 amount >= min_amount。
風控集成
通過 5 個基本條件和 2412 暫停窗口後,系統還會進行以下風控檢查:
黑名單檢查:調用 hk-deposit-blacklist-go 服務。如果用戶或關聯資訊命中黑名單,入金的 DepositType 會被標記為 HIGH_RISK(5),強制轉入人工審核流程。黑名單支持設置過期時間——部分黑名單條目是臨時性的(如某用戶被臨時風控觀察)。
白名單驗證:調用 hk-deposit-whitelist-go 服務。主要用於 HK 線上開戶用戶的 eDDA 方式驗證——確認該用戶已通過白名單准入。
高風險國家/SWIFT 檢查:如果匯款來源國在高風險國家名單中(基於 SWIFT 代碼判斷),入金會被標記為 HIGH_RISK,需要人工審核。這是反洗錢(AML)合規要求。
HK 線上開戶區域限制:線上開戶用戶 + 非 FPS 方式 + 沒有綁定港區銀行卡支付方式 → 自動攔截。這是防止線上開戶用戶通過非本地渠道入金的風控策略。
完整決策樹
條件不通過 ≠ 入金失敗
任何條件不通過,系統只是把"自動入賬"降級為"輔助匹配"——運營確認後仍然可以入賬。風控命中 HIGH_RISK 的入金也不是直接拒絕,而是需要運營和風控團隊聯合審核。這些條件都是安全閥,不是攔截器。
匹配後的完整路徑
從匹配成功到資金到賬,中間經過 SBA(Server Bank Account)入金編排。SBA 是系統的"內部銀行",所有資金餘額變動都通過 SBA 的 Procedure 完成,保證原子性。詳見 SBA 概念與數據模型。
匹配規則調試指南
當匹配引擎的行為不符合預期時(該配上的沒配上、不該配上的配上了),按以下路徑排查。
分步 Runbook:匹配結果不符合預期
第 1 分鐘 — 確認匹配輸入
- 找到對應的 Flow 記錄(OA 流水列表 → 搜索金額/日期/銀行)
- 找到對應的 Apply 記錄(OA 申請列表 → 搜索 UID/金額)
- 確認兩條記錄的
status都是 0(待處理)— 如果不是 0,匹配引擎不會掃描
第 2~5 分鐘 — 逐維度對比 4. 幣種:Flow.currency vs Apply.currency(必須完全一致) 5. 金額:計算差額 = Apply.amount - Flow.amount
- 差額 < 0 → 流水比申請大,不匹配
- 差額在容差內 → 應該匹配(查該銀行的容差表)
- 差額超容差 → 正常不匹配
- 姓名:
Flow.en_namevs 用戶註冊英文名- 完全一樣 → 精確匹配
- 順序不同 → 應該走模糊匹配
- 有特殊字符/前綴 → 檢查歸一化是否生效
- 日期:流水日期是否在申請日期的匹配窗口內?
- 標準窗口:-3 ~ +2 天
- 中銀窗口:-3 ~ +4 天
- FPS 窗口:-1小時 ~ +2天
- 卡號:
Flow.customer_accountvsApply.bank_card_number(清洗後比較)
第 5~10 分鐘 — 判斷預期結果 9. 查該銀行的 Matcher 類規則(銀行專屬匹配規則) 10. 確認該銀行該 flow type 的匹配路徑: - 是走自動入賬路徑還是輔助匹配路徑? - 該 flow type 是否在 mustFalse 列表中(即不能自動入賬)? 11. 如果所有維度都滿足但還是沒配上 → 檢查是否被風控攔截或 2412 暫停
定位到問題後:
- 如果是容差/窗口不夠 → 評估是否需要調整(→ 變更指南)
- 如果是數據問題(姓名格式異常、卡號缺失) → 聯繫用戶修正
- 如果是系統 Bug → 記錄復現步驟,升級到入金開發團隊
常見誤解
| 誤解 | 事實 |
|---|---|
| "匹配引擎是即時的" | 不是。每 3 分鐘批量運行一次。中間有個匹配週期的等待 |
| "完全匹配就一定自動入賬" | 不一定。還需通過 5 個前提條件 + 風控檢查,任一不通過都降級為輔助匹配 |
| "輔助匹配就是匹配失敗" | 不是。輔助匹配是"可能對,但系統不夠確定"。運營確認後正常入賬 |
| "所有銀行用同一套匹配規則" | 不是。14 家銀行各有獨立的 Matcher 類,規則差異很大 |
| "金額差異就是手續費" | 通常是,但也可能是用戶轉錯金額、或銀行側匯率換算差異 |
| "改了容差只影響一家銀行" | 看改的是哪個函數。通用容差函數(如 localTransferSimilarAmount)會影響所有使用它的銀行 |
讀完之後
| 我想... | 去看 |
|---|---|
| 排查匹配失敗的具體問題 | 入金排障 |
| 查容差、限額、時間窗口的數字 | 入金規則速查 |
| 了解流水怎麼進入系統 | 銀行流水採集 |
| 了解 eDDA 為什麼不走匹配引擎 | eDDA 代扣入金 |
| 了解匹配後 SBA 怎麼入賬 | SBA 資金編排 |
| 修改匹配規則該怎麼做 | 入金變更指南 |
| 了解匹配後的沖正/退款路徑 | 退款與沖正 |