SCB (Standard Chartered)
About This Page
What: Standard Chartered Bank's FPS withdrawal channel, Book Transfer (crypto asset transfer), and Webhook event mechanism Audience: PMs needing to understand SCB integration details Prerequisites: Bank Capability MatrixReading time: 2 minutes Owner: Withdrawal Product Manager
Key takeaway: SCB's core capability is FPS withdrawal API + Webhook event push, representing semi-automated withdrawal — no need for operations to log into online banking.
Capability Overview
| Capability | Supported | Protocol/Channel | Core Service |
|---|---|---|---|
| Deposit Statements | ❌ | — | — |
| FPS Withdrawal | ✅ | REST API + Webhook | scb_service (Go) |
| Book Transfer | ✅ | REST API | scb_service (Go) |
| Sub-account | ✅ | — | Sub-account deposit matching |
| eDDA/eDDI | ❌ | — | — |
| BST | ❌ | — | — |
SCB is a withdrawal-dedicated bank — no deposit statement collection, primarily providing FPS withdrawal and Book Transfer channels.
Withdrawal: FPS
Withdrawal Method
| Dimension | Description |
|---|---|
| Method Code | TRANSFER_METHOD_SC = 'sc' |
| Classification | Electronic bank method (allEBankMethod) |
| Name | SCB Online Banking Withdrawal |
Data Flow
Webhook Events
SCB asynchronously notifies transaction status changes via Webhook callbacks, no polling needed:
| Webhook Type | Meaning | Trigger Scenario |
|---|---|---|
payment_status | Payment status change | Withdrawal instruction processing result |
credit_debit_advice | Debit/Credit advice | Fund arrival/debit confirmation |
Webhook Processing Status:
| Status Code | Meaning |
|---|---|
| 0 | New (pending) |
| 1 | Processing |
| 2 | Processed |
FPS Withdrawal Statement Query
The system can query statement records via API:
- Supports pagination (cursor-based, default 20 per page)
- Return fields: TransactionID, BankStatementID, ValueTime, ValueDate, Amount, Currency
- Includes Payer/Payee info: receiving card number, payer bank name, SWIFT code
Book Transfer (Crypto Asset Transfer)
Book Transfer is SCB's internal inter-account transfer capability, used for fund movement in specific scenarios:
| Dimension | Description |
|---|---|
| Purpose | Fund transfer between sub-accounts |
| Request Parameters | RequestID, Amount, Debtor (payer), Creditor (payee) |
| Amount Validation | Must be >= 0 |
| ID Generation | Snowflake algorithm generates ReferenceID |
| Queue Event | QueueEventTransferCreate |
Sub-Account Deposit
Although SCB doesn't have an independent deposit statement collection service, it supports sub-account deposit matching. Users transfer funds via SCB sub-accounts, and the system auto-matches after verifying sub-account ownership via SubAccountSDK.
Channel Interface Details
Channel Interface Overview
| Dimension | Description |
|---|---|
| Protocol Type | HTTPS REST + JSON |
| Authentication | TLS mutual authentication + JWT Token (30-second validity) |
| Encryption | AES256Signed (response encryption) |
| Signature Algorithm | RS256 (RSA) |
| Core Service | scb_service (Go) |
HTTP Headers (Required for All Requests)
Every request to SCB API must carry these Headers:
| Header | Value | Description |
|---|---|---|
Content-Type | Application/JSON | Request body format |
ResponseEncryptionType | AES256Signed | Response encryption method |
Routing-Identifier | ZZ | Routing identifier |
GroupId | GHK54005 | Group ID |
Authorization | Bearer [JWT_TOKEN] | JWT token (30-second validity) |
Note: messageSender and countryCode are fields in the request body JSON (see PaymentInitRequest below), not HTTP Headers.
Certificate Configuration
SCB uses TLS mutual authentication + RS256-signed JWT Token, involving multiple key sets:
| Certificate | Path | Purpose |
|---|---|---|
| Client certificate | conf/keys/client.cer | TLS mutual authentication |
| Client private key | conf/keys/clientcertsslprivatekey.pem | Signing / Decryption |
| Client public key | conf/keys/clientpubkey.pem | Bank verifies our identity |
| JWT signing key | conf/keys/scbapibankingprivatekey.pem | JWT RS256 signing |
JWT Token Parameters:
| Parameter | Value |
|---|---|
| Issuer | "SCB" |
| Audience | "SCB-APIBanking" |
| Validity | 30 seconds |
Extremely Short JWT Validity
JWT Token is valid for only 30 seconds; the system must regenerate before each request. Clock skew exceeding a few seconds may cause authentication failure — ensure server NTP synchronization.
Interface 1: Payment Initialization (Withdrawal Initiation)
POST /openapi/payments/v2/initiate
Request PaymentInitRequest:
| Field | Type | Required | Description |
|---|---|---|---|
header.messageSender | string(<=246) | ✅ | Sender |
header.messageId | string(<=35) | ✅ | Message ID, unique identifier |
header.countryCode | string(2) | ✅ | Country code. Value "HK" |
header.timestamp | int64 | ✅ | Unix timestamp |
instruction.paymentTimestamp | int64 | ✅ | Payment timestamp |
instruction.requiredExecutionDate | string(<=10) | ✅ | Execution date. Format "YYYY-MM-DD" |
instruction.amount.currencyCode | string(3) | ✅ | Currency. Values "HKD" / "USD" |
instruction.amount.amount | string | ✅ | Amount. e.g. "1000.00" |
instruction.referenceID | string(<=16) | ✅ | Reference number |
instruction.purpose | string(<=10) | ❌ | Purpose |
instruction.paymentType | string(<=4) | ❌ | Payment type |
instruction.chargerBearer | string(<=4) | ❌ | Fee bearer |
instruction.debtor.name | string(<=140) | ✅ | Payer name |
instruction.debtorAccount.id | string(<=34) | ✅ | Payer account |
instruction.debtorAccount.identifierType | string | ✅ | Account type. Values "BBAN" / "IBAN" / "Other" |
instruction.creditor.name | string(<=140) | ✅ | Payee name |
instruction.creditorAccount.id | string(<=34) | ✅ | Payee account |
instruction.creditorAgent.financialInstitution.BIC | string(<=11) | ❌ | Payee bank BIC. e.g. "SCBLHKHHXXX" |
instruction.remittanceInfo.multiUnstructured | array[string] | ❌ | Remittance information |
Response PaymentInitResponse:
| Field | Type | Description |
|---|---|---|
paymentIdentifier | string | SCB payment identifier |
internalTrackingId | string(<=35) | Internal tracking ID |
clientReferenceId | string(<=35) | Client reference ID |
referenceId | string(<=35) | Reference number |
statusString | string(<=10) | Status |
timestamp | ISO-8601(<=24) | Timestamp |
Interface 2: Payment Status Query
POST /openapi/payments/v2/status
Request:
{
"clientReferenceIds": ["ref1", "ref2", "..."]
}Supports batch query of multiple withdrawal statuses.
Response (per record):
| Field | Type | Description |
|---|---|---|
statusString | string | Status description |
statusCode | string | ISO 20022 status code |
reasonCode | string | Reason code |
valueDate | YYYY-MM-DD | Value date |
debitDate | YYYY-MM-DD | Debit date |
debitAmount | string | Debit amount |
Scheduling rule: System polls incomplete withdrawal statuses every 30 seconds.
Interface 3: Webhook Credit/Debit Advice (Deposit Notification)
POST /credit-debit-advice
SCB proactively pushes credit/debit notifications via Webhook. Full payload fields:
| Field | Type | Description |
|---|---|---|
groupId | string | Group ID |
accountIdentifier.accountId | string | Account number |
accountIdentifier.currencyCode.isoCode | string | Currency |
eventDate | YYYY-MM-DD | Event date |
adviceType | string | "CRDT"=Credit (deposit) / "DBIT"=Debit (withdrawal) |
valueDate | YYYY-MM-DD | Value date |
transactionAmount.currencyCode | string | Transaction currency |
transactionAmount.amount | decimal | Transaction amount |
transactionFreeText | array[string] | Transaction description (free text) |
payerDetails.name | string | Payer name |
payerDetails.account.id | string | Payer account |
timestamp | ISO-8601 | Timestamp |
Configured Receiving Accounts
| Currency | Account | BIC | Purpose |
|---|---|---|---|
| HKD | 44700993333 | SCBLHKHHXXX | Securities |
| HKD | 91701015121 | SCBLHKHHXXX | Crypto / Hash Key |
| HKD | 91701015121 | SCBLHKHHXXX | PantherTrade |
| USD | 44700993333 | SCBLHKHHXXX | Securities |
| USD | 91701015121 | SCBLHKHHXXX | Crypto / Hash Key |
| USD | 91701015121 | SCBLHKHHXXX | PantherTrade |
moomoo-Side Adaptation
Webhook → BankFlow Mapping: Upon receiving SCB Webhook, the system converts payload to internal BankFlow records:
| Webhook Field | BankFlow Field | Description |
|---|---|---|
transactionAmount.amount | amount | Amount |
transactionAmount.currencyCode | currency | Currency |
payerDetails.name | payer_name | Payer name |
payerDetails.account.id | payer_account | Payer account |
adviceType | direction | CRDT→Deposit, DBIT→Withdrawal |
eventDate | transaction_date | Transaction date |
Status Code Mapping (ISO 20022 → Internal Status):
| ISO 20022 Status Code | Meaning | Internal Status |
|---|---|---|
ACCC | Accepted Settlement Completed | Success |
RJCT | Rejected | Failed |
CANC | Cancelled | Cancelled |
ACSP | Accepted Settlement in Process | Processing |
ACCP | Accepted Customer Profile | Accepted |
Change Guide
| Change Requirement | Modification Location | Description |
|---|---|---|
| Add new Webhook event type | scb_service → webhook handler | Add new event processing logic |
| Modify FPS withdrawal parameters | scb_service → withdrawal request builder | Adjust API request fields |
| Book Transfer add validation | scb_service → book_transfer.go | Modify amount/account validation rules |
| Modify sub-account matching rules | SubAccountSDK configuration | Adjust sub-account ownership verification |
| Modify withdrawal approval template | Task.php → $stepTemplates | Adjust SCB withdrawal approval flow |
Common Customer Complaints Top 3
| # | User Feedback | Cause | CS Script |
|---|---|---|---|
| 1 | "FPS withdrawal didn't arrive" | Webhook push delay or withdrawal still processing | "FPS withdrawals typically arrive within minutes; please contact customer service if it exceeds 30 minutes" |
| 2 | "FPS withdrawal was returned" | Incorrect payee information | "The transfer has been returned by the bank; please verify payee bank card information and resubmit" |
| 3 | "Withdrawal status shows processing forever" | SCB Webhook not received | "Your withdrawal is being processed; we are confirming bank status, please wait" |
Monitoring & Alerts
| Alert Item | Trigger Condition | Severity | Handling Steps |
|---|---|---|---|
| Webhook reception failure | SCB push notification not received | High | Check Webhook endpoint availability, proactively call status interface |
| JWT Token expired | Authentication failure (30-second validity) | Medium | Check server NTP clock sync, ensure skew < 5 seconds |
| FPS payment long PENDING | Withdrawal hasn't reached terminal state after 30 minutes | Medium | Proactively call Payment Status interface, confirm bank-side status |
After Reading
| I want to... | Go to |
|---|---|
| See SCB's position among all banks | Bank Capability Matrix |
| Understand SCB withdrawal's full approval flow | Withdrawal Lifecycle |
| Compare with another FPS withdrawal bank | CGB |
| Check withdrawal channel execution details | Channel Execution Manual |