深色模式
招商银行 CMB
本页说明
讲什么:招商银行银证转账(BST)渠道侧 Socket 协议规范 + moomoo 侧适配逻辑 适合谁:PM 了解对接细节 / 开发定位代码 / 运营理解银行特性 前置阅读:银行能力矩阵 · BST 银证转账预计阅读:8 分钟 负责人:出入金产品团队
核心要点:招行通过 SM2 加密的 Socket 双向链路实现秒级银证转账,是三家 BST 银行中协议最复杂但响应最快的。
能力总览
| 能力 | 支持情况 | 协议/通道 | 核心服务 |
|---|---|---|---|
| 入金(BST 银证转账) | ✅ | 二进制 Socket 双向链路 | cmb_stock_trans Entry Server |
| 出金(BST 银证自动) | ✅ | 二进制 Socket 双向链路 | cmb_stock_trans Exit Server |
| SM2 国密加密 | ✅ | SM2 签名 + 加密 | 内置加密模块 |
| eDDA/eDDI | ❌ | — | — |
| FPS | ❌ | — | — |
招商银行是 moomoo 的核心 BST(银证转账)渠道之一,通过专线 Socket 双向持久连接实现实时入金通知和出金指令下发。支持 SM2 国密加密,保障资金指令的安全性。
核心参数速查
| 参数 | 值 | 说明 |
|---|---|---|
| IMPORT_BANK_ID | 7 | 系统内银行标识 (CMBCCHINA) |
| TransType | 102 (BST) / 205 (普通) | 银证转账 / 普通入金两种类型 |
| AUTO_SETTING_ID | 2 | auto_settings 表中的限额配置 ID |
| 协议类型 | 二进制 Socket | 固定字节长度消息帧 |
| 加密方式 | SM2 国密算法 | 可选,默认 'N' 不加密 |
| 通信模式 | 双向持久连接 | Entry Server + Exit Server |
渠道接口概览
协议架构
| 维度 | 说明 |
|---|---|
| 协议类型 | 二进制 Socket(固定字节长度消息帧) |
| 加密方式 | SM2 国密算法(可选,默认 'N' 不加密) |
| 数据格式 | 二进制(固定长度字段,ASCII 编码) |
| 通信模式 | 双向持久连接(Entry Server 接收 + Exit Server 发送) |
| 心跳机制 | 0009/1009 和 0010/1010 双向心跳保活 |
| 连接管理 | 断连自动切换备用 Exit Server |
消息帧结构
每条 Socket 消息由固定格式的头部 + 可变长度的业务数据组成:
| 部分 | 长度 | 格式 | 说明 |
|---|---|---|---|
| 加密类型 | 1 字节 | char | 'N' = 不加密,'Y' = SM2 加密 |
| 包总长度 | 2 字节 | little-endian uint16 | 整个消息帧的长度 |
| 签名 | 64 字节 | binary | SM2 数字签名(不加密时为空白填充) |
| 命令码 | 4 字节 | ASCII | 如 "0001"、"4001" |
| TX 包长度 | 2 字节 | little-endian uint16 | 业务数据部分的长度 |
| 头部合计 | 73 字节 | ||
| 业务数据 | 可变 | binary | 固定长度字段拼接 |
字节序注意
包长度字段使用 little-endian 字节序,开发时需注意编解码方向。
渠道侧接口详情 — 完整命令码表
登录与认证
| 命令码 | 方向 | 消息名 | 用途 |
|---|---|---|---|
| 0001 | 券商→银行 | BrokerageLoginToBankReq | 券商登录银行,建立 Entry 链路 |
| 1001 | 银行→券商 | BrokerageLoginToBankRsp | 登录响应,返回认证结果 |
| 0002 | 银行→券商 | BankLoginToBrokerageReq | 银行登录券商,建立 Exit 链路 |
| 1002 | 券商→银行 | BankLoginToBrokerageRsp | 银行登录响应 |
| 0003 | 券商→银行 | BrokerageLoginoutReq | 券商主动登出 |
| 1003 | 银行→券商 | BrokerageLoginoutRsp | 登出响应确认 |
密码与配置
| 命令码 | 方向 | 消息名 | 用途 |
|---|---|---|---|
| 0004/1004 | 双向 | ModifyPwd | 修改通信密码 |
| 0005/1005 | 双向 | ChangeDate | 修改对账日期 |
心跳保活
| 命令码 | 方向 | 消息名 | 用途 |
|---|---|---|---|
| 0009/1009 | 券商→银行 | Keepalive | 券商侧心跳(moomoo 发起) |
| 0010/1010 | 银行→券商 | Keepalive | 银行侧心跳(招行发起) |
双向心跳确保连接存活。任一方超时未收到心跳即判定连接断开,触发重连。
客户管理
| 命令码 | 方向 | 消息名 | 用途 |
|---|---|---|---|
| 2001/3001 | 银行→券商 | GetCustmorInfo | 银行查询客户在券商的信息 |
| 2002/3002 | 券商→银行 | NotifyCustmorResult | 通知客户验证结果(开户/验证) |
| 2003/3003 | 银行→券商 | Cancel | 取消客户的银证授权关系 |
资金转账(核心)
| 命令码 | 方向 | 消息名 | 用途 |
|---|---|---|---|
| 4001/5001 | 银行→券商 | BankMarginIn | ⭐⭐⭐ 入金通知 — 银行告知券商有客户转入资金 |
| 4002/5002 | 券商→银行 | BrokerageMarginOut | ⭐⭐⭐ 出金指令 — 券商指示银行将资金转出到客户账户 |
| 4003/5003 | 银行→券商 | BankMarginOut | ⭐⭐⭐ 出金结果通知 — 银行告知出金处理结果 |
| 4004/5004 | 券商→银行 | BankMarginOutReject | ⭐⭐ 拒绝出金 — 券商拒绝银行侧发起的出金请求 |
对账
| 命令码 | 方向 | 消息名 | 用途 |
|---|---|---|---|
| 6001/7001 | 双向 | MarginCheck | 对账请求发起 |
| 6011/7011 | 银行→券商 | BankMarginInList | 入金对账清单 |
| 6013/7013 | 银行→券商 | BankNewCustmoerList | 新开户客户清单 |
| 6014/7014 | 银行→券商 | BankCancelList | 取消授权客户清单 |
| 6015/7015 | 银行→券商 | BankMarginOutList | 出金对账清单 |
| 6003/7003 | 券商→银行 | NewCustmoerCheck | 新客户对账确认 |
| 6004/7004 | 券商→银行 | CancelCheck | 取消授权对账确认 |
| 6005/7005 | 券商→银行 | MarginOutCheck | 出金对账确认 |
核心接口字段详情
4001 BankMarginInReq(入金通知)
银行通知券商有一笔入金到账,是 BST 入金的核心消息。
| 字段 | 长度 | 类型 | 描述 |
|---|---|---|---|
| m_brokerage_custmor_id | 20B | string | 券商客户 ID。取值 moomoo UID |
| m_bank_custmor_id | 16B | string | 银行客户 ID。取值 银行卡号 |
| m_currency | 3B | string | 币种。取值 HKD / USD / CNH |
| m_amount | 20B | string | 金额。如 "50000.00" |
| m_tx_date | 8B | string | 交易日期。格式 YYYYMMDD |
| m_tx_time | 6B | string | 交易时间。格式 HHMMSS |
| m_tx_seq | 16B | string | 交易序号。唯一标识(去重依据) |
| m_reconciliation_date | 8B | string | 对账日期。格式 YYYYMMDD |
字段编码说明
所有字段为固定长度 ASCII 字符串,不足部分右补空格。金额字段包含小数点,如 "50000.00" 后补空格至 20 字节。币种严格 3 字节:HKD、USD、CNH。
4002 BrokerageMarginOutReq(出金指令)
券商向银行发起出金指令,将客户资金从证券账户转回银行账户。
| 字段 | 长度 | 类型 | 描述 |
|---|---|---|---|
| m_brokerage_custmor_id | 20B | string | 券商客户 ID。moomoo UID |
| m_bank_custmor_id | 16B | string | 银行客户 ID。银行卡号 |
| m_bank_custmor_name | 20B | string | 银行客户姓名。用于银行侧验证 |
| m_currency | 3B | string | 币种。HKD / USD / CNH |
| m_amount | 20B | string | 金额。出金金额 |
| m_tx_date | 8B | string | 交易日期。格式 YYYYMMDD |
| m_tx_time | 6B | string | 交易时间。格式 HHMMSS |
| m_tx_seq | 16B | string | 交易序号。唯一标识 |
| m_reconciliation_date | 8B | string | 对账日期。格式 YYYYMMDD |
通用响应字段
| 字段 | 长度 | 类型 | 描述 |
|---|---|---|---|
| m_rsp_code | 4B | string | 响应码,"0000" = 成功 |
moomoo 侧适配
Entry/Exit Server 双向架构
招行 BST 采用双向持久连接架构,moomoo 侧部署两个 Server 分别处理入站和出站消息:
| Server | 进程名 | 职责 | 连接方向 |
|---|---|---|---|
| Entry Server | entrance_business | 接收银行发来的消息(入金通知、对账清单等)→ 转发给 CRM | 银行 → moomoo |
| Exit Server | exit_business | 接收 CRM 的出金指令 → 发送给银行 | moomoo → 银行 |
断连处理:Exit Server 支持备用地址。当主连接断开时,自动切换到备用 exit_server 地址,确保出金指令不中断。
SM2 国密加密流程
招行 BST 支持 SM2 国密算法对消息进行签名和加密,保障资金指令的安全性。
加密配置
- 加密类型字段 = 'Y' 时启用 SM2
- 默认为 'N'(不加密),可按需开启
- 证书文件位于
cmb_stock_trans/conf/目录下
入金:BST 实时入金
入金流程
BST 入金的最大优势是实时性和确定性:银行直接告知客户 ID 和金额,无需像普通银行转账那样做模糊匹配。
出金:BST 自动出金 (auto_bs)
出金流程
处理时段
| 币种 | 处理时段 | 说明 |
|---|---|---|
| HKD / USD | 交易日 08:40 ~ 15:59 | 全交易日可处理 |
| CNH | 交易日 08:40 ~ 10:59 | 仅上午,下午不可处理 |
| 保证金提取 | 交易日 08:40 ~ 10:59 | 与 CNH 同窗口 |
CNH 出金时段限制
CNH(离岸人民币)的出金窗口仅到上午 10:59,远短于 HKD/USD。运营和用户需注意在此窗口内发起 CNH 出金,超时将延至下一个交易日处理。
CNH 出金限制
calcMethod() 方法中对 CNH 有额外限制:
- CNH + 非香港银行 → method = null(不支持)
- 即 CNH 出金到大陆银行卡 = 不支持
- CNH 仅支持出金到香港本地的招行账户
出金取消规则
| 场景 | 可否取消 | 条件 |
|---|---|---|
| 非交易时间(< 08:20 或 ≥ 16:00) | ✅ | 无条件可取消 |
| 交易日 08:20 ~ 16:00 | ✅ / ❌ | 距预定执行时间 ≥ 10 分钟方可取消 |
| 非交易日 | ✅ | 无条件可取消 |
为什么交易时段内有 10 分钟限制? 出金指令一旦进入银行处理队列就无法撤回。10 分钟的缓冲期确保取消请求能在银行实际执行前到达。
回调结果码
| result | 含义 | 系统处理 | 是否需人工 |
|---|---|---|---|
| 0 | 成功 | Task 状态 → DONE | ❌ |
| -5 | 超时 | 自动切换备用 exit_server 重试 | ❌ |
| -6 | 银行拒绝 | Task 状态 → 异常 | ✅ 人工处理 |
超时重试机制
当收到 result = -5(超时)时:
- 记录当前 exit_server 超时事件
- 切换到备用 exit_server 地址
- 使用相同的 m_tx_seq 重新发送出金指令
- 如果备用 exit_server 也超时,标记为异常,等待人工处理
出金限额配置
招行 BST 出金的限额通过 auto_settings 表配置(WHERE id = 2):
| 字段 | 含义 | 说明 |
|---|---|---|
| hk_max_amount | 单笔最大金额 | 超过则拒绝 |
| hk_alarm_amount | 告警金额 | 超过则触发告警但不阻断 |
| hk_stop_amount | 熔断金额 | 超过则暂停自动出金 |
三级阈值逻辑:
- 金额 ≤ alarm_amount:正常自动处理
- alarm_amount < 金额 ≤ max_amount:自动处理 + 触发告警通知
- 金额 > max_amount 或累计 > stop_amount:暂停自动出金,转人工审批
异常场景与告警
Socket 断连
| 告警项 | 级别 | 响应时限 | 说明 |
|---|---|---|---|
| Entry Server 断连 | 严重 | 15 分钟内 | 无法接收入金通知 |
| Exit Server 断连 | 严重 | 15 分钟内 | 无法发送出金指令 |
| 双向心跳超时 | 警告 | 30 分钟内 | 可能即将断连 |
Socket 断连是最严重的告警之一——断连期间所有 BST 入金通知和出金指令都会中断。系统会自动尝试重连,但如果 15 分钟内未恢复,需要开发人员介入排查。
常见异常处理
| 异常场景 | 表现 | 处理方式 |
|---|---|---|
| Socket 断连 | 入金/出金中断 | 自动重连;15 分钟未恢复则人工介入 |
| SM2 签名验证失败 | 消息被拒绝 | 检查证书是否过期或被替换 |
| 出金超时 (result=-5) | 银行无响应 | 自动切换备用 exit_server |
| 银行拒绝 (result=-6) | 出金失败 | 人工核实原因后重试或退款 |
| 对账不平 | 入金/出金金额不一致 | 运营核查差异,联系招行对账 |
| CNH 超时段出金 | 出金被拒 | 延至下一个交易日上午处理 |
双方功能对应矩阵
| 功能 | 渠道侧(招商银行) | moomoo 侧 | 说明 |
|---|---|---|---|
| 登录认证 | 双向握手 | Entry/Exit Server | 0001-1003,建立双向链路 |
| 心跳保活 | 双向心跳 | Entry/Exit Server | 0009-1010,每 30s 一次 |
| 入金通知 | 4001 BankMarginIn | Entry → CRM | m_brokerage_custmor_id 等,实时入金 |
| 出金指令 | 5002 接收执行 | CRM → Exit → 银行 | m_amount / m_currency 等,自动出金 |
| 出金结果 | 4003 BankMarginOut | Entry → CRM | result 码,回调通知 |
| 对账 | 6xxx 系列 | Entry/Exit | 多种清单,每日对账 |
| 加密 | SM2 验签解密 | SM2 签名加密 | 消息头 64B 签名,可选 |
定时任务
| 任务 | 频率 | 说明 |
|---|---|---|
| 心跳检测 | 每 30 秒 | Entry/Exit Server 双向心跳 |
| 断连检查 | 每 5 分钟 | 检查 Socket 连接状态,异常则告警 |
| 对账发起 | 每日收盘后 | 发起 6001 对账请求 |
| 对账核验 | 每日 T+1 | 比对入金/出金/客户清单 |
需求变更指引
| 变更需求 | 改动位置 | 说明 |
|---|---|---|
| 修改出金限额 | auto_settings WHERE id = 2 | 调整 max/alarm/stop 三级阈值 |
| 修改处理时段 | exit_business → 时段配置 | 调整各币种的处理窗口 |
| 修改 CNH 限制 | calcMethod() → CNH 判断逻辑 | 修改 CNH 出金的银行/地区限制 |
| 修改取消规则 | 出金取消逻辑 → 时间判断 | 调整 10 分钟缓冲期 |
| 更换 SM2 证书 | cmb_stock_trans/conf/ | 替换公私钥文件并重启服务 |
| 调整心跳间隔 | cmb_stock_trans → keepalive 配置 | 修改心跳频率 |
| 新增命令码 | cmb_stock_trans/comm/pact.h | 协议定义文件 |
| 修改 Entry Server 逻辑 | cmb_stock_trans/entrance_business/ | 入站消息处理 |
| 修改 Exit Server 逻辑 | cmb_stock_trans/exit_business/ | 出站消息处理 |
| 调整备用 exit_server | Exit Server 配置 | 修改备用地址列表 |
代码位置速查
| 模块 | 路径 | 说明 |
|---|---|---|
| 协议定义 | cmb_stock_trans/comm/pact.h | 所有命令码和消息结构定义 |
| Entry Server | cmb_stock_trans/entrance_business/ | 入站消息接收和转发 |
| Exit Server | cmb_stock_trans/exit_business/ | 出站消息发送(出金指令) |
| SM2 加密 | cmb_stock_trans/ 内置模块 | 签名 / 加密 / 解密 |
| 限额配置 | auto_settings 表 id = 2 | 数据库配置 |
| 出金通道 | withdraw/.../Method.php → auto_bs | 出金方法注册 |
与其他 BST 银行的对比
| 维度 | 招商银行 CMB | 民生银行 | 天星银行 |
|---|---|---|---|
| 协议 | 二进制 Socket | — | — |
| 加密 | SM2 国密 | — | — |
| 连接模式 | 双向持久连接 | — | — |
| 入金 | ✅ 实时通知 | ✅ | ✅ |
| 出金 | ✅ auto_bs | ✅ | ✅ |
| CNH 支持 | ✅(仅上午) | — | — |
| 对账 | 自动对账 | — | — |
BST 的优势
相比普通银行转账入金需要模糊匹配,BST 银证转账最大的优势是确定性——银行直接告知客户 ID 和金额,无需匹配引擎介入,入金实时到账。
常见客诉 Top 3
| # | 用户反馈 | 原因 | 客服话术 |
|---|---|---|---|
| 1 | "BST 出金超时" | Socket 连接抖动,回调码 -5 | "出金正在处理中,系统已自动重试,请稍候查看结果" |
| 2 | "BST 出金被拒" | 回调码 -6,银行侧拒绝 | "银行暂时无法处理您的出金,请稍后重试或联系客服" |
| 3 | "为什么不能用招行出金" | 银证授权未生效或已失效 | "请确认您的银证授权状态正常,如已过期请重新签约" |
读完之后
| 我想... | 去看 |
|---|---|
| 了解 BST 银证转账的整体架构 | BST 银证转账 |
| 看招行在各银行中的位置 | 银行能力矩阵 |
| 了解出金通道的执行细节 | 通道执行手册 |
| 了解出金审批规则 | 出金规则与审批 |
| 查 TransType 和 Bank ID 对照 | 入金规则速查 |
| 查错误码和状态码 | 统一错误码中心 |
| 了解其他入金匹配逻辑 | 匹配与自动入账 |
这个页面有帮助吗?