Skip to content

匯豐 HSBC Pull 模式

本頁說明

講什麼:匯豐的 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 团队使用