深色模式
民生银行 MS
本页说明
讲什么:民生银行银证转账(BST)渠道侧 Protobuf/SRPC 协议规范 + moomoo 侧适配逻辑 适合谁:PM 了解对接细节 / 开发定位代码 / 运营理解银行特性 前置阅读:内银系 BST 总览、银行能力矩阵预计阅读:8 分钟 负责人:出入金产品团队
核心要点:民生采用 Protobuf/SRPC 协议的 Socket 模式,与招行共用双向链路架构但序列化方式不同。
能力总览
| 能力 | 支持情况 | 协议/通道 | 核心服务 |
|---|---|---|---|
| BST 银证入金 | ✅ | Protobuf/SRPC(SM2 国密加密) | ms_stock_bank_transaction |
| BST 银证出金 | ✅ | auto_bs 银证自动出金 | ms_stock_bank_transaction |
| eDDA 授权 | ❌ | — | — |
| eDDI 代扣 | ❌ | — | — |
| FPS | ❌ | — | — |
| 入金流水匹配 | ❌ | — | — |
民生银行是 moomoo 接入的第二家 BST 银行——与招行共同构成内银系 BST 双通道,但采用完全不同的协议栈(Protobuf/SRPC vs 二进制 Socket)。
核心标识
| 标识 | 值 | 说明 |
|---|---|---|
| IMPORT_BANK_ID | 13 | CMBC,系统内银行唯一编号 |
| TransType | 101 (BST), 204 (普通) | 101 用于银证转账,204 用于普通入金 |
| AUTO_SETTING_ID | 1 | 自动出金配置 ID |
| 服务名 | ms_stock_bank_transaction | 核心银证服务 |
| 代码目录 | ms_sb_trans_python/ | 服务代码根目录 |
渠道接口概览
| 维度 | 说明 |
|---|---|
| 协议类型 | Protobuf 序列化 + SRPC 框架 |
| 加密方式 | SM2 国密算法(国家商用密码标准) |
| 数据格式 | Protobuf 二进制序列化(非 JSON/XML) |
| 通信模式 | RPC 请求-响应(同步调用) |
| 编码 | GB18030(中文姓名等字段使用 bytes 类型) |
| 签名算法 | SM2 国密签名,确保数据不可篡改 |
与招行的协议区别
招行使用自定义二进制 Socket 协议,民生使用 Google Protobuf + 自研 SRPC 框架。两者都走 SM2 加密,但序列化方式不同——招行是手工二进制编码,民生是 Protobuf 自动序列化。Protobuf 方案在可维护性上更优。
渠道侧接口详情 — 9 个 RPC 方法
民生银行提供 9 个 RPC 接口,通过 Request ID 标识不同的业务操作:
| 方法名 | Request ID | 请求 / 响应类型 | 用途(方向) |
|---|---|---|---|
| OpenApproval | 0x01 | OpenApprovalReq / Rsp | 开户审批(民生 → moomoo) |
| SyncData | 0x02 | CrmReq / CrmRsp | 同步客户/交易数据(民生 → moomoo) |
| WithDrawApproval | 0x03 | WithDrawApprovalReq / Rsp | 出金审批(民生 → moomoo) |
| Reconciliate | 0x04 | ReconciliationReq / Rsp | 每日对账(民生 → moomoo) |
| ChangePassword | 0x05 | ChangePasswordReq / Rsp | 修改交易密码(民生 → moomoo) |
| WithDrawAck | 0x06 | WithDrawAckReq / Rsp | 出金确认——银行确认到账(民生 → moomoo) |
| LoginIn | 0x07 | LoginInReq / Rsp | 柜员登录系统(民生 → moomoo) |
| LoginOut | 0x08 | LoginOutReq / Rsp | 柜员登出系统(民生 → moomoo) |
| CreateWithdrawFutu | 0x09 | WithdrawFutuReq / Rsp | 创建出金——moomoo 侧主动发起(moomoo → 民生) |
方法调用流程简述
- 开户流程:用户在银行端签约 → 银行调用 OpenApproval → moomoo 审批 → 返回结果
- 入金流程:用户在银行端发起 → 银行通过 SyncData 推送入金数据 → moomoo 处理到账
- 出金流程:用户在 moomoo 端发起 → CreateWithdrawFutu 发送出金请求 → 银行处理 → WithDrawAck 确认
- 对账流程:每日银行发起 Reconciliate → 双方核对交易数据 → 发现差异人工处理
核心接口字段详情
CrmReq — 数据同步请求
SyncData 方法的请求体,是民生向 moomoo 推送各类业务数据的统一入口:
| 字段 | 类型 | 描述 | 备注 |
|---|---|---|---|
| date | string | 数据日期 | 格式 YYYYMMDD |
| type | ReqType enum | 请求类型(10 种) | 决定本次推送的数据类别 |
ReqType 枚举 — 10 种数据类型
| 枚举值 | 名称 | 说明 | 触发时机 |
|---|---|---|---|
| 1 | OPEN | 开户数据 | 用户在银行端完成银证签约 |
| 2 | OPENRES | 开户结果 | moomoo 审批后返回给银行 |
| 3 | DEPOSIT | 入金数据 | 用户发起入金转账 |
| 4 | WITHDRAW | 出金数据 | 出金请求到达银行 |
| 5 | WITHDRAWRES | 出金结果 | 银行处理出金后返回 |
| 6 | CLOSE | 销户数据 | 用户解除银证关系 |
| 7 | OPENRC | 开户对账 | 每日对账——单笔开户 |
| 8 | BATCHOPENRC | 批量开户对账 | 每日对账——批量开户 |
| 9 | WITHDRAWRC | 出金对账 | 每日对账——单笔出金 |
| 10 | BATCHWITHDRAWRC | 批量出金对账 | 每日对账——批量出金 |
数据推送 vs 轮询
与天星(REST API 轮询)不同,民生采用推送模式——银行主动通过 SyncData 将数据推送到 moomoo 侧。moomoo 不需要定时轮询银行接口。
DepositItem — 入金数据字段
银行推送入金数据时,每笔入金以 DepositItem 表示:
| 字段 | 类型 | 描述 | 取值范围/格式 |
|---|---|---|---|
| TraDat | string | 交易日期 | YYYYMMDD |
| TraTim | string | 交易时间 | HHMMSS |
| RefNo | string | 参考号 | 银行侧唯一标识,对账关键 |
| SDNo | string | 券商编号 | 固定值,标识 moomoo |
| SecAc | string | 证券账号 | moomoo 账号(与 CID 映射) |
| CusAc | string | 客户账号 | 银行卡号 |
| Ccy | string | 币种 | HKD / USD(不支持 CNH) |
| Amt | string | 金额 | 字符串格式,如 "50000.00" |
| AcCkDt | string | 对账日期 | YYYYMMDD,对账时使用 |
WithDrawItem — 出金数据字段
| 字段 | 类型 | 描述 | 取值范围/格式 |
|---|---|---|---|
| TraDat | string | 交易日期 | YYYYMMDD |
| RefNo | string | 参考号 | 银行侧唯一标识 |
| SDNo | string | 券商编号 | 固定值 |
| SecAc | string | 证券账号 | moomoo 账号 |
| CusAc | string | 客户账号 | 银行卡号 |
| Ccy | string | 币种 | HKD / USD |
| Amt | string | 金额 | 字符串格式 |
| AcCkDt | string | 对账日期 | YYYYMMDD |
| SucFlg | string | 成功标志 | Y = 成功 / N = 失败 |
| TraTime | string | 交易时间 | HHMMSS |
OpenApprovalReq — 开户审批请求
银行推送开户审批,moomoo 侧决定是否通过:
| 字段 | 必填 | 类型 | 描述 |
|---|---|---|---|
| AgrNo | ✅ | string | 协议号。银证签约协议唯一标识 |
| SDNo | ✅ | string | 券商编号。固定值 |
| SecAc | ✅ | string | 证券账号。需在 moomoo 系统中存在 |
| CusAc | ✅ | string | 客户账号。银行卡号 |
| AprSts | ✅ | string | 审批状态。银行端预审结果 |
| RejRsn | ❌ | string | 拒绝原因。仅审批不通过时有值 |
| CusEnm | ❌ | string | 客户英文名。用于姓名校验 |
| CusCnm | ❌ | bytes | 客户中文名。bytes 类型(GB18030 编码) |
CusCnm 使用 bytes 类型
中文姓名字段 CusCnm 不是 string 而是 bytes 类型。这是因为 Protobuf 的 string 要求 UTF-8 编码,但民生银行使用 GB18030 编码传输中文——如果用 string 类型会导致解码错误。开发时需特别注意编码转换。
WithDrawApprovalReq — 出金审批请求
| 字段 | 必填 | 类型 | 描述 |
|---|---|---|---|
| OrgRefNo | ✅ | string | 原始参考号。关联原始出金请求 |
| SDNo | ✅ | string | 券商编号。固定值 |
| SecAc | ✅ | string | 证券账号。moomoo 账号 |
| CusAc | ✅ | string | 客户账号。银行卡号 |
| Ccy | ✅ | string | 币种。HKD / USD |
| Amt | ✅ | string | 金额。字符串格式 |
| AprSts | ✅ | string | 审批状态。通过 / 拒绝 |
| RejRsn | ❌ | string | 拒绝原因。仅拒绝时填写 |
与招行的关键差异
民生和招行同属内银系 BST,但协议和实现有显著差异:
| 维度 | 招行 CMB | 民生 MS |
|---|---|---|
| IMPORT_BANK_ID | 12 | 13 |
| AUTO_SETTING_ID | 2 | 1 |
| 协议 | 自定义二进制 Socket 协议 | Protobuf/SRPC 框架 |
| 序列化 | 手工二进制编码/解码 | Protobuf 自动序列化 |
| 加密算法 | SM2 国密 | SM2 国密 |
| CNH 支持 | 仅限 HK 银行卡持有者 | 完全不支持 |
| 处理时段 | 08:40 ~ 15:59 | 08:40 ~ 15:59 |
| 保证金时段 | 08:40 ~ 10:59 | 08:40 ~ 10:59 |
| 错误码体系 | Socket 响应码(0/-5/-6) | Protobuf 错误枚举(2001~2006) |
| 对账方式 | 每日文件对账 | SyncData(type=7~10)推送对账 |
| 服务名 | cmb_stock_trans | ms_stock_bank_transaction |
| 代码语言 | Python | Python |
| 接口数量 | — | 9 个 RPC 方法 |
一句话总结:招行是"裸"二进制协议(灵活但维护难),民生是 Protobuf 标准协议(结构清晰但依赖 proto 文件同步)。
CNH 限制
民生银行完全不支持人民币(CNH)币种。这是在代码层面硬编码的限制:
checkCurrency() → 检测到 CNH → 直接拒绝 → 返回错误码 2001 (MsBsRejRsn::LOCK_OF_CASH)| 币种 | 支持情况 | 说明 |
|---|---|---|
| HKD | ✅ | 完全支持 |
| USD | ✅ | 完全支持 |
| CNH | ❌ | checkCurrency() 直接拒绝 |
CNH 入金会被误报为"资金不足"
由于 CNH 拒绝使用的错误码是 2001(LOCK_OF_CASH = 资金不足),用户可能看到"资金不足"的错误提示,但实际原因是币种不支持。运营排查时需注意区分。
对比:
- 招行:CNH 仅限 HK 银行卡持有者(有条件支持)
- 天星:HKD / USD / CNH 全面支持
- 民生:CNH 完全不支持
错误码体系
民生特有错误码(MsBsRejRsn 枚举)
| 错误码 | 枚举名 | 含义 | 处理方式 |
|---|---|---|---|
| 2001 | LOCK_OF_CASH | 资金不足 / 币种不支持。账户余额不足,或 CNH 入金被拦截 | 通知用户检查余额/币种 |
| 2002 | ACCOUNT_ABNORMAL | 账户状态异常。账户被冻结、已销户等 | 联系民生银行确认账户状态 |
| 2003 | OTHER_REJECTION | 其他拒绝原因。银行侧风控拦截等 | 人工排查,联系银行获取详情 |
| 2004 | NSS_ISSUE | NSS 问题。网络安全子系统异常 | 技术排查网络/证书配置 |
| 2005 | GDCA_ISSUE | GDCA 问题。广东省数字证书认证异常 | KYC/证书相关排查 |
| 2006 | INVALID_BANKCARD | 银行卡无效。卡号错误、已注销、未激活 | 引导用户重新绑卡 |
与通用 BST 错误码的映射
| 民生错误码 | 对应通用状态 | 对用户的展示 |
|---|---|---|
| 2001 | FAILED(入金失败) | "资金不足,请检查银行账户余额" |
| 2002 | FAILED(账户异常) | "银行账户状态异常,请联系银行" |
| 2003 | FAILED(拒绝) | "银行拒绝处理,请联系客服" |
| 2004 | FAILED(系统异常) | "系统异常,请稍后重试" |
| 2005 | FAILED(KYC 异常) | "身份验证异常,请联系客服" |
| 2006 | FAILED(卡无效) | "银行卡无效,请更换银行卡" |
入金流程
民生 BST 入金流程
民生入金由银行端主导——用户在民生银行 App/柜台发起转账到证券账户:
入金时段限制
| 时段 | 时间范围 | 可执行操作 |
|---|---|---|
| 正常交易时段 | 08:40 ~ 15:59 | 入金 + 出金 |
| 保证金入金时段 | 08:40 ~ 10:59 | 仅保证金类入金 |
| 非交易时段 | 16:00 ~ 次日 08:39 | 不接受入金/出金请求 |
时段外入金
民生银行在非交易时段发起的入金请求会被 moomoo 侧拒绝。与天星不同(天星会暂存请求等待交易时段),民生需要用户在交易时段内重新发起。
出金流程
标准出金流程
民生出金支持两种模式:
| 模式 | 触发方式 | 接口 | 说明 |
|---|---|---|---|
| moomoo 端发起 | 用户在 moomoo App 点击出金 | CreateWithdrawFutu (0x09) | moomoo 主动调用银行接口 |
| 银行端发起 | 银行推送出金请求 | WithDrawApproval (0x03) | 民生银行推送,moomoo 审批 |
moomoo 端出金流程
银行端出金审批流程
当用户在民生银行端发起出金时:
- 银行发送
WithDrawApproval(0x03)到 moomoo - moomoo 执行风控检查(余额、限额、黑名单等)
- 审批通过:返回 AprSts = 通过 → 银行执行转账
- 审批拒绝:返回 AprSts = 拒绝 + RejRsn(拒绝原因)
auto_bs 自动出金
民生出金走 auto_bs 自动出金通道,AUTO_SETTING_ID = 1。自动出金需满足以下全部条件:
| 条件 | 说明 |
|---|---|
| 账户状态正常 | 非冻结、非销户 |
| 不在黑名单 | 出金黑名单检查通过 |
| 单笔不超限 | 金额在限额范围内 |
| 每日不熔断 | 当日累计未触发熔断 |
| 交易时段内 | 08:40 ~ 15:59 |
| 币种支持 | HKD 或 USD(非 CNH) |
不满足任一条件则转人工审批。
对账机制
每日对账流程
民生通过 SyncData 接口的 4 种对账类型实现每日对账:
| ReqType | 对账类型 | 说明 |
|---|---|---|
| 7 (OPENRC) | 单笔开户对账 | 逐笔核对开户记录 |
| 8 (BATCHOPENRC) | 批量开户对账 | 批量核对开户记录 |
| 9 (WITHDRAWRC) | 单笔出金对账 | 逐笔核对出金记录 |
| 10 (BATCHWITHDRAWRC) | 批量出金对账 | 批量核对出金记录 |
对账差异处理
| 差异类型 | 说明 | 处理 |
|---|---|---|
| 长款(moomoo 有,银行无) | moomoo 侧多了一笔交易 | 核实是否银行漏推送,必要时冲正 |
| 短款(银行有,moomoo 无) | 银行侧多了一笔交易 | 核实是否 moomoo 漏处理,必要时补录 |
| 金额不一致 | 同一笔交易金额不同 | 以银行侧为准,调整 moomoo 侧记录 |
| 状态不一致 | 同一笔交易状态不同 | 人工判断并修正 |
安全与加密
SM2 国密算法
民生银行使用中国国家商用密码标准 SM2 算法进行通信加密:
| 维度 | 说明 |
|---|---|
| 算法类型 | SM2 椭圆曲线公钥密码 |
| 密钥长度 | 256 位 |
| 等效安全性 | 约等于 RSA-3072 |
| 用途 | 请求/响应数据加密 + 数字签名 |
| 合规要求 | 中国境内银行通信必须使用国密算法 |
加密流程
- 请求端:将 Protobuf 序列化后的二进制数据用 SM2 公钥加密
- 传输:加密后的数据通过 SRPC 框架传输
- 接收端:用 SM2 私钥解密,再用 Protobuf 反序列化
- 签名验证:每个请求附带 SM2 数字签名,接收端验签确保数据完整性
异常场景手册
入金异常(4 类)
| # | 异常 | 症状 | 原因与处理 |
|---|---|---|---|
| 1 | 入金被拒(2001) | 银行返回 LOCK_OF_CASH | CNH 币种被拦截 / 余额不足。确认币种,若为 CNH 则告知不支持 |
| 2 | 账户异常(2002) | 银行返回 ACCOUNT_ABNORMAL | 银行卡冻结/销户。联系民生银行确认状态 |
| 3 | SyncData 未到达 | moomoo 未收到入金推送 | 网络中断/SRPC 通信异常。检查网络连通性,查看 SRPC 日志 |
| 4 | 数据解密失败 | Protobuf 反序列化错误 | SM2 密钥不匹配/数据损坏。检查密钥配置,联系银行技术 |
出金异常(5 类)
| # | 异常 | 症状 | 原因与处理 |
|---|---|---|---|
| 1 | CreateWithdrawFutu 失败 | 出金请求被银行拒绝 | 参数错误/银行侧风控。检查请求参数和错误码 |
| 2 | WithDrawAck 未到达 | 出金后长时间无确认 | 银行处理延迟/通信中断。人工查询银行侧状态 |
| 3 | 冻结未释放 | 出金失败但资金仍冻结 | 回滚流程异常。手动释放冻结 |
| 4 | 审批超时 | WithDrawApproval 无响应 | moomoo 审批服务异常。检查审批服务日志 |
| 5 | 重复出金 | 同一笔出金多次执行 | RefNo 去重失败。通过 OrgRefNo 排查重复 |
对账异常(3 类)
| # | 异常 | 症状 | 原因与处理 |
|---|---|---|---|
| 1 | 对账数据缺失 | 某日对账未收到 | Reconciliate 调用失败。手动触发对账 |
| 2 | 长款/短款 | 双方记录不一致 | 网络丢包/处理时序差异。人工核对并调整 |
| 3 | 批量对账超时 | BATCHOPENRC/BATCHWITHDRAWRC 处理慢 | 数据量过大。分批处理或扩容 |
柜员系统
民生银行有独立的柜员登录/登出机制,通过 LoginIn/LoginOut 接口管理:
| 接口 | Request ID | 用途 | 说明 |
|---|---|---|---|
| LoginIn | 0x07 | 柜员登录 | 银行柜员开始操作前登录 |
| LoginOut | 0x08 | 柜员登出 | 银行柜员操作结束后登出 |
柜员系统的业务意义
民生银行的部分操作(如开户审批、出金审批)需要银行柜员参与。柜员登录后才能执行审批操作,登出后系统记录操作日志。这是传统银行体系的特有流程,天星等虚拟银行不需要此机制。
密码管理
ChangePassword(0x05)接口用于修改银证交易密码:
| 维度 | 说明 |
|---|---|
| 触发场景 | 用户在银行端申请修改交易密码 |
| 影响范围 | 修改后所有银证操作需使用新密码 |
| 安全要求 | 密码在传输中经 SM2 加密,moomoo 侧不存储明文 |
代码位置与服务部署
| 维度 | 说明 |
|---|---|
| 服务名 | ms_stock_bank_transaction |
| 代码目录 | ms_sb_trans_python/ |
| 语言 | Python |
| Proto 文件 | 民生侧提供 .proto 定义文件 |
| 依赖 | SM2 国密库、Protobuf 运行时、SRPC 框架 |
关键代码模块
| 模块 | 职责 |
|---|---|
ms_sb_trans_python/handler/ | 9 个 RPC 方法的请求处理器 |
ms_sb_trans_python/crypto/ | SM2 加解密和签名验签 |
ms_sb_trans_python/proto/ | Protobuf 生成的消息类 |
ms_sb_trans_python/service/ | 业务逻辑(入账、出金、对账) |
ms_sb_trans_python/config/ | 银行连接配置、密钥配置 |
需求变更指引
| 变更需求 | 改动位置 | 说明 |
|---|---|---|
| 新增支持 CNH | checkCurrency() + 银行侧协商 | 需银行侧同步支持 CNH,修改币种校验逻辑 |
| 修改错误码映射 | handler/ 中的错误处理 | 调整 MsBsRejRsn 到用户提示的映射 |
| 修改处理时段 | 时段校验逻辑 | 同步修改前后端时段判断 |
| 新增 RPC 方法 | 银行提供新 proto → 生成代码 → 实现 handler | 需银行侧先发布 proto 文件 |
| 更换 SM2 密钥 | config/ 密钥配置 | 需与银行协调密钥轮换时间窗口 |
| 修改对账规则 | service/reconciliation.py | 调整差异判断阈值或处理策略 |
| 修改自动出金条件 | auto_bs 配置 + AUTO_SETTING_ID | 参考 出金规则手册 |
| 调整限额 | 限额配置(SQL seed) | 修改单笔上限/报警/熔断阈值 |
常见客诉 Top 3
| # | 用户反馈 | 原因 | 客服话术 |
|---|---|---|---|
| 1 | "BST 出金超时" | Socket 连接抖动,回调码 -5 | "出金正在处理中,系统已自动重试,请稍候查看结果" |
| 2 | "为什么民生不支持 CNH" | 民生银证不支持离岸人民币 | "民生银行目前支持港币和美元出入金,暂不支持人民币" |
| 3 | "出金被银行拒绝" | 回调码 -6 或余额不足 | "请确认账户余额充足,如仍被拒请联系客服核实原因" |
监控与告警
关键监控项
| # | 监控项 | 触发条件 | 处理方式 |
|---|---|---|---|
| 1 | SRPC 连接中断(严重) | 与民生银行的 SRPC 连接断开 | 检查网络,自动重连 |
| 2 | SM2 解密失败(高) | 收到的数据无法解密 | 检查密钥配置是否一致 |
| 3 | 入金失败率突增(高) | 单位时间内失败数量超限 | 排查具体错误码分布 |
| 4 | 出金确认超时(高) | CreateWithdrawFutu 后无 WithDrawAck | 人工查询银行侧状态 |
| 5 | 对账差异(中) | 每日对账发现长款/短款 | 运营核对处理 |
| 6 | 柜员异常登录(中) | LoginIn 频率异常或非工作时间登录 | 安全团队排查 |
读完之后
| 我想... | 去看 |
|---|---|
| 看三家 BST 银行的整体对比 | 内银系 BST 总览 |
| 了解招行的二进制 Socket 协议 | 招商银行 CMB |
| 看天星的 REST API 方案 | 天星银行 Airstar |
| 查 BST 错误码 | 统一错误码中心 |
| 看出金自动审批条件 | 出金规则手册 |
| 看所有银行的能力对比 | 银行能力矩阵 |
这个页面有帮助吗?