Skip to content

出金生命周期

本页说明

讲什么:跟着一笔钱走完出金全程——从用户点击"提交"到钱到银行卡,中间每一步发生了什么 适合谁:需要理解出金完整路径的产品经理 前置阅读出金方式总览预计阅读:5 分钟 负责人:出金产品经理

核心要点:一笔出金从提交到完成经历六大阶段:前置检查→任务创建→风控检测→三步审批→自动/人工执行→结果确认。大部分出金在 Confirm→Remittance 两步内自动完成。


全程概览

一笔出金从头到尾经历这些阶段:

下面按时间顺序,完整叙述每一步。


第一步:用户提交 + 前置检查

用户在 App 点击"提交出金"后,在出金任务创建之前,系统执行一系列前置检查。检查不通过的出金请求不会创建出金任务——用户在 App 端直接看到错误提示。

最大可提金额

系统首先计算用户最大可提金额:

最大可提金额 = min(实时净资产, Min_ELV, 最大授信额)

如果出金金额超过最大可提金额,直接拒绝。融资账户和现金账户的计算方式不同,融资账户还需扣除保证金要求。

前置检查清单

顺序检查项不通过结果触发时机
1出金限制标记(风控)直接拒绝("账户暂时无法出金")进入资金页面 / 点击确认
2出金黑名单直接拒绝("账户被限制提取资金")进入资金页面
3不动账户 / 休眠户直接拒绝("休眠户不支持出金")进入资金页面 / 点击确认
4证券账户状态拒绝("未开通证券账户/已销户")进入页面
5穿仓校验拒绝("账户存在欠款")点击确认出金
6GDCA 认证拒绝("未完成 GDCA")点击确认出金
7NSS 问卷拒绝("未完成 NSS 问卷")点击确认出金
8银行卡有效性提示重新绑卡选择收款账户
9银行账户认证状态拒绝("银行账户未通过认证")选择收款账户
10在线开户入金门槛拒绝(绑卡须转账 ≥ 10,000 HKD 或 1,500 USD)选择收款账户 / 点击确认
11可用出金方式限制可选通道选择收款账户
12币种-市场一致性拒绝点击确认
13费用计算展示给用户确认(CHATS/RTGS 有弹窗)点击确认
14通道路由确定 method 值点击确认
更多限制场景(低频但需注意)
检查项不通过结果说明
大陆银行卡拒绝("不支持提取到中国大陆银行账户")系统直接拦截
A 股通人民币限制拒绝("A 股通 CNH 仅支持提取到香港银行")仅 CNH + 非港银行
Payoneer 账户拒绝("Payoneer 账户不支持出金")业务限制
波多黎各地区拒绝地区限制
融资可提金额拒绝("超出现金可提金额")融资账户专属
银行币种不匹配拒绝("银行账户币种与出金币种不一致")如港元账户提美元
天星银证未授权拒绝("未授权银证")仅银行发起出金场景
机构账户未授权拒绝机构账户专属

这些错误码归属 140670xxx 系列,完整列表见 出金数据字典 § 前置校验错误码

如果需求变更:修改前置检查
  • 新增检查项 → withdraw/src/app/Business/CreatorBase.phpcheck*() 方法链中添加
  • 调整黑名单 → hk-withdraw-blacklist-go 服务管理接口(数据库配置,即时生效)
  • 修改通道路由逻辑 → withdraw/src/app/Business/CreatorBase.phpcalcMethod() 方法
  • 修改费用计算 → CreatorBase.phpgetFee() 方法

第二步:任务创建 + 通道路由

检查全部通过后,系统创建出金任务(写入 tasks 表),同时确定出金通道。

通道路由由 calcMethod() 自动决定:

关键边界:即使银行卡支持 BST,如果是招行/民生 + 离岸人民币 CNH,系统不选 BST,而是留给运营手动选择。因为招行/民生的 BST 对 CNH 有额外限制。天星不受此影响。

method = null 时,运营在 Confirm 步骤从 9 种可选通道中手动选择。

任务创建后状态为 PENDING(0),同时入队多个异步事件(风控检测、银行卡状态更新等),开始后续处理。


第三步:风控检测

任务创建后几秒内,系统自动执行高风险检测(HighRiskCheck),用 6 个因子判断这笔出金是否异常。

6 个因子中只有 4 个会触发额外审核(USER、AREA、FRAUDULENT、SWIFT),命中后任务模板从 default 升级为 unusual——审批从 2 步变成 3 步。

FREQUENCY 和 AMOUNT 只做记录,不触发额外审核——因为它们已有独立的安全机制(每日 10 笔限制、三层限额)。

详细的 6 因子说明和 bitmask 规则 → 出金规则手册 § 高风险判定


第四步:审批三步

风控检测完成后,任务状态变为 PROCESSING(1),进入审批流程。最多三步:

Step 1: Audit(高危审核)— 仅 unusual 模板

只有被标记为异常的出金才需要。运营人员审核该出金是否存在风险——检查用户账户状态、出金目的地、金额是否异常。

大部分正常出金跳过此步

Step 2: Confirm(确认指示)— 所有出金

所有出金都经过此步。运营确认:

  1. 用户银行卡状态正常
  2. 出金方式已正确设置
  3. 对于 method = null 的任务,手动选择出金通道

BST 额外校验:Confirm 会验证银证授权(Mandate)状态是否为 OPEN。如果不是 OPEN,出金无法推进——运营需要引导用户先完成银证授权。

重要:Confirm 不执行实际转账,这个动作保留给 Remittance。

Step 3: Remittance(汇出资金)— 所有出金

这是资金真正离开的一步。系统首先检查自动出金条件(6 个条件详见 规则手册):

  • 全部通过 → 自动调用 startTransfer(),进入下一节的自动执行路径
  • 任一不通过 → 降级为人工,运营确认后手动触发转账

审批可以全自动

对于 BST 通道的普通出金(非 unusual),如果自动出金条件全部满足,三步审批中 Confirm 和 Remittance 都是系统自动推进的。用户感知上就是"提交后几分钟到账"。

如果需求变更:修改审批流程
  • 修改审批步骤 → withdraw/src/app/Business/Task.php$stepTemplates 数组
  • 新增审批步骤 → 新建 Step 类(实现 IFStep 接口)+ 加到模板数组
  • 修改自动出金条件 → withdraw/src/app/Business/AutoSetting.php
  • 详细变更指南 → 出金变更指南

第五步(A):BST 全自动执行

如果通道是 BST(auto_bs),Remittance 调用 startTransfer() 后,进入全自动路径:

招行/民生:通过 Socket 双向链路实时获取结果,通常秒级完成。

天星:通过 REST API 分两阶段轮询获取结果——快速轮询(AsbBstTransfer 每 5 秒,最多 10 次,~50 秒)和兜底同步(SyncAsbBstWithdraw 2 小时窗口内持续同步)。兜底同步后仍未完成则标记异常,需运营人工查询天星 API 确认银行侧状态。

余额扣减注意:Remittance 执行时先从 auto_settings 扣减出金金额。如果余额低于 alarm 阈值 → 发飞书告警;低于 stop 阈值 → 自动关闭该币种的自动出金。这个扣减发生在银行转账之前——即使银行拒绝,余额已扣减,需运营手动恢复。

通道技术细节 → 通道执行手册 § BST


第五步(B):人工通道执行

所有非 BST 通道(网银、FPS、传统)都是运营驱动的:

关键区别:非 BST 通道的 startTransfer()Confirm 步骤就调用了(不是 Remittance),因为是同步调用——SBA 立刻返回 transfer_manual。然后运营在银行完成转账后,在 Remittance 步骤点击确认。

部分通道在 Remittance 有前置要求:

通道前置要求
广发 FPSFPS 批量提交完成
CHATS/RTGS文件导出完成
中银 FPSFPS 提交完成

通道技术细节 → 通道执行手册


第六步:结果处理

无论 BST 还是人工通道,最终结果只有三种:

结果任务状态后续
成功DONE(2)通知用户,出金完成
失败保持 PROCESSING(1)运营介入,可能换通道重试
超时保持 PROCESSING(1)运营查询银行状态,手动确认或重试

BST 回调码参考:

  • 0 = 成功 → Task DONE
  • -5 = 超时 → 自动切换备用服务器重试
  • -6 = 银行拒绝 → 标记失败,需人工处理

异常场景的详细排查 → 出金排障


其他触发方式

上面描述的是"用户在 moomoo App 发起出金"的标准路径。还有几种非标准触发方式:

银行发起出金

招行、民生、天星支持银行端发起出金——用户在银行 App 操作转出,moomoo 被动接收:

系统每分钟通过队列消费者拉取银行流水,发现新的银行端出金后自动创建任务,method 固定为 auto_bs,进入标准审批流程。

cmb_list / ms_list 记录状态:0=待处理 → 1=处理中 → 2=成功(任务已创建) / 3=失败

如果需求变更:支持新银行的银行端发起
  1. 新建 xxx_list 表(参考 cmb_list 结构)
  2. 新建两个队列事件:SyncXxxWithdraw(拉取流水)+ XxxWithdrawCreate(创建任务)
  3. Queue.php$_enableEvent 中注册
  4. 对接银行侧流水查询 API

基金赎回出金

基金赎回不是用户直接发起出金,而是赎回成功后系统自动创建出金任务

基金赎回有独立的 5 个事件组成等待链路:

事件做什么
FundWithdrawCreate接收赎回完成通知
FundWithdrawWait等待赎回资金到达证券账户
FundWithdrawArrivalTime检查预计到账时间
FundWithdrawSuccess资金到账 → 创建 fund 模板的出金任务
FundWithdrawFailed到账失败 → 需人工处理

这条链路可能需要 T+1 到 T+3 天,取决于基金赎回的到账时间。

基金赎回 ≠ 用户主动出金

触发方式不同(系统自动 vs 用户手动),前置流程不同(需等资金从基金账户转入证券账户),但风控处理相同(都经过 HighRiskCheck)。

现金宝赎回出金

现金宝(活期理财)赎回与基金赎回类似,但回调方式不同——通过 SrvPush(服务推送)回调,而非队列轮询。

事件做什么
CurrentDepositRedeemSuccess赎回成功 → 推进出金任务
CurrentDepositRedeemRejected赎回被拒 → 出金任务标记失败
CurrentDepositRedeemSbaCreateRetrySBA 创建失败时重试

CRM 代发出金

运营可在 CRM 系统中直接帮用户发起出金(无需用户在 App 操作)。适用场景:

  • 用户无法登录 App(如设备故障)
  • 批量退款/补偿操作
  • 特殊情况下的运营协助

CRM 代发出金与用户自发出金走相同的审批流程和风控检测,但跳过部分 App 端前置检查(如 GDCA)。

OM 账户出金

OM(Omnibus)账户是合并持仓账户,出金时 Remittance 步骤会先执行 OmWithdrawDeduct(OM 扣款),从 OM 子账户扣除资金。如果 OM 扣款失败,出金任务卡在 Remittance 步骤,需人工处理。

OM 出金也支持 BST 自动出金,但前提是 OM 扣款已完成。

冲正

出金已完成(DONE)后需要把资金追回时,运营发起冲正(REVERSE):

  1. 运营在 CRM 发起冲正操作
  2. 系统检查状态——只有 DONE 的任务才能冲正
  3. 更新任务状态为 REVERSE(5)
  4. SBA 执行反向资金操作
  5. 通知用户出金已撤回

触发原因:银行退回、错误出金、风控事后拦截。


异步驱动:为什么有时候要等

你可能注意到,出金流程中很多步骤之间有几秒到几分钟的间隔。这是因为出金系统采用事件驱动队列——每个异步操作是一个"事件",放入数据库队列表中,由后台进程逐个处理。

11 点截止规则与 8:30 批量处理

出金任务有一个关键的日切时间点

时间系统行为
每日 11:00截止线——此时间之后提交的非自动出金,标记为"次日处理"
次日 08:30系统自动将前一天 11:00 后提交的任务从"次日处理"转为"处理中",运营开始处理

这意味着用户在 11:00 之后提交的非自动出金(非 BST 通道),实际要等到次日 08:30 才开始处理。BST 自动出金不受此规则影响(在服务时段内随时处理)。

NSS 名单筛查

跨境电汇(tele_transfer)在执行前需通过 NSS(Name Screening Service) 检查收款人姓名,确认不在制裁名单上。NSS 不通过的出金需人工审核,运营联系合规团队判断。

你观察到的实际发生了什么
"提交后几秒才开始审批"风控检测事件在排队等待执行
"BST 出金等了几分钟"系统正在轮询银行结果(每 5~60 秒一次)
"广发 FPS 出金等了很久"广发轮询最多 1000 次(可达数小时)
"基金赎回出金等了好几天"在等赎回资金从基金账户到证券账户

队列消费者每分钟由 cron 启动,基于数据库锁避免重复消费。如果某类事件的专用消费者进程挂了,该类事件会卡住。

这不是 bug

间隔是异步设计的正常表现。如果出金异常地长时间不推进,排查方向是:对应的队列消费者进程是否在运行。


常见误解

误解事实
"用户点了提交,出金就开始了"还没有。系统先执行 14 项前置检查,任一不通过连出金任务都不会创建。用户在 App 端直接看到错误提示
"处理中 = 银行正在转钱"不一定。"处理中"包含了 Audit → Confirm → Remittance 三步审批,可能卡在运营确认环节,银行还没收到指令
"BST 出金秒到"招行/民生通常秒级,但天星最长可能等 2 小时(快速轮询 + 兜底同步)。即使招行,也需要 SBA 冻结/扣款/发指令的处理时间
"11 点后不能出金"可以出金。BST 自动出金不受此限制。11 点截止规则只影响非 BST 通道——这些任务会推迟到次日 08:30 开始处理
"CRM 代发出金跳过风控"不跳过。CRM 代发走相同的审批流程和风控检测(HighRiskCheck),只是跳过部分 App 端前置检查(如 GDCA)

读完之后

我想...去看
了解某条规则为什么存在、能不能改出金规则手册
看某种通道从 Remittance 到银行的技术细节通道执行手册
出金出了问题,按症状排查出金排障
推动一个出金相关的需求变更出金变更指南
查某个状态码/字段是什么意思出金数据字典
这个页面有帮助吗?

内部业务文档 · 仅限 moomoo 团队使用