Skip to content

Hang Seng

About This Page

What: Hang Seng's deposit statement matching, eDDA/eDDI direct debit, corporate online banking withdrawal business rules, and key differences from HSBC Audience: PMs needing in-depth understanding of Hang Seng integration details Prerequisites: Bank Capability Matrix, HSBC (recommended to read HSBC first; Hang Seng focuses on differences) Reading time: 4 minutes Owner: Deposit Product Manager

Key takeaway: Hang Seng and HSBC share the FPS system but differ significantly in implementation — Hang Seng uses HASE Protocol (non-standard JSON), while HSBC uses standard FPS XML. Recommended to read the HSBC page first, then Hang Seng differences.


Capability Overview

CapabilitySupportedProtocol/Channel
Deposit Statement MatchingMultiple statement types (ATM/GT/WY/ZP/BP)
eDDA AuthorizationeDDA API (internal SRPC, bank-side HTTPS REST)
eDDI Direct DebiteDDI API (internal SRPC, bank-side HTTPS REST)
WithdrawalCorporate online banking (method=hase)
FPS
BST

Hang Seng is the first bank integrated with eDDI on moomoo — project design documents explicitly state "first brokerage to integrate Hang Seng eDDI service."


Key Differences from HSBC

Both Hang Seng and HSBC support eDDA/eDDI, but implementation details differ significantly:

DimensionHSBCHang Seng
eDDA ModelMandate authorizationSimplified model (direct payer/payee)
Authorization requires OTPYes (SMS verification code)No (digital certificate instead)
AuthenticationToken + Basic AuthP12 digital certificate + SHA256-RSA signature
Concurrency ControlToken bucket (optimistic lock, 4/sec)Serialization (pessimistic lock, one at a time)
Bank Return StatusACSC/RJCT/ACCP/ACSPS(Success)/F(Failed)/P(Processing)
Trading Session AwarenessNoneDesigned but currently disabled
Grayscale DeploymentSupported (dual API + dual credentials)
Certificate SourceHongkong Post e-Cert (USB delivery)

Deposit: Statement Types & Matching Rules

Hang Seng deposit statements are divided into 5 types, each with different matching strategies:

Statement TypeMeaningMatching ConditionsAuto-deposit
WYOnline banking transferAmount similar + Name exact, date window -3~+2 days✅ Only auto-deposit type
ATMATM depositAmount exact, by batch time
GTCounter depositAmount exact, by batch time
ZPCheque depositAmount exact + Name optional, date window -3~+2 days
BPBill paymentAmount exact + Bill account number
DefaultOtherAmount similar, date window -3~+2 days

WY Type Auto-Deposit Conditions

Only WY (online banking transfer) type can auto-deposit, requiring all 4 conditions simultaneously:

  1. Deposit notification type is normal deposit (NOTICE_TYPE_NORMAL)
  2. Currency exact match
  3. Amount exactly equal
  4. English name exact match

If any condition is not met, WY statements fall back to "similar matching," requiring manual review.

ATM/GT Batch Time Matching

For ATM and GT types, date matching doesn't look at the statement date, but rather the batch import time (atm_date) — records imported in the same second are treated as the same batch. This is because ATM/counter deposit bank statements may arrive at significantly different times from the actual deposit time.

Amount Tolerance

CurrencyToleranceApplicable Types
HKDCRM - 20 ≤ Statement ≤ CRMWY/Default (during similar matching)
USDCRM - 3 ≤ Statement ≤ CRMWY/Default (during similar matching)

ATM, GT, ZP, and BP types require exact amount match, tolerance does not apply.


eDDA/eDDI Direct Debit

eDDA Authorization: No OTP Required, Digital Certificate Instead

Unlike HSBC, Hang Seng's eDDA doesn't require the user to input an OTP SMS verification code. Instead, it authenticates request legitimacy through digital certificate signing. This means:

  • User authorization flow is shorter (no need to wait for and enter SMS code)
  • But security depends on certificate management — certificate expiration or loss affects the entire eDDI service
Digital Certificate Details
  • Source: Hongkong Post e-Cert (ecert.gov.hk)
  • Format: P12 (PKCS#12), USB delivery
  • Signing Algorithm: SHA256 + RSA-PKCS1_v1_5
  • Signing Steps:
    1. SHA256 hash the request content
    2. Convert hash to uppercase hex string
    3. SHA256 hash the hex string again
    4. Sign with RSA private key
    5. Base64 encode result and place in msgSignature request header

eDDI Request Parameters

Hang Seng eDDI is more simplified than HSBC, not requiring mandate_identification:

ParameterDescriptionExample
payer_bankPayer bank code"024" (Hang Seng)
payer_idPayer account number"123456789001"
payer_namePayer nameUser's name
payee_bankPayee bank code"024" (Hang Seng)
payee_account_numberPayee accountCurrent account (3-6-3) or savings account (3-1-6)
transaction_amountAmount (11 digits, including 2 decimal places)"00000012345" = 123.45
currencyCurrency"HKD"
payment_purpose_codePurpose code01=Fee, 07=E-commerce, 08=Other

eDDI State Machine

Feature Disabled

The new_blank trading session awareness feature has been commented out in code (handles.py L37-42). Currently all requests enter wait_process state regardless of session. The following description is the original design, not current runtime behavior.

Trading Session Awareness (original design): If an eDDI instruction is created during non-Hong Kong stock trading session (e.g., nighttime), it won't be sent to the bank immediately, but enters new_blank state waiting for the trading session to begin. This is a Hang Seng-unique feature; HSBC has no such restriction.

Bank Return Status Codes

Status CodeMeaningSystem Action
SDebit successfulend_ok, create deposit flow
FDebit failedend_reject, record failure reason
PProcessingpending, continue querying

Channel Interface Overview

DimensionDescription
Protocol TypeHTTPS REST + P12 digital certificate signing
AuthenticationHongkong Post e-Cert (P12 PKCS#12 + SHA256-RSA signing)
Bank Code"024"
Concurrency ModelSerialization (pessimistic lock, one request at a time)
Trading Session AwarenessDesigned but currently disabled (code commented out)

eDDI Request Fields Complete Table

EDDIProcedure (Hang Seng eDDI format) complete fields:

FieldTypeDescriptionValues/Format
payer_bankstringPayer bank code"024"=Hang Seng, or other bank codes
payer_idstringPayer IDAccountNumber (e.g. "123456789001") or CustomerID (e.g. "012N18020900000202")
payer_namestringPayer namee.g. "Logistic Company A"
debtor_referencestringPayer referencee.g. "Shipping Fee"
transaction_amountstring(11)Amount (11 digits zero-padded, last 2 are cents)"00000012345" = 123.45 HKD
payee_bankstringPayee bank code"024"
payee_account_numberstringPayee accountCurrent account: 3-6-3 format "333666666333", Savings: 3-1-6 format "3331666666"
payer_typestringPayer type"01"=AccountNumber, "02"=CustomerID
currencystringCurrency"HKD"
payment_purpose_codestringPayment purpose code"01"=Charge, "02"=Fee, "03"=Donation, "04"=Rent, "05"=Insurance, "06"=Utility, "07"=E-commerce, "08"=Other
client_transaction_idstringClient transaction IDSystem-generated, e.g. "ABC000123456789"

Response Fields:

FieldDescription
transaction_idHang Seng transaction ID
acknowledgement_idHang Seng acknowledgement ID
error_code"000"=Success, others require developer documentation
error_reasonError description
reject_codeRejection code

Amount Format

Hang Seng eDDI uses an 11-digit zero-padded string, with the last 2 digits being cents:

Actual AmountTransmission FormatDescription
123.45 HKD"00000012345"123.45 x 100 = 12345, zero-pad to 11 digits
10,000.00 HKD"00001000000"10000.00 x 100 = 1000000, zero-pad to 11 digits
0.50 HKD"00000000050"0.50 x 100 = 50, zero-pad to 11 digits

Conversion rule: Multiply decimal amount by 100, convert to integer, then left-pad with zeros to 11 characters.

Account Number Format

Hang Seng bank account numbers have two formats depending on account type:

Account TypeFormatStructureExample
Current Account3-6-3BBB-AAAAAA-CCC"333666666333"
Savings Account3-1-6BBB-T-AAAAAA"3331666666"

The system automatically determines account type based on the account number length.

Bank Error Codes (Complete Table)

Error CodeMeaningTypeHandling
000SuccessNormal processing
BRC_8I1Insufficient balanceBusinessNotify user to top up
BRC_8RWAuthorization issueBusinessRe-authorize
BRC_8RZAccount abnormalBusinessContact bank
FP2414Electronic authorization not foundAuthorizationRe-sign
FP2415eDDA not activatedAuthorizationWait for activation
FP2416eDDA expiredAuthorizationRe-sign
FP2417Exceeded eDDA limitAuthorizationIncrease limit
CAC_018Bank service unavailableSystemAuto retry
CAC_021Bank service unavailableSystemAuto retry
CAC_022Duplicate transactionIdempotencyTrack as pending
CAC_998Bank timeoutSystemAuto retry
CAC_999Bank timeoutSystemAuto retry
BRC_8RKBank service unavailableSystemAuto retry
BRC_8RMBank service unavailableSystemAuto retry
Other CAC_*Other rejectionsBusinessImmediately reject

Error Code Classification

  • BRC prefix: Bank Business Return Code, divided into retryable (8RK/8RM) and non-retryable (8I1/8RW/8RZ)
  • FP prefix: eDDA authorization-related errors, usually requiring user re-signing or waiting for activation
  • CAC prefix: Channel Access Code (communication errors), most are auto-retryable; CAC_022 is a duplicate transaction requiring special handling

moomoo Matching Rules (HangSengMatch) — By Statement Type

The system routes to different matching branches based on Hang Seng statement type codes, each with different matching strictness:

Statement TypeCodeMatching Rules (Amount / Name / Date)Auto-deposit
Online Banking (WY)WYAmount exact+tolerance, name exact match, standard window (-3~+2 days)✅ Only auto-deposit type
ATMATMAmount exact, batch time (atm_date)
Counter (GT)GTAmount exact, batch time (atm_date)
Cheque (ZP)ZPAmount exact, date window (-3~+2 days)
Bill (BP)BPAmount exact, bill account verification

WY Auto-Deposit 4 Conditions (all must be met for auto-deposit):

  1. notice_type = NOTICE_TYPE_NORMAL (normal deposit notification)
  2. Currency exact match
  3. Amount exactly equal (stricter than assisted matching, doesn't use tolerance logic)
  4. English name exact match

ATM/GT "Batch Time Matching" explanation: Doesn't look at the statement date field, but rather atm_date — records imported in the same second are treated as the same batch. This is because ATM/counter deposit bank statements may arrive at significantly different times from the actual deposit time, making import batch time more reliable.

Serialization Control

Hang Seng requires one eDDI request at a time — no concurrency. The system implements serialization using InnoDB row locks:

ParameterDescription
Lock TypeInnoDB row-level pessimistic lock (UserLock table)
Lock GranularityOne request at a time
Lock Identifierselnum=886 (default)
Grayscale Lockselnum_gray / selnum_formal locked separately

Why does Hang Seng need serialization while HSBC doesn't? Hang Seng's eDDI interface doesn't support concurrent requests — if two debits arrive simultaneously, the bank returns an error. So the system must queue them one by one. HSBC supports a degree of concurrency (rate controlled via token bucket).

Grayscale Deployment

Hang Seng eDDI supports grayscale release, allowing some users to use the new version interface:

DimensionGrayscale EnvironmentProduction Environment
API Endpointddi_url_grayddi_url
Credentialsgray_usrname / gray_pswusername / password
Certificategray_profile_idprofile_id
Serial Lockselnum_grayselnum_formal
Routing RulesGrayscale user list + user_id moduloDefault

Withdrawal: Corporate Online Banking

Hang Seng withdrawal uses corporate online banking batch remittance, with method code hase.

DimensionDescription
Method CodeTRANSFER_METHOD_HASE = 'hase'
ClassificationElectronic bank method (allEBankMethod)
NameHang Seng Online Banking Withdrawal
Automation LevelSemi-automated (requires corporate online banking operation)

Same as HSBC, Hang Seng withdrawal goes through the corporate online banking channel, not eDDI (eDDA/eDDI is only used for deposit direct debit).


Change Guide

Change RequirementModification LocationDescription
Modify WY auto-deposit conditionsHangSengMatch.php → WY branchAdjust name/amount/currency matching conditions
Add new statement typeHangSengMatch.php → switch branchAdd matching rules for new type
Modify amount toleranceMatchRule.phpamountSimilar()Adjust HKD -20 / USD -3 thresholds
eDDI add purpose codesba_hase_eddi request parametersAdd payment_purpose_code
Modify serialization strategysba_hase_edditable_model.pyAdjust UserLock logic
Replace digital certificatesba_hase_eddi/conf/Replace P12 file and password
Modify grayscale ratiosba_hase_eddigray_control.pyAdjust user list/modulo rules
Add retryable error codessba_hase_eddihandles.pyModify hase_bank_service_not_available_map
Modify withdrawal approvalTask.php$stepTemplatesAdjust Hang Seng withdrawal approval template
Certificate renewalHongkong Post e-Cert websiteApply for new certificate, replace P12 file

Common Customer Complaints Top 3

#User FeedbackCauseCS Script
1"eDDA debit failed"BRC_8I1 insufficient balance"Please ensure your Hang Seng bank account has sufficient balance and try again"
2"eDDA suddenly stopped working"Consecutive insufficient balance → bank auto-cancels authorization"Your eDDA authorization may have been cancelled by the bank, please re-sign the eDDA authorization"
3"Amount debited differs from application"Bank service fee deduction"Cross-bank transfers may incur service fees, actual debit amount is subject to bank charges"

Monitoring & Alerts

Alert ItemTrigger ConditionSeverityHandling Steps
eDDI concurrent lock conflictInnoDB row lock wait timeoutMediumCheck sba_hase_eddi concurrency config, reduce simultaneous debits
BRC_8I1 consecutive alertsSame user multiple insufficient balanceMediumRemind user to top up in advance, consecutive occurrences may cause auto-cancellation of authorization
Web notification reception failureHang Seng web notification callback failureHighCheck callback endpoint availability, inspect HTTP status codes
Bank service unavailableCAC_018/021/998/999MediumSystem auto-delays retry; contact Hang Seng tech support if persistent

After Reading

I want to...Go to
Compare HSBC's eDDA/eDDI differencesHSBC
Understand the full matching engine logicMatching & Auto-Deposit
Check eDDA/eDDI error codesUnified Error Code Center
See Hang Seng's position among all banksBank Capability Matrix
Understand eDDA/eDDI's role in the architectureSystem Architecture & Data Flow
Was this page helpful?

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