Skip to content

汇丰 HSBC

本页说明

讲什么:汇丰的 MT910 流水接入、eDDA/eDDI 入金代扣、企业网银出金的完整业务规则与渠道侧接口字段 适合谁:需要深入了解汇丰对接细节的产品经理、对接开发 前置阅读银行能力矩阵预计阅读:15 分钟 负责人:入金产品经理

核心要点:汇丰是唯一同时支持三种入金方式(MT910 Push、eDDA/eDDI Pull、企业网银出金)的银行,也是手续费逻辑最复杂的——容差需覆盖 HKD 65 / USD 14 的手续费扣减。


能力总览

能力支持情况协议/通道核心服务
入金流水采集MT910 (SWIFT 报文)hsbc_bank_flow_service (Python)
eDDA 授权签约eDDA API (SRPC)sba_hsbc_eddi proxy (Python)
eDDI 入金代扣eDDI API (SRPC)sba_hsbc_eddi worker (Python)
出金企业网银批量汇款method=hsbc
FPS
银证 BST

汇丰是唯一同时支持"三种入金方式"的银行:MT910 流水采集(用户主动转账)+ eDDA/eDDI 代扣(系统自动扣款)+ 企业网银出金。


渠道接口概览

汇丰与 moomoo 之间共有三套接口系统,各自独立运行:

#接口系统协议方向用途服务
1MT910 SWIFT 报文SFTP + GPG 加密汇丰 → moomoo入金流水采集(用户主动转账后银行推送到账通知)hsbc_bank_flow_service
2eDDA/eDDI APIREST API (SRPC 封装)moomoo ↔ 汇丰代扣入金(eDDA 签授权 + eDDI 执行扣款)sba_hsbc_eddi
3企业网银网银批量文件moomoo → 汇丰出金(批量汇款)method=hsbc

三套系统之间互不依赖:MT910 处理用户主动转账的流水,eDDA/eDDI 处理系统自动代扣,企业网银处理出金。唯一的交叉点是匹配引擎——当入金方式为 eDDI 代扣时,MT910 流水匹配会主动跳过该笔申请。


渠道侧接口详情

MT910 报文完整字段解析

MT910 (Confirmation of Credit) 是 SWIFT 标准的贷记确认报文。汇丰通过 SFTP 推送加密的 MT910 文件,moomoo 解密后逐条解析。

完整字段映射

SWIFT 标签字段名描述提取规则
:20:txn_ref_no交易参考号(文件内唯一)完整值 → short_transaction_id
:21:related_ref关联参考号可选,完整值
:25:account_id银行账号标识完整账号 → bank_account
:32A:date_ccy_amount日期 + 币种 + 金额见下方解析规则 → date + ccy + credit
:50K:ordering_customer汇款人姓名和账号第 1 行 → 账号,第 2+ 行 → 姓名(去前缀) → customer_account + en_name
:52A: / :52D:ordering_institution汇款银行BIC 代码或多行地址 → remarks(拼接)
:56A: / :56D:intermediary中间行(跨境汇款)可选,BIC 或多行
:72:sender_to_receiver交易详情/附言自由文本,≤512 字符 → remarks(拼接)

:32A: 解析规则

:32A: 是入金的核心字段,包含日期、币种、金额三部分,格式为连续字符串:

格式: YYMMDDCCCNNNN.NN
示例: 250827HKD50000.00
部分位置规则示例
日期前 6 位"20" + YYMMDD → 标准日期2508272025-08-27
币种第 7-9 位ISO 4217 三字符代码HKD / USD / CNY
金额第 10 位起至末尾decimal,含小数点50000.00

支持币种:HKDUSDCNY

:50K: 姓名清洗规则

:50K: 字段通常包含多行信息,解析时需要做姓名清洗:

内容处理
第 1 行通常是账号提取为 customer_account
第 2 行及之后汇款人姓名拼接为 en_name

姓名清洗——去除以下前缀后再用于匹配:

前缀说明
MR先生
MRS太太
MISS小姐
MS女士

示例::50K: 内容为 123456789\nMR CHAN TAI MAN,解析结果:customer_account=123456789en_name=CHAN TAI MAN

SFTP 配置

参数说明
协议SFTP(SSH File Transfer Protocol)
SSH 密钥RSA 密钥对
公钥位置src/conf/HSBC_SSP_PREPROD_SFTP_KEY.pub
私钥位置src/conf/id_rsa
GPG 加密必须(所有下载文件均经 GPG 解密)
支持币种HKD, USD, CNY
配置文件sftp_config.ini + parse_flow.ini

去重机制

TransactionReferenceNumber:20: 标签值)去重——同一文件内该值唯一。写入 raw_hsbc_bank_flow 表时,如果该参考号已存在则跳过,避免重复入账。


eDDA API 完整字段

eDDA (Electronic Direct Debit Authorization) 是用户授权 moomoo 从其汇丰账户自动扣款的签约接口。以下为各请求/响应的完整字段定义。

BankAccountInfo(嵌套结构)

eDDA/eDDI 接口中多处使用的银行账户信息结构体:

字段类型必填描述
bank_codestring(3)银行代码。取值 "004" = HSBC,"024" = 恒生
account_identificationstring(12-35)银行账号。取值 汇丰个人账号
currencystring(3)币种。取值 "HKD"
account_scheme_namestring(4)账号类型。取值 "BBAN"(默认)

EDDAApplyReq(申请授权请求)

字段类型必填描述
req_idstring(1-32)请求 ID。全局唯一
merchant_request_identificationstring(1-30)商户注册 ID。moomoo 侧生成
creditor_referencestring(1-35)DDA 标识符。关联 eDDA 授权
ultimate_debtor_namestring(1-140)最终付款人姓名。用户真实姓名
debtor_namestring(1-140)付款人姓名。同上或代理人姓名
debtor_accountBankAccountInfo付款人银行账户。用户的汇丰账户
creditor_namestring(1-140)收款人姓名。moomoo 公司名称
creditor_accountBankAccountInfo收款人银行账户。moomoo 的汇丰收款账户
debtor_private_identificationstring(1-12)HKID 或护照号。用户身份证件号码
debtor_private_identification_scheme_namestring(4)证件类型。取值 "HKID""NIDN"
debtor_mobile_numberstring手机号。用于接收 OTP
maximum_amount_currencystring(3)限额币种。取值 "HKD"
maximum_amountstring(≤18)最大扣款金额。取值 "99999999.00" = 无限制
frequency_typestring(≤4)扣款频率类型。取值 "MNTH" = 每月 / "ADHO" = 按需
duration_from_datestring授权起始日期。NULL = 立即生效
duration_to_datestring(10)授权结束日期。NULL = 永久有效
otp_hold_indicatorbool是否需要 OTP 验证。汇丰同行 = true
sms_language_codestring(≤10)OTP 短信语言。取值 "eng" / "zh-s" / "zh-t"

otp_hold_indicator 说明

otp_hold_indicator=true 时,汇丰会在 Apply 阶段暂停流程,等待用户输入 OTP 验证码后才继续。这是汇丰同行转账的安全要求。

EDDAApplyRsp(申请授权响应)

字段类型描述
resp_codestring银行响应码(成功/失败)
mandate_identificationstringDDA 参考 ID(后续 OTP 确认和扣款时使用)
otp_identification_numberstringOTP 标识符(用于 OTPConfirm 请求)
otp_mobile_numberstring掩码手机号(如 ****1234,用于前端展示)
mandate_statusstring授权状态(Apply 阶段通常为待确认)
reject_reason_listRejectReasonList拒绝原因列表(Apply 失败时返回)

OTPConfirmReq(OTP 确认请求)

字段类型必填描述
req_idstring(1-32)请求 ID
mandate_identificationstringDDA 参考(来自 EDDAApplyRsp)
creditor_accountBankAccountInfo收款方账户(moomoo 账户)
otp_identification_numberstringOTP ID(来自 EDDAApplyRsp)
otp_passwordstring用户输入的短信验证码

OTP 确认成功后,eDDA 授权进入银行审核阶段,通过 EDDAEnquiry 轮询最终状态。


eDDI API 完整字段

eDDI (Electronic Direct Debit Instruction) 是在 eDDA 授权完成后,moomoo 向汇丰发起的实际扣款请求。

EDDILaunchReq(发起扣款请求)

字段类型必填描述
req_idstring(1-32)请求 ID。全局唯一
merchant_instruction_identificationstring(≤35)DDI 请求 ID。moomoo 侧生成的扣款指令 ID
mandate_identificationstring(≤35)DDA 参考。与 creditor_reference 二选一
debtor_namestring(≤140)付款人姓名。用户姓名
debtor_accountBankAccountInfo付款人账户。用户的汇丰账户
creditor_accountBankAccountInfo收款方账户。moomoo 的汇丰收款账户
creditor_referencestring(≤35)收款方参考。与 mandate_identification 二选一
instructed_amount_currencystring(3)扣款币种。取值 "HKD"
instructed_amountstring(≤18)扣款金额。如 "10000.00"
remittance_informationstring(≤140)汇款信息。建议留空
sms_language_codestring(≤10)短信语言。扣款通知语言

mandate_identification 与 creditor_reference

这两个字段二选一即可定位 eDDA 授权。mandate_identification 是银行返回的 DDA 参考 ID,creditor_reference 是 moomoo 侧的 DDA 标识符。实际实现中优先使用 mandate_identification

EDDIRsp(扣款响应)

字段类型描述
payment_statusstring交易状态:ACSC/RJCT/ACCP/ACSP
resp_codestring银行响应码
reject_reason_listRejectReasonList拒绝原因列表
transaction_idstring银行交易 ID
statusstring"return_ok" = 银行已返回 / "empty" = 银行尚未返回

status="empty" 时,表示银行尚未处理完成,需要通过 EDDIEnquiry 接口继续轮询。

EDDIEnquiry(查询扣款结果)

字段类型必填描述
req_idstring(1-32)请求 ID
merchant_instruction_identificationstring(≤35)DDI 请求 ID(与 Launch 时一致)
creditor_accountBankAccountInfo收款方账户

查询返回的 payment_status 字段决定扣款的最终走向,具体状态码含义见下方"eDDI 状态机"章节。


eDDI 错误码

当 eDDI 扣款被银行拒绝(payment_status=RJCT)时,reject_reason_list 中会返回具体的错误码:

错误码含义处理建议
MPP02020eDDA 已取消或不存在引导用户重新签署 eDDA 授权
MPP02021付款账户已关闭通知用户银行账户已失效
MPP02022超过 eDDA 限额引导用户在汇丰 App 提升 eDDA 限额
MPP02038eDDA 授权已休眠(Dormant)需联系汇丰银行重新激活
MPP02039eDDA 已过期引导用户重新签署 eDDA 授权
MPP05000超过账户取款限额建议用户降低入金金额或联系银行
MFD10007重复交易系统侧已处理过,无需重试

更多错误码

完整的 eDDA/eDDI 错误码列表见 统一错误码中心


入金:MT910 流水采集

什么是 MT910

MT910 是 SWIFT 标准银行报文格式,银行用它来通知企业"有一笔钱到账了"。汇丰通过 MT910 报文把交易信息推送给 moomoo。

2024 年 7 月起,汇丰已升级为实时推送(之前是每日批次文件),入金响应速度显著提升。

数据流

文件处理流程

步骤操作说明
1SFTP 拉取从汇丰 SFTP 服务器按日期拉取文件
2下载到本地存入 mt910_files/YYYYMM/ 目录
3GPG 解密用私钥解密,生成 plain_ 前缀的明文文件
4解析报文正则匹配 SWIFT 标签,提取字段
5写入数据库存入 raw_hsbc_bank_flow,按交易参考号去重
6转换为流水调用 resolve_bank_flows() 写入流水系统

处理频率:每天执行,处理昨天和今天的文件。

文件命名规则

MT910.<富途账号>.<汇丰商户码>.<时间戳>.TXT 例如:MT910.741071039201.PC000001581.20210301120000.TXT

监控指标
指标 ID含义
1002976脚本启动
936360异常错误
936363-365ListFiles 操作统计
936366-368GetFiles 操作统计
604339重复交易
604340数据库写入失败

eDDA/eDDI 入金代扣

eDDA 和 eDDI 是什么

概念全称作用
eDDAElectronic Direct Debit Authorization用户授权 moomoo 从汇丰账户自动扣款
eDDIElectronic Direct Debit Instructionmoomoo 向汇丰发出扣款指令,从用户账户扣钱

简单说:eDDA 是"签授权",eDDI 是"执行扣款"。用户先签 eDDA 授权,之后每次入金时系统自动发 eDDI 扣款。

eDDA 授权流程

eDDA 授权三步走:

步骤RPC 方法用户操作银行操作
1. 申请授权EDDAApply填写银行账号信息发送 OTP 短信到用户手机
2. OTP 确认OTPConfirm输入收到的短信验证码验证 OTP
3. 查询状态EDDAEnquiry等待返回授权状态

eDDI 扣款执行

eDDI 是系统在用户入金时自动执行的扣款。共有 三种入金类型

类型枚举值说明
FUND_HOLD11基金定投,同时冻结入金
STOCK_HOLD21股票定投,同时冻结入金
FUND_PURCHASE_HOLD31基金申购,同时冻结入金

还有三种不冻结的基础类型:FOUNDING_AIP(1)=基金定投、STOCK_MP(2)=股票定投、FUND_PURCHASE(3)=购买基金。

eDDI 状态机

eDDI Procedure 完整状态定义:

状态含义来源后续转换
new扣款指令已创建系统初始化wait_process
wait_process初始化完成,准备发送系统处理pending / end_ok / end_reject
pending已发送到银行,等待确认Launch 返回 status="empty"ACCP/ACSPend_ok / end_reject / repairing
end_ok扣款成功银行返回 ACSC终态,创建入金流水
end_reject银行拒绝银行返回 RJCT终态,记录拒绝原因
repairing异常需人工干预系统判定异常pending(人工修复后重试)

银行返回的扣款状态码:

状态码全称含义系统动作
ACSCAccepted Settlement Completed扣款成功end_ok,创建入金流水
RJCTRejected银行拒绝end_reject,记录拒绝原因
ACCPAccepted Clearing in Progress清算处理中pending,继续轮询
ACSPAccepted Settlement in Progress结算处理中pending,继续轮询
empty银行尚未返回继续轮询

轮询与重试机制

eDDI 执行后不是立刻得到结果,需要轮询银行:

参数说明
正常轮询间隔1-4 秒随机避免固定频率冲击银行
高峰期轮询间隔1-19 秒随机高峰期拉长间隔
高峰时段07:00-07:10可配置
重试阈值 13 次超过后触发告警
重试阈值 210 次超过后升级告警
HTTP 429 处理自动重试银行限流时排队重试

速率限制(Token Bucket)

汇丰对 eDDA/eDDI 接口有调用频率限制。系统使用令牌桶机制控制请求速率:

参数
生产环境速率4 个请求/秒
默认速率1 个请求/秒
锁策略乐观锁(基于 timestamp 字段版本校验)
正常轮询间隔1-4 秒随机
高峰轮询间隔1-19 秒随机(07:00-07:10)
重试阈值 13 次 → 触发告警
重试阈值 210 次 → 升级告警

为什么用乐观锁? 早期用悲观锁(排他锁),生产环境出现过锁超时(默认 50 秒),导致请求线程堆积。改为乐观锁后,通过 timestamp 字段做版本校验,避免了锁等待问题。

令牌桶工作原理
  1. 守护进程按配置频率(4/秒)往 token_bucket 表添加令牌
  2. 每个请求尝试消费一个令牌:UPDATE ... SET token=token-1 WHERE token>0 AND timestamp=@version
  3. 如果 timestamp 不匹配(乐观锁冲突),重试
  4. 如果 token=0(令牌用完),请求被限流
eDDI 监控指标
指标 ID含义
561904eDDI 初始化
561910扣款成功
561911扣款失败
561912扣款待确认
561913超时重试
561925重试超过 3 次
561926重试超过 10 次
573198重复交易 (MFD10007)
589305HTTP 错误

moomoo 侧适配

MT910 → BankFlow 完整映射

MT910 报文解析后,通过 resolve_bank_flows() 转换为 moomoo 统一的 BankFlow 结构:

MT910 字段SWIFT 标签BankFlow 字段转换规则
txn_ref_no:20:short_transaction_id直接映射,作为去重键
account_id:25:bank_account直接映射
date (from :32A:):32A: 前 6 位date"20" + YYMMDDYYYY-MM-DD
ccy (from :32A:):32A: 第 7-9 位ccyISO 4217 三字符 → 内部币种码
amount (from :32A:):32A: 第 10 位起creditdecimal 字符串 → 金额
ordering_customer 第 1 行:50K:customer_account汇款人银行账号
ordering_customer 第 2+ 行:50K:en_name清洗后的英文姓名
ordering_institution:52A: / :52D:remarks(拼接)BIC 代码或银行名称
sender_to_receiver_info:72:remarks(拼接)附言信息追加到 remarks
bank_type固定值:HSBC
flow_direction固定值:CREDIT(贷方)

匹配规则(HsbcMatch)

汇丰匹配有两层容差——自动入账用严格容差,人工审核用宽松容差:

场景HKD 容差USD 容差触发条件
自动入账CRM - 65 ≤ 流水 ≤ CRMCRM - 14 ≤ 流水 ≤ CRM姓名精确匹配 + 银行账号匹配
人工审核CRM - 420 ≤ 流水 ≤ CRMCRM - 60 ≤ 流水 ≤ CRM姓名相似 + 金额相近

为什么容差是负数方向? 银行转账可能被扣除手续费(如电汇手续费、中间行费用),导致实际到账金额小于用户发起金额。容差只向下开口——流水金额可以比 CRM 金额少(手续费扣减),但不能多。

银行账号匹配的特殊处理

处理说明
去前缀汇丰账号有时会带 3 位银行代码前缀(如 004),系统自动去掉前缀再比较
代码列表004(HSBC)外,还需处理 024(恒生)等关联银行代码
模糊匹配去前缀后长度对齐再逐字符比较

eDDA 入金排除:如果入金申请的方式是 DEPOSIT_METHOD_HSBC_EDDA(eDDI 代扣),则跳过流水匹配引擎——因为 eDDI 有自己的独立入账流程,不需要也不应该与 MT910 流水匹配。

eDDI → 入金流水映射

eDDI 扣款成功(ACSC)后,系统自动创建入金流水,字段来源与 MT910 不同:

BankFlow 字段数据来源说明
short_transaction_idEDDIRsp → transaction_id银行返回的交易 ID
bank_accountEDDILaunchReq → debtor_account用户的汇丰账户
date系统当前日期扣款执行日期
ccyEDDILaunchReq → instructed_amount_currency扣款币种
creditEDDILaunchReq → instructed_amount扣款金额(无手续费扣减)
en_nameEDDILaunchReq → debtor_name付款人姓名
customer_accountEDDILaunchReq → debtor_account.account_identification用户银行账号
deposit_method固定值:DEPOSIT_METHOD_HSBC_EDDA

eDDA 授权状态映射

eDDA 授权在 moomoo 侧维护独立的状态机:

mandate_status(银行)moomoo 侧状态说明
ACTV已生效可正常发起 eDDI 扣款
SUSP已暂停暂时不可扣款,需等待恢复
CANC已取消用户或银行取消授权,需重新签署
EXPR已过期超过 duration_to_date,需重新签署

出金:企业网银

汇丰出金通过企业网银批量汇款,方法码为 hsbc

维度说明
方法码TRANSFER_METHOD_HSBC = 'hsbc'
分类电子银行方法(allEBankMethod
中文名汇丰网银出金
自动化程度半自动(需企业网银操作)
支持币种HKD, USD
审批模板按金额分级,见 Task.php$stepTemplates

注意:汇丰出金走的是企业网银通道,不是 eDDI。eDDA/eDDI 仅用于入金代扣,出金是完全独立的通道。

出金操作流程

步骤操作角色
1系统生成出金批次文件自动
2运营导入企业网银运营人员
3企业网银审批财务审批人
4银行执行汇款汇丰银行
5系统确认出金结果自动/运营

需求变更指引

变更需求改动位置说明
修改自动入账容差HsbcMatch.phpamountSimilarForAuto()调整 HKD -65 / USD -14 阈值
修改人工审核容差HsbcMatch.phpamountSimilar()调整 HKD -420 / USD -60 阈值
新增匹配维度HsbcMatch.phpmatch() 方法添加新的匹配条件
修改银行账号前缀规则HsbcMatch.php → 银行代码数组添加/修改 3 位前缀
新增 eDDI 入金类型EddiDepositType.php添加新枚举值 + SBA 配置
修改令牌桶速率sba_hsbc_eddi token_bucket 守护进程配置调整 frequency 参数
修改轮询间隔sba_hsbc_eddi_worker.ini调整 rush/normal 间隔
eDDA 参数变更sba_hsbc_eddi proxy 层修改授权参数(频率、金额等)
MT910 字段变更hsbc_bank_flow_serviceparse.py修改 SWIFT 标签解析规则
修改 SFTP 配置sftp_config.ini + parse_flow.ini修改服务器/账号/路径
GPG 密钥更换hsbc_bank_flow_service/conf/更新私钥和密码
修改出金审批Task.php$stepTemplates调整 HSBC 出金审批模板
新增 eDDI 错误码处理sba_hsbc_eddi worker → 错误处理逻辑添加新错误码映射
修改 :50K: 姓名清洗规则hsbc_bank_flow_serviceparse.py调整前缀清洗列表

常见客诉 Top 3

#用户反馈原因客服话术
1"eDDA 签约失败"手机号/姓名与汇丰登记不一致"请确认 moomoo 注册姓名和手机号与汇丰银行登记信息一致"
2"验证码过期了"OTP 有效期较短"请重新获取验证码,收到后尽快输入"
3"eDDA 扣款超过限额"超过签约时设置的最大扣款金额"您的扣款金额超过授权限额,请减少金额或联系汇丰银行调整限额"

监控与告警

告警项触发条件严重度处理步骤
MT910 SFTP 连接失败SFTP 文件传输中断🔴 高检查 SFTP 配置和网络连通性,确认 GPG 密钥未过期
eDDI Token Bucket 耗尽每秒 4 Token 限流触发🟡 中检查是否有大量扣款任务堆积,适当降低并发
eDDI 扣款批量超时扣款任务长时间未返回结果🟡 中查看 sba_hsbc_eddi 日志,确认银行侧是否正常
GPG 解密失败MT910 文件无法解密🔴 高确认 GPG 密钥是否过期或被更换,联系汇丰更新

读完之后

我想...去看
对比恒生的 eDDA/eDDI 差异恒生 Hang Seng
了解匹配引擎的完整逻辑匹配与自动入账
查 eDDA/eDDI 错误码统一错误码中心
看汇丰在各银行中的位置银行能力矩阵
了解 eDDA/eDDI 在架构中的角色系统架构与数据流
了解 SBA 编排层如何调度 eDDISBA 资金编排
查看入金流水采集的通用流程流水采集通道
这个页面有帮助吗?

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