深色模式
银行流水采集
本页说明
讲什么:每家银行的流水如何到达系统、流水表结构与分片策略、采集定时任务、流水类型码 适合谁:需要理解"匹配引擎的输入从哪来"的产品经理 前置阅读:入金方式总览预计阅读: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 和流水状态码 | 入金规则速查 |
| 看某家银行的详细对接规则 | 银行能力矩阵 |
| 了解采集服务在架构中的位置 | 系统架构与数据流 |
这个页面有帮助吗?