ICBC Asia
About This Page
What: ICBC Asia channel-side interface specification + moomoo-side adaptation logic Audience: PMs understanding integration details / developers locating code / operations understanding bank characteristics Prerequisites: Bank Capability MatrixReading time: 8 minutes Owner: Deposit & Withdrawal Product Team
Key takeaway: ICBC Asia is a representative traditional deposit channel — API scheduled pull for statements, supporting only manual withdrawal and wire transfer, no FPS, no BST, no eDDA.
Capability Overview
| Capability | Supported | Protocol/Channel | Core Service |
|---|---|---|---|
| Deposit Statement Collection | ✅ | Bank-Enterprise Direct REST API | icbc_be_relay (Python) |
| Withdrawal | ✅ | Manual withdrawal (operations use corporate online banking) | method=manual |
| FPS Deposit | ✅ | Statement matching → auto-deposit possible | IcbcasiaMatch |
| Online Banking Deposit | ✅ | Statement matching → auto-deposit possible | IcbcasiaMatch |
| Remittance Deposit | ✅ | Statement matching → auto-deposit possible | IcbcasiaMatch |
| ATM Deposit | ⚠️ | Statement matching → no auto-deposit | Manual review |
| Cheque Deposit | ⚠️ | Statement matching → no auto-deposit | Manual review |
| eDDA/eDDI | ❌ | — | — |
| BST | ❌ | — | — |
| Identifier | Value |
|---|---|
| IMPORT_BANK_ID | 10 (ICBCASIA) |
| TransType | 202 |
| Matching Command | match:main icbc-new (every 3 minutes) |
ICBC Asia has relatively mature interfaces among Chinese-funded banks — collecting statements in real-time via Bank-Enterprise Direct API, supporting auto-deposit for FPS/online banking/remittance. Withdrawal is manual mode, with operations staff operating in corporate online banking.
Channel Interface Overview
ICBC Asia connects through the "Bank-Enterprise Direct Connection" protocol, which is a standardized interface solution for enterprise customers among Chinese-funded banks.
| Dimension | Description |
|---|---|
| Transport Protocol | HTTPS REST |
| Data Format | JSON |
| Authentication | RSA2 signing (private key signs biz_content, bank public key verifies) |
| Pagination | cursor-based (next_tag field) |
| Core Service | icbc_be_relay (Python) |
RSA2 Signing Mechanism
Every request requires RSA2 signature verification, with bidirectional verification ensuring data integrity:
msg_id generation rule: "futu" + millisecond timestamp + 2 random digits, ensuring global uniqueness per request.
Channel-Side Interface Details
Statement Query Interface
This is ICBC Asia's core interface, used to pull transaction statements for a specified date range and currency.
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
app_id | string | ✅ | Application identifier. Production environment configuration |
msg_id | string | ✅ | Unique transaction number. e.g. "futu" + millisecond timestamp + 2 random digits |
sign_type | string | ✅ | Signature type. Value "RSA2" |
sign | string | ✅ | Signature value. RSA private key signature of biz_content |
timestamp | string | ✅ | Request time. Format "YYYY-MM-DD HH:MM:SS" |
biz_content.account_no | string | ✅ | Bank account number. moomoo's receiving account at ICBC |
biz_content.bank_code | string | ✅ | Bank code. ICBC Asia bank code |
biz_content.begin_date | string | ✅ | Start date. Format "YYYYMMDD" |
biz_content.end_date | string | ✅ | End date. Format "YYYYMMDD" |
biz_content.currency | string | ✅ | Currency. Values HKD / USD / CNH |
biz_content.min_amount | string | ❌ | Minimum amount. Filter small transactions |
biz_content.trans_code | string | ✅ | Transaction type code. Hardcoded (production-specific value) |
biz_content.cis | string | ✅ | Client system ID. Hardcoded |
biz_content.login_id | string | ✅ | Login ID. Hardcoded |
biz_content.next_tag | string | ❌ | Pagination marker. Empty for first request; pass bank-returned next_tag value for subsequent requests |
Response Parameters
| Field | Type | Description |
|---|---|---|
debit_amount | decimal | Debit amount (unit: cents, no decimal point) |
credit_amount | decimal | Credit amount (unit: cents, no decimal point) |
balance | decimal | Balance after transaction (unit: cents) |
th_currency | string | Currency (determined by account type) |
busi_time | string | Transaction time HHMMSS (used for sorting and deduplication) |
remarks | string | Transaction remarks (contains transaction type, payer information) |
date | string | Transaction date YYYYMMDD |
time | string | Time HHMMSS |
Amount Unit Note
ICBC Asia returns amounts in cents without decimal points. For example, 100 yuan is actually returned as 10000. The system must divide by 100 when parsing to convert to yuan. This differs from most banks that directly return yuan/decimal format, and is the most common source of errors in ICBC integration.
Error Codes
| Error Code | Meaning | Handling |
|---|---|---|
622394 | HTTP request error | Auto retry, log |
625565 | Public key signature verification failed | Check RSA key pair correctness, verify key files |
622395 | msg_id mismatch | Technical investigation, check request/response msg_id consistency |
622396 | Abnormal return_code | Check specific error information in bank response body |
Error Code Configuration Location
Monitor metric IDs in icbc_be_relay correspond one-to-one with error codes, reporting to the monitoring system when triggered. See Unified Error Code Center.
Data Flow
Database Tables
| Table | Purpose | Key Fields |
|---|---|---|
raw_icbc_bank_flow | Raw bank response, fully preserved | Full JSON returned by bank |
icbc_bank_flow | Parsed standardized statements | credit/debit (converted to yuan), date, time, remarks |
icbc_balance | Balance snapshot (opening/closing balance) | balance, date |
icbc_be_next_tag | Pagination marker, records last pull position | next_tag, account_no, currency |
moomoo-Side Adaptation
Statement Standardization Mapping
Conversion from ICBC Asia raw fields to moomoo unified BankFlow format:
| Bank Raw Field | BankFlow Field | Conversion Logic |
|---|---|---|
credit_amount | credit | Cents → Yuan (divide by 100) |
debit_amount | debit | Cents → Yuan (divide by 100) |
th_currency | ccy | Mapped by account type (HKD/USD/CNH) |
date | date | Direct mapping YYYYMMDD |
busi_time | time | Direct mapping HHMMSS |
remarks | remarks | Direct mapping (contains transaction type labels) |
Special Processing Rules
Amount Unit Conversion
ICBC Asia is currently the only bank returning amounts in cents. All amount fields (credit_amount, debit_amount, balance) must be divided by 100 before writing to the icbc_bank_flow table.
Card Number Processing
ICBC Asia card numbers are 12 digits total, where the last digit is a currency identifier. When matching user bank card numbers, the last digit must be removed before comparison.
ICBC card number: 123456789010 (12 digits, last digit "0" is currency identifier)
Matching uses: 12345678901 (remove last digit, take first 11)Card Number Prefix Processing
Additionally, matching automatically removes 00 prefix — ICBC card number format is special, and some statements have card numbers padded with 00 prefix.
Deduplication Logic
Deduplication is based on the following four-field combination; statements with the same combination are only stored once:
Dedup key = date + time + remarks + credit + debitMatching Rules (IcbcasiaMatch)
ICBC Asia's matching logic is divided into sub-account path and normal path — two completely different pipelines.
Dual-Path Routing
| Path | Trigger Condition | Auto-deposit? | Amount Tolerance & Special Requirements |
|---|---|---|---|
| Sub-account path | Statement from sub-account | ❌ Assisted match only | Sub-account SDK verification |
| Normal path — Exact | Amount exact + Name EN+CN dual match | ✅ | 0 (FPS) / -20 HKD / -3 USD. Card number (remove last digit) + date window |
| Normal path — Assisted | Amount within tolerance + Name similar | ❌ | -20 HKD / -3 USD. Card number (remove last digit) + date window |
Full Match Conditions (Auto-deposit eligible)
All conditions must be met simultaneously:
| Dimension | Rule | Description |
|---|---|---|
| Currency | Exact match | Statement currency = Application currency |
| Amount | CRM - 20 ≤ Statement ≤ CRM (HKD/CNH); CRM - 3 ≤ Statement ≤ CRM (USD) | FPS requires exact amount match (tolerance=0) |
| Name | EN and CN name dual verification both pass | Stricter than other banks |
| Date Window | -3 ~ +2 days | Standard daySimilar window |
| Card Number | Exact match after removing last digit | ICBC 12-digit card number special processing |
Assisted Match Conditions (Requires manual review)
| Dimension | Rule | Description |
|---|---|---|
| Currency | Exact match | — |
| Amount | CRM - 20 ≤ Statement ≤ CRM (HKD/CNH); CRM - 3 ≤ Statement ≤ CRM (USD) | Same tolerance as auto-deposit |
| Name | Similar match (nameSimilar) | Non-exact match can still enter manual review |
| Date Window | -3 ~ +2 days | — |
Matching Capability by Deposit Method
| Deposit Method | Statement Label (Chinese label in remarks) | Auto-deposit | Description |
|---|---|---|---|
| FPS Transfer | FPS 轉賬 | ✅ | Amount must match exactly (tolerance=0) |
| Online Banking Transfer | 網上轉賬存款 | ✅ | Standard tolerance allowed |
| Remittance Deposit | 匯款存入 | ✅ | Standard tolerance allowed |
| ATM Deposit | ATM-related | ❌ | Assisted match only, requires manual review |
| Cheque Deposit | Cheque-related | ❌ | Assisted match only, requires manual review |
| Sub-account Transfer | Sub-account path | ❌ | Assisted match only, via sub-account SDK verification |
Amount Tolerance Summary
| Currency | Auto-deposit / Assisted Match Tolerance | ATM Special Tolerance | Remittance Special Tolerance (USD) |
|---|---|---|---|
| HKD/CNH | CRM - 20 ≤ Statement ≤ CRM | CRM - 10 ~ CRM | — |
| USD | CRM - 3 ≤ Statement ≤ CRM | — | CRM - 55 ~ CRM |
Why does ATM have special tolerance? ATM deposits may incur small service fees (approximately 10 HKD), so ATM tolerance is set to CRM-10 ~ CRM.
Why is USD remittance tolerance larger? USD cross-bank remittances pass through intermediary banks, which may deduct up to 55 USD in fees, making USD remittance tolerance much larger than local transfer's -3.
Corresponding Code
deposit/src/app/Business/Match/IcbcasiaMatch.php — contains sub-account path routing and normal path complete matching logic. Statement type is routed to different rules via regex matching of Chinese labels in the remarks field.
Balance Continuity Tracking
The system tracks ICBC account balance changes daily to ensure statement data completeness:
Verification Formula
balance[today_start] + SUM(credit - debit) == balance[today_end]Sorting and Value Extraction
- Daily statements sorted by
busi_time ASC - First record's balance = day's opening balance
- Last record's balance = day's closing balance
- If equation doesn't hold → statement data is incomplete, trigger alert
Date Switchover Logic
| Time | Pull Strategy | Description |
|---|---|---|
| 00:00 ~ 00:35 | Pull previous day's data | Bank end-of-day settlement may be delayed, ensure previous day data is complete |
| After 00:35 | Pull current day's data | Switch to current day real-time statements |
Why 00:35? ICBC Asia's end-of-day batch processing usually completes around 00:30, with a 5-minute buffer before switching to the new day.
Async Tasks
| Task | Trigger Method | Description |
|---|---|---|
icbc_be_relay | Cron scheduled | Periodically pull statements from ICBC API, store in raw and parsed tables |
| Daily completion | 00:00:10 | Pull previous day's complete statements every midnight, ensure no gaps |
match:main icbc-new | Every 3 minutes | Execute ICBC statement matching, attempt auto-deposit or assisted match |
Withdrawal
ICBC Asia currently doesn't support API-automated withdrawal, using manual processing.
| Dimension | Description |
|---|---|
| Method Code | manual (manual withdrawal) |
| Operation Method | Operations staff logs into ICBC corporate online banking, manually executes transfers |
| Follow-up Time | 3 days (longer than standard 1 day) |
| Reason for Longer Follow-up | ICBC Asia's statement arrival speed is slower; bank processing and statement reflection after withdrawal needs more time |
Deposit Timeout Rules
After a user submits a deposit application, the system sets notification and rejection timeout days. After timeout, the system notifies the user or auto-rejects.
| Deposit Method | Same Bank (Notification days + Rejection days) | Cross-bank HKD/CNH | Cross-bank USD |
|---|---|---|---|
| FPS | 1 day + 1 day | 2~4 days + 1 day | 1~4 days + 1 day |
| Online Banking Transfer | 1 day + 1 day | 2~4 days + 1 day | Same as left |
| ATM / Cheque | 2 days + 1 day | 2 days + 1 day | Same as left |
"Notification days + Rejection days" meaning: If no matching statement found after notification days → system notifies user to confirm; if still no match after rejection days → system auto-rejects the deposit application.
Bilateral Feature Matrix
| Function | Channel-Side (ICBC Asia) | moomoo-Side | Status |
|---|---|---|---|
| Statement Query | Bank-Enterprise Direct REST API + RSA2 signing | icbc_be_relay scheduled pull | ✅ Live |
| Pagination | next_tag cursor mechanism | icbc_be_next_tag table records progress | ✅ Live |
| Balance | Each transaction returns balance | icbc_balance table + continuity verification | ✅ Live |
| FPS Deposit | Statement label FPS 轉賬 | Exact match → auto-deposit | ✅ Live |
| Online Banking Deposit | Statement label 網上轉賬存款 | Exact match → auto-deposit | ✅ Live |
| Remittance Deposit | Statement label 匯款存入 | Tolerance match → auto-deposit | ✅ Live |
| ATM Deposit | ATM transaction statements | Assisted match → manual review | ⚠️ No auto-deposit |
| Cheque Deposit | Cheque transaction statements | Assisted match → manual review | ⚠️ No auto-deposit |
| Withdrawal | Corporate online banking manual operation | method=manual | ✅ Manual mode |
| eDDA/eDDI | Not supported | — | ❌ |
| BST | Not supported | — | ❌ |
Change Guide
If you need to modify ICBC Asia-related business rules, here are the specific modification locations:
| Change Requirement | Modification Location | Description |
|---|---|---|
| Modify statement pull frequency | icbc_be_relay cron configuration | Adjust scheduled task interval |
| Replace RSA key | icbc_be_relay/conf/API_GATEWAY.pub | Replace public key file, restart service |
| Modify date switchover time | relay.py → 00:35 judgment logic | Adjust end-of-day switchover threshold |
| Add currency query | relay.py → biz_content.currency enum | Add new currency and configure corresponding receiving account |
| Modify matching amount tolerance | IcbcasiaMatch.php → localTransferSimilarAmount | Adjust HKD -20 / USD -3 thresholds |
| Modify FPS exact match rules | IcbcasiaMatch.php → FPS branch | Adjust FPS tolerance (currently=0) |
| Modify matching date window | IcbcasiaMatch.php → daySimilar | Adjust -3~+2 day parameters |
| Add auto-deposit-eligible statement types | IcbcasiaMatch.php → remarks regex | Add new Chinese label matching rules |
| Modify card number processing rules | IcbcasiaMatch.php → card number comparison logic | Adjust remove-last-digit/remove-prefix strategy |
| Modify matching frequency | deposit/doc/crontab.sh → match:main icbc-new | Adjust cron interval |
| Modify withdrawal follow-up days | Withdrawal configuration → manual method parameters | Adjust 3-day follow-up period |
Common Customer Complaints Top 3
| # | User Feedback | Cause | CS Script |
|---|---|---|---|
| 1 | "ICBC deposit not arrived" | Bank-Enterprise Direct query timeout or statement not collected | "Your deposit is being processed, please wait patiently for matching" |
| 2 | "Deposit amount is wrong" | ICBC uses cents unit, conversion differences possible | "The system is verifying the amount, we will process any discrepancies promptly" |
| 3 | "Why can't I withdraw via ICBC" | ICBC only has deposit integration, no withdrawal support | "ICBC currently only supports deposits, please use other bank channels for withdrawals" |
After Reading
| I want to... | Go to |
|---|---|
| See ICBC's position among all banks | Bank Capability Matrix |
| Understand the full matching engine logic | Matching & Auto-Deposit |
| Look up TransType and Bank ID reference | Deposit Reference |
| See BST banks (CMB/CMBC/Airstar) | BST Banks |
| Understand statement collection's position in system architecture | System Architecture & Data Flow |