BST (Bank-Securities Transfer) Overview
About This Page
What: Full comparison of integration models, protocol differences, limit systems, and exception handling across the three BST banks Audience: Product managers who need a deep understanding of BST channel details Prerequisites: Withdrawal Methods Overview, Bank Capability MatrixReading time: 6 minutes Owner: Deposit Product Manager
Key Takeaway: BST (Bank-Securities Transfer) is the fastest withdrawal channel. The three banks have vastly different protocols: CMB/CMBC use Socket bidirectional links (second-level response), while Airstar uses REST API polling (minute-level response).
Three Banks at a Glance
| Dimension | CMB | CMBC | Airstar |
|---|---|---|---|
| Protocol | Socket Binary (GB18030) | Socket XML Text (SM2 Encryption) | REST API (JSON/UTF-8) |
| Authorization Model | BST Agreement | BST Agreement | Mandate Authorization (6 states) |
| Withdrawal Initiator | Both bank-side + moomoo-side | Bank-side only | Both moomoo-side + bank-side |
| Result Delivery | Real-time push (Socket callback) | Real-time push (Socket callback) | Polling |
| Deposit Status | Success / Failure | Success / Failure | NEW / PENDING / SUCCESS / FAILED / REFUNDED |
| Withdrawal Status | 0 (Success) / -5 (Timeout) / -6 (Rejected) | 0 (Success) / -5 (Timeout) / -6 (Rejected) | NEW / PENDING / SUCCESS / FAILED |
Core difference in one sentence: CMB and CMBC use traditional Socket dedicated lines (bank-led), while Airstar uses a modern REST API (moomoo-led).
Individual Bank Channel Interface Details
This page provides a high-level comparison of BST protocols. For channel-side interface fields, moomoo-side adaptation mappings, and complete matching rules for each bank, see the individual bank pages:
BST Authorization (Mandate)
Authorization Model Comparison
| CMB / CMBC | Airstar | |
|---|---|---|
| Terminology | BST Agreement | Mandate Authorization |
| Initiation Method | User completes agreement on bank side | User initiates on moomoo side, confirmed by bank |
| Number of States | 2 (Signed / Unsigned) | 6 (Full state machine) |
| Multi-market | Separate agreement per market | One authorization auto-maps to 3 markets |
| Core Identifier | Bank card number | mandate_id |
Airstar Mandate State Machine
Automatic 3-Market Mapping: After a user completes one Airstar Mandate authorization, the system automatically creates BST binding relationships for HK (Hong Kong stocks), US (US stocks), and CN (A-share connect) markets. Users do not need to operate separately for each market.
mandate_id is Airstar's core identifier: Unlike CMB/CMBC which use bank card numbers as the primary key, Airstar uses mandate_id as the unique identifier for BST relationships. All operations for bank card management, deposits, and withdrawals are linked through mandate_id.
Deposit Flow Comparison
Common BST Deposit
All BST banks share the same deposit logic framework:
- User initiates deposit -> System creates deposit instruction -> Sends to bank -> Bank processes -> Result returned -> Funds credited
Airstar Deposit Specifics
Two deposit sources:
| Source | source Value | Description |
|---|---|---|
| User initiates on moomoo side | 1 | User clicks deposit in moomoo App |
| User initiates on bank side | 2 | User initiates transfer to securities account in Airstar Bank App |
Bank-side initiation (source=2) is unique to Airstar — CMB/CMBC BST deposits can only be initiated from the moomoo side.
Polling mechanism:
Unlike CMB/CMBC which push results in real-time via Socket, moomoo actively polls Airstar:
| Job Name | Responsibility | Poll Count | Description |
|---|---|---|---|
AsbBstCreateJob | Create deposit instruction | — | Sends deposit request to Airstar |
AsbBstCreateResultJob | Poll deposit result | Up to 60 + slow polling | Polls Airstar API at intervals to check deposit status |
AsbBstDepositJob | Process deposit credit | — | Executes internal credit logic after deposit confirmed successful |
First 60 polls at 5-second intervals; after 60, switches to slow polling every 5 minutes until a terminal state is reached or manual intervention.
REFUNDED Status (Airstar-exclusive):
Airstar deposits have a status that other BST banks lack — REFUNDED. This indicates that after funds were successfully credited, the bank initiated a refund.
Trigger scenarios:
- Bank detects transaction anomaly and proactively refunds
- Compliance reasons trigger refund
System handling: Upon receiving REFUNDED status, the system must reverse the already-credited funds and notify the user. This is an exception scenario requiring Operations attention.
Withdrawal Flow Comparison
Common BST Withdrawal
BST withdrawal follows the Freeze-Transfer-Release three-step pattern:
Why freeze first? Because there is a time window between sending the instruction and bank confirmation. Without freezing, the user could spend the money during this period, causing a negative balance. Freezing ensures the withdrawal amount cannot be used by other operations during processing.
Airstar Withdrawal Specifics
Two withdrawal modes:
| Mode | Description |
|---|---|
| moomoo-side initiated | User clicks withdrawal in moomoo App, system sends instruction via API |
| Bank-side initiated | User initiates transfer from securities account to bank in Airstar Bank App (Airstar exclusive) |
Polling mechanism:
| Job Name | Responsibility | Retries | Description |
|---|---|---|---|
AsbBstTransfer | Withdrawal transfer instruction | Up to 10 | Sends withdrawal request and polls result |
SyncAsbBstWithdraw | Bank-side withdrawal pull | Every minute cron | Pulls bank-side initiated withdrawal requests, creates moomoo-side withdrawal tasks |
Flow: moomoo-side withdrawal -> AsbBstTransfer polls up to 10 times -> if still incomplete, marks as exception needing manual confirmation. Bank-side withdrawal -> SyncAsbBstWithdraw pulls every minute -> creates withdrawal task for processing.
CMB / CMBC Withdrawal
CMB and CMBC send withdrawal instructions via Socket connection:
- Withdrawal service calls BST service (
cmb_stock_trans/ms_stock_bank_transaction) - Encrypts request data
- Sends to bank's
exit_servervia Socket - Bank processes and returns result in real-time via the same bidirectional link
- Result codes: 0 (Success) / -5 (Timeout, auto-switch to backup exit_server for retry) / -6 (Bank rejected)
Three-Tier Limit System
BST channels control per-transaction amount, cumulative amount, and daily amount in layers. See Withdrawal Rules Manual - Three-Tier Limits for detailed explanation.
Airstar Limit Details
| Dimension | HKD | USD |
|---|---|---|
| Per-transaction max | 3,000,000 | 500,000 |
| Cumulative alarm | 40,000,000 | 10,000,000 |
| Daily circuit breaker (stop) | 15,000,000 | 3,000,000 |
Online account opening minimum deposit: HKD 10,000 / USD 1,500 / CNH 10,000
How the three tiers work together:
- Tier 1 (Per-transaction): Single deposits/withdrawals exceeding HKD 3M are directly rejected
- Tier 2 (Cumulative alarm): When cumulative reaches HKD 40M, an alert notifies Operations, but transactions continue
- Tier 3 (Daily circuit breaker): When daily cumulative reaches HKD 15M, auto deposit/withdrawal is shut down for the day; subsequent transactions require manual processing
CMB / CMBC Limits
CMB/CMBC Limit Explanation
CMB and CMBC limits are controlled by the bank-side system (not moomoo configuration). Specific values need to be confirmed with the bank. They are known to have per-transaction and daily limit mechanisms; when exceeded, the bank directly rejects and returns callback code -6. For over-limit issues, refer to Withdrawal Troubleshooting - BST Callback Exceptions.
Online Account Opening (Airstar Exclusive)
Airstar supports a three-in-one online account opening flow — new customers can complete in one continuous process:
- Open securities account: Complete KYC identity verification
- Mandate authorization: Authorize Airstar Bank for BST
- First deposit: Complete first deposit to securities account
The value of this flow is new customer acquisition — it lowers the barrier from registration to tradeable status. The traditional process requires users to switch between multiple systems (open account -> go to bank for agreement -> come back to deposit); the three-in-one flow is completed end-to-end within the moomoo App.
Online account opening deposit restrictions: The first deposit has a minimum amount requirement (HKD 10,000 / USD 1,500 / CNH 10,000), higher than regular deposit minimums, to ensure new customers have sufficient funds for trading.
Airstar Only
CMB and CMBC BST agreements must be completed on the bank side, and do not support the three-in-one flow within moomoo.
Cron Jobs
Airstar Job List
| Job Name | Responsibility | Frequency | Retries | Dependency |
|---|---|---|---|---|
AsbBstCreateJob | Create BST deposit instruction | Trigger-based | — | User deposit request |
AsbBstCreateResultJob | Poll deposit result | Scheduled | Slow poll after 60 | AsbBstCreateJob |
AsbBstDepositJob | Deposit credit processing | Trigger-based | — | AsbBstCreateResultJob returns SUCCESS |
AsbBstTransfer | Withdrawal transfer + poll result | Trigger-based | Up to 10 | Approval passed |
SyncAsbBstWithdraw | Bank-side withdrawal pull | Every minute cron | — | Bank-side initiated withdrawal |
AsbBstCreateFromBankJob | Bank-side deposit processing | Trigger-based | — | Bank-side initiated deposit |
AsbBstCreateRetryJob | Deposit creation retry | Trigger-based | — | AsbBstCreateJob failure |
Job Chain:
Deposit: AsbBstCreateJob (moomoo-side) / AsbBstCreateFromBankJob (bank-side) -> AsbBstCreateResultJob (60 fast polls + slow poll) -> AsbBstDepositJob (credit)
Withdrawal: moomoo-side: AsbBstTransfer (poll 10 times) -> timeout needs manual confirmation | Bank-side: SyncAsbBstWithdraw (pull every minute) -> creates withdrawal task
CMB / CMBC Jobs
| Service Name | Bank | Responsibility |
|---|---|---|
cmb_stock_trans | CMB | BST service, Socket binary communication |
ms_stock_bank_transaction | CMBC | BST service, Socket XML text communication |
CMB/CMBC use real-time bidirectional Socket, requiring no polling jobs — the bank pushes results directly through the same connection after processing.
Full cron job list -> Cron Jobs & Monitoring
Exception Scenarios Manual
Authorization Exceptions (5 types)
| # | Exception | Symptom | Cause | Resolution |
|---|---|---|---|---|
| 1 | Authorization timeout | Mandate stuck in PendingAuthorise state | Bank processing delay or communication interruption | Wait + manually query bank-side status |
| 2 | Authorization failure | Mandate becomes RejectAuthorise | User info verification failed / bank-side risk control | Investigate failure cause, guide user to re-initiate |
| 3 | Authorization revocation | Mandate becomes Revoked | User initiated revocation | Confirm user intent, re-authorize if needed |
| 4 | Partial market authorization failure | Some of 3 markets binding succeeded | BST configuration issue for certain market | Check failed market config, manually supplement binding |
| 5 | Bank-side revocation not synced | Bank-side already revoked but moomoo still shows Authorised | Sync delay or callback lost | Manually sync Mandate status |
Deposit Exceptions (7 types)
| # | Exception | Symptom | Cause | Resolution |
|---|---|---|---|---|
| 1 | Instruction creation failure | AsbBstCreateJob errors | Parameter exception / Mandate not Authorised | Check Mandate status and request parameters |
| 2 | Polling timeout | Still PENDING after 60 polls | Bank processing anomaly | Manually query bank-side status |
| 3 | Deposit failure | Status becomes FAILED | Bank rejected (insufficient balance/limit etc.) | Check bank-returned error code |
| 4 | Deposit refund | Status becomes REFUNDED | Bank initiated refund | Reverse credited funds, notify user |
| 5 | Bank-side deposit not synced | source=2 deposit moomoo didn't receive | Callback lost | Manually query Airstar API to supplement |
| 6 | Amount mismatch | Credited amount differs from requested amount | Bank-side fees or exchange rate difference | Verify bank-side transaction details |
| 7 | Duplicate deposit | Same deposit created multiple records | Deduplication mechanism failed | Check procedure_id/request_id/bank_ref_id |
Withdrawal Exceptions (5 types)
| # | Exception | Symptom | Cause | Resolution |
|---|---|---|---|---|
| 1 | Withdrawal instruction failure | AsbBstTransfer errors | Parameter exception / Bank rejected | Check error code, release frozen funds |
| 2 | Polling timeout | Still PENDING after 10 polls | Bank processing anomaly | Manually query bank-side status |
| 3 | Freeze not released | Withdrawal failed but funds still frozen | Release process exception | Manually release freeze |
| 4 | Bank-side withdrawal not synced | User initiated withdrawal from bank side but moomoo didn't deduct | Callback lost | Manually query Airstar API, execute deduction |
| 5 | Partial withdrawal | Bank only transferred partial amount | Bank-side limit or insufficient balance | Verify amount difference, process remainder |
Monitoring & Alerts
Airstar 13 Alert Items
| # | Alert Item | Trigger Condition | Severity | Response |
|---|---|---|---|---|
| 1 | Authorization creation timeout | Mandate in PendingAuthorise exceeds threshold | High | Check Airstar API connectivity |
| 2 | Authorization failure rate spike | RejectAuthorise count exceeds limit per time unit | High | Investigate bank-side anomaly |
| 3 | Deposit creation failure | AsbBstCreateJob consecutive failures | High | Check request parameters and API status |
| 4 | Deposit polling timeout | AsbBstCreateResultJob entered slow poll with no terminal state | High | Manually query bank-side status |
| 5 | Deposit refund | Received REFUNDED status | High | Immediately reverse, notify user |
| 6 | Withdrawal polling timeout | AsbBstTransfer exhausted 10 attempts | High | Manually confirm bank-side status |
| 7 | Bank-side withdrawal pull exception | SyncAsbBstWithdraw cron errors | Critical | Check Airstar API connectivity |
| 8 | Freeze not released | Withdrawal failed but freeze not rolled back | Critical | Manually release freeze |
| 9 | Daily circuit breaker triggered | Daily cumulative reaches stop threshold | Medium | Operations confirms then decides whether to restore |
| 10 | Cumulative alarm triggered | Cumulative reaches alarm threshold | Medium | Operations monitors, assess risk |
| 11 | Duplicate transaction detected | procedure_id/request_id duplicate | High | Check deduplication logic |
| 12 | API connectivity exception | Airstar API response timeout or error rate increase | Critical | Contact Airstar Bank technical support |
| 13 | Bank-side initiation volume anomaly | source=2 transaction volume spike | Medium | Investigate whether normal business fluctuation |
Error Codes
Error Code System
Airstar error codes are categorized by operation type prefix, not by business domain:
| Error Code Prefix | Operation Type | Description |
|---|---|---|
| 14060xxxx | Create authorization | Errors when moomoo initiates Mandate creation |
| 14061xxxx | Cancel authorization | Errors when moomoo initiates Mandate cancellation |
| 14062xxxx | Query authorization | Errors when moomoo queries Mandate status |
| 14063xxxx | moomoo-initiated transfer | Errors when moomoo initiates deposit/withdrawal transfer |
| 14064xxxx | Query transfer | Errors when moomoo queries transfer status |
| 14067xxxx | Bank-initiated transfer | moomoo-side validation errors when bank initiates transfer |
| 14072xxxx | Notify transfer result | Errors when bank notifies transfer result |
| 14073xxxx | Notify authorization result | Errors when bank notifies authorization result |
CMB/CMBC Error Codes
CMB and CMBC return result codes via Socket callback (0/-5/-6) and do not have independent error code series. Detailed callback handling logic is at Withdrawal Data Dictionary - Bank Callback Result Codes.
BST Channel Comparison
Airstar vs CMB/CMBC
| Dimension | Airstar | CMB / CMBC |
|---|---|---|
| Protocol | REST API (HTTP + JSON) | Socket binary protocol |
| Encoding | UTF-8 | GB18030 |
| Initiator | moomoo + bank bidirectional | CMB bidirectional / CMBC bank-side only |
| Authorization Model | Mandate (6 states) | BST Agreement (2 states) |
| Multi-market Mapping | One authorization -> 3 markets auto-mapped | Separate agreement per market |
| Core Identifier | mandate_id | Bank card number |
| Result Delivery | Polling | Real-time push (Socket callback) |
| Deposit Status | NEW/PENDING/SUCCESS/FAILED/REFUNDED | Success/Failure |
| Withdrawal Status | NEW/PENDING/SUCCESS/FAILED | 0 (Success)/-5 (Timeout)/-6 (Rejected) |
| Deposit Polling | 60 fast polls + slow poll | No polling needed |
| Withdrawal Polling | 10 times | No polling needed |
| Refund Mechanism | Supports REFUNDED status | None |
| Online Account Opening | Supports three-in-one | Not supported |
| Error Codes | By operation type (14060~14073 series) | 0 / -5 / -6 |
BST vs Other Withdrawal Channels
| Dimension | BST | Online Banking (HSBC/Hang Seng) | FPS | Traditional Channels |
|---|---|---|---|---|
| Automation | Fully automatic (only one) | Semi-auto | Semi-auto | Manual |
| Speed | Seconds~minutes | Minutes~hours | Minutes | Hours~days |
| Protocol Complexity | High (Socket/API) | Low (Corporate online banking) | Medium (FPS API) | Low (Online banking/wire) |
| Operations Involvement | Only on exceptions | Confirm step | Confirm step | Full involvement |
| Applicable Banks | CMB/CMBC/Airstar | HSBC/Hang Seng | BOCHK/SCB/CGB | All banks |
| Limit Control | Three-tier limit system | Bank-side limits | FPS system limits | Varies by bank |
After Reading
| I want to... | Go to |
|---|---|
| Deep dive into CMB's Socket binary protocol | CMB |
| Deep dive into CMBC's XML text protocol | CMBC (MS) |
| Deep dive into Airstar's REST API + RSA-OAEP | Airstar |
| See BST's role in the withdrawal system | Withdrawal Methods Overview |
| See auto-withdrawal 6 conditions and three-tier limits | Withdrawal Rules Manual |
| Look up Mandate status codes and Airstar error codes | Unified Error Code Center |
| See BST job frequencies and alerts | Cron Jobs & Monitoring |
| See other banks' integration methods | Bank Capability Matrix |