深色模式
匹配与自动入账
本页说明
讲什么:当用户通过 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 资金编排 |
| 修改匹配规则该怎么做 | 入金变更指南 |
| 了解匹配后的冲正/退款路径 | 退款与冲正 |
这个页面有帮助吗?