Withdrawal Change Guide
About This Page
What: The 10 most common withdrawal change requests PMs encounter — for each one, what to change, where to change it, what it impacts, and who needs to approve Audience: Product managers who need to push withdrawal-related requirement changes Prerequisites: Withdrawal Methods OverviewReading time: 8 minutes Owner: Withdrawal Product Manager
Key Takeaway: Withdrawal changes are categorized as code changes (requires release, 1-3 days) and database configuration (takes effect immediately). Each change type is annotated with modification location, impact scope, and approval requirements.
How to Use This Page
When you have a withdrawal-related requirement change:
- Find the corresponding change scenario below
- Check "Configuration Type" to assess difficulty and timeline
- Check "Impact Chain" to evaluate risk
- Check "Approval Requirements" to confirm who needs to sign off
- Check "Verification Method" to confirm how to validate
Configuration Type Quick Reference
| Type | Meaning | How It Takes Effect | Change Timeline |
|---|---|---|---|
| Code constant | Hardcoded in PHP/Go/Python code | Requires release process | 1~3 days (dev + test + release) |
| Config file | config/*.php or .env | Requires release process | 1~2 days |
| Database config | Stored in DB config tables | Takes effect immediately after change | Same day |
| Operations backend | Adjustable via OA/CRM backend | Ops self-service | Immediate |
| Cron config | Scheduled task expressions | Requires ops deployment | 0.5~1 day |
| Bank-side | Requires bank cooperation | Goes through business + technical integration | Weeks~months |
Scenario 1: Adjust Auto-Withdrawal Limits
Example: Raise Airstar HKD single transaction cap from 3 million to 5 million
| Dimension | Description |
|---|---|
| What to change | max_amount field for the corresponding bank+currency in auto_settings table |
| Where to change | Database auto_settings table, locate row by id (bank: CMB=2, CMBC=1, Airstar=3), modify {prefix}max_amount |
| Configuration type | Database config — takes effect immediately |
| Impact chain | Limit raised → More large withdrawals take auto path → Ops workload decreases, but large anomalies may auto-pass. Limit lowered → More withdrawals degrade to manual → Ops workload increases, higher security |
| Verification method | Send a test withdrawal slightly above old limit but below new limit, confirm it takes the auto path |
| Approval requirements | Risk control team sign-off (mandatory) + Product confirmation + Ops awareness |
| Rollback | Restore original value, takes effect immediately |
Three-Tier Limit Linkage
When modifying max_amount (single transaction cap), you must simultaneously evaluate whether alarm_amount (alarm threshold) and stop_amount (circuit breaker threshold) also need adjustment. Raising the single cap without adjusting the circuit breaker may result in a few large withdrawals triggering the circuit breaker.
Current three-tier limit values → Withdrawal Rules Manual § Three-Tier Limit System
Scenario 2: Modify High-Risk Determination Rules
Example: Make mainland China (CN) no longer trigger high-risk Audit
| Dimension | Description |
|---|---|
| What to change | Determination logic for the HIGH_RISK_AREA factor |
| Where to change | withdraw/src/app/Business/HighRisk/HighRiskBiz.php → various checkHighRisk*() methods |
| Configuration type | Code constant — requires release |
| Impact chain | Remove CN → Mainland bank card withdrawals no longer trigger Audit → Audit review volume decreases, but may miss abnormal mainland-direction withdrawals. Add country → All withdrawals to that country get extra Audit step → Ops review volume increases |
| Special note | The high-risk country list updates from an API every 5 minutes, but CN and PR are hardcoded in HighRiskBiz.php's checkHighRiskArea() (not in the API list). Removing CN requires code change, not API adjustment |
| Verification method | Send a test withdrawal with mainland bank card, confirm the AREA(2) bit is no longer set in high_risk bitmask |
| Approval requirements | Risk control team sign-off (mandatory) + Compliance confirmation |
| Rollback | Restore original code, re-release |
Common change scenarios
- Make FREQUENCY also trigger Audit → Add bit check in
HighRiskCheck.php→needAudit() - Modify the ">= 10 transactions" frequency threshold → Modify FREQUENCY check logic in
HighRiskBiz.php - Add a new risk factor → New bit constant + calculation logic + needAudit check
Current 6-factor details → Withdrawal Rules Manual § High-Risk Determination
Scenario 3: Modify Approval Templates
Example: Add a fast withdrawal template for VIP users that skips Confirm
| Dimension | Description |
|---|---|
| What to change | $stepTemplates array, add new template or modify existing template steps |
| Where to change | withdraw/src/app/Business/Task.php → $stepTemplates array |
| Configuration type | Code constant — requires release |
| Impact chain | Fewer steps → Faster withdrawal approval, but fewer safety checks. More steps → Slower withdrawal, higher security but increased ops workload. New template → Must also add template selection logic in CreatorBase.php |
| Verification method | Send a test withdrawal with target user type, check the template field and actual approval step count |
| Approval requirements | Product confirmation + Risk control confirmation + Ops awareness (flow change) |
| Rollback | Restore original template, re-release |
New steps require Step class implementation
Each approval step is a PHP class implementing the IFStep interface. Adding a step is not just adding an array element — you need to write the step's check logic, CRM interaction logic, and permission control.
Current 6 templates → Withdrawal Rules Manual § Approval Templates
Scenario 4: Adjust Auto-Withdrawal Balance Management
Example: Raise Airstar HKD alarm threshold from 40 million to 60 million
| Dimension | Description |
|---|---|
| What to change | alarm_amount and/or stop_amount in auto_settings table |
| Where to change | Database auto_settings table |
| Configuration type | Database config — takes effect immediately |
| Impact chain | alarm threshold raised → Earlier alert → Ops has more reaction time. alarm threshold lowered → Alert delayed → Balance may approach circuit breaker without notice. stop threshold raised → Earlier circuit breaker → Safer but ops needs more frequent "top-ups". stop threshold lowered → Later circuit breaker → Auto-withdrawal runs longer |
| Verification method | After adjustment, observe whether next alert/circuit breaker triggers at balance values matching new thresholds |
| Approval requirements | Ops supervisor confirmation |
| Rollback | Restore original values, takes effect immediately |
"Top-up" Operation
When balance falls below stop_amount triggering circuit breaker, ops needs to: 1. Update {prefix}amount to increase balance ("top up"); 2. Set {prefix}status to 1 (reopen). Both steps are required.
auto_settings complete fields → Withdrawal Rules Manual § Auto-Withdrawal Configuration
Scenario 5: Restore Withdrawal Fees
Example: Restore cross-border withdrawal charges of HKD 105 / USD 15
| Dimension | Description |
|---|---|
| What to change | The $fee = 0 forced-free line at the end of getFee() |
| Where to change | withdraw/src/app/Business/CreatorBase.php → getFee() method |
| Configuration type | Code constant — requires release |
| Impact chain | Restore fees → User withdrawal cost increases → May affect withdrawal frequency and user satisfaction. Fees are displayed for user confirmation before submission → Frontend display logic does not need modification (already exists) |
| Special note | The code already defines a complete fee schedule (HKD 105 / USD 15 / CNH 105); just deleting the trailing $fee = 0 restores it. No need to rewrite fee logic |
| Verification method | Send a test withdrawal with a cross-border bank card, confirm the App displays correct fees and the Task fee field is correct |
| Approval requirements | Product owner + Ops awareness + Customer service prepare talking points |
| Rollback | Add back $fee = 0, re-release |
Current fee schedule → Withdrawal Rules Manual § Fee Rules
Scenario 6: Add New BST Bank
Example: Connect a new bank for BST
This is the most complex withdrawal change scenario, involving multiple services.
Development Checklist
| Step | Work Content | Service/File Involved |
|---|---|---|
| 1 | Bank-side agreement signing + technical protocol confirmation | Business team |
| 2 | Develop BST integration service | New Python/Go service (reference cmb_stock_trans) |
| 3 | Develop SBA withdrawal orchestration adaptation | sba_cash_withdraw_system add bank branch |
| 4 | Add bank config in auto_settings table | Database + AutoSetting.php add bank_id mapping |
| 5 | Add channel routing in Method.php | calcMethod() add BST judgment branch |
| 6 | Create new xxx_list table | Bank-initiated withdrawal transaction storage |
| 7 | Create new queue events | SyncXxxWithdraw + XxxWithdrawCreate |
| 8 | Mandate/agreement management | Bank card service + BankCardXxxBst extension table |
| 9 | Frontend channel display | App deposit/withdrawal page adaptation |
| 10 | Integration testing | End-to-end: Agreement → Deposit → Withdrawal → Callback |
Protocol Selection
| Protocol | Reference | Arrival Time | Complexity |
|---|---|---|---|
| Socket bidirectional link (SM2) | CMB cmb_stock_trans | Seconds (real-time push) | High |
| REST API + polling | Airstar airstar_service | Seconds~minutes | Medium |
Approval Requirements
Business team (bank cooperation) + Tech lead + Risk control confirmation + Product confirmation
Reference Timeline
| Integration Method | Reference Timeline | Reference Service |
|---|---|---|
| Socket bidirectional link | 6~8 weeks | cmb_stock_trans (CMB) |
| REST API | 4~6 weeks | airstar_service (Airstar) |
Scenario 7: Add New FPS Withdrawal Channel
Example: Connect Standard Chartered's FPS withdrawal API (from manual to semi-auto)
| Dimension | Description |
|---|---|
| What to change | Upgrade manual channel to semi-auto with API integration |
| Where to change | Multiple locations — see development checklist |
| Configuration type | Code development — requires full development cycle |
Development Checklist
| Step | Work Content | File Involved |
|---|---|---|
| 1 | Create Go service to interface with bank FPS API | New xxx_fps_service (reference cgb_fps_service) |
| 2 | Create new business class in PHP | withdraw/src/app/Business/Withdraw/XxxFpsBiz.php (reference CgbFpsBiz.php) |
| 3 | Create new polling event | SyncXxxFpsResult (reference SyncCgbFpsResult) |
| 4 | Add channel constant in Method.php | New xxx_fps_api constant and group membership |
| 5 | Create new status tracking table | task_xxx_fps (reference task_cgb_fps) |
| 6 | Adjust CRM display | Channel list, action buttons |
Approval requirements: Tech lead + Product confirmation
Reference timeline: 3~4 weeks (including integration testing)
Channel execution details → Channel Execution Manual § FPS Channel
Scenario 8: Modify Processing Hours
Example: Extend Airstar processing hours from 08:00~22:00 to 07:00~23:00
| Dimension | Description |
|---|---|
| What to change | Auto-processing time window for BST channel |
| Where to change | Withdrawal cron task scripts + time window checks in SBA orchestration |
| Configuration type | Cron config + Code constant — requires ops deployment + code release |
| Impact chain | Window expanded → More time periods can auto-process withdrawals → Better user experience. But must confirm bank side accepts instructions during that period — if bank doesn't process, instructions will queue on bank side |
| Why it can't be changed arbitrarily | Processing hours are aligned with bank business hours. If the system sends instructions during bank off-hours, the bank may return timeout or rejection |
| Verification method | Send a test withdrawal during the newly added time period, confirm bank processes normally |
| Approval requirements | Product confirmation + Ops deployment + Must first confirm with bank their supported hours |
| Rollback | Restore original time configuration |
Current channel processing hours → Withdrawal Rules Manual § Processing Hours
Scenario 9: Add New Withdrawal Currency
Example: Add JPY (Japanese Yen) withdrawal
| Step | Work Content | File Involved |
|---|---|---|
| 1 | Add JPY columns to auto_settings table | jp_status, jp_amount, jp_max_amount etc. 6 fields |
| 2 | Add prefix mapping in AutoSetting.php | New jp_ prefix handling |
| 3 | Add JPY fee rate in getFee() | CreatorBase.php switch statement |
| 4 | Support JPY in channel routing | Confirm which channels support JPY withdrawal |
| 5 | Frontend currency selector | App withdrawal page add JPY option |
| 6 | SBA configuration | SBA system support JPY account balance operations |
Prerequisite: Confirm which withdrawal channels support JPY. BST channels require bank confirmation on whether JPY BST is supported.
Approval requirements: Product confirmation + Clearing team confirmation + Tech lead
Reference timeline: 2~3 weeks
Scenario 10: Modify Withdrawal Notification Logic
Example: Change post-withdrawal success push notification to include receiving bank information
| Dimension | Description |
|---|---|
| What to change | Notification copy and trigger logic |
| Where to change | Notification service configuration (not under withdraw service jurisdiction — withdraw only sends notification events) |
| Configuration type | Depends on notification service implementation |
| Impact chain | Copy modification only affects user-facing display; trigger logic modification may affect notification timing and frequency |
| Special note | The withdrawal system triggers notifications through SBA callbacks; when Task status updates to DONE, notification is sent. Modifying notification content does not require changing the withdrawal service, only the notification service template |
| Verification method | Complete a withdrawal in test environment, confirm notification content and channel |
| Approval requirements | Product confirmation |
Change Risk Matrix
| Change | Technical Risk | Business Risk | Change Timeline | Suggested Gradual Rollout |
|---|---|---|---|---|
| Adjust limits | Low | High (large anomalies) | Immediate | Adjust by bank x currency incrementally |
| Modify risk control rules | Low | High (missed risks) | 1~3 days | Remove single factor first, observe 1 week |
| Modify approval templates | Medium | High (missing approvals) | 1~3 days | Gradual rollout to specific user group first |
| Adjust balance management | Low | Medium | Immediate | Adjust one currency first and observe |
| Restore fees | Low | High (user experience) | 1~3 days | Not recommended for gradual rollout; needs full rollout synced with frontend display |
| Add BST bank | High | Medium | 6~8 weeks | New bank goes live independently |
| Add FPS channel | Medium | Low | 3~4 weeks | New channel goes live independently |
| Modify processing hours | Low | Medium | 0.5~1 day | Extend by 30 minutes first and observe |
| Add new currency | Medium | Low | 2~3 weeks | Open by currency incrementally |
| Modify notifications | Low | Low | 1~2 days | Gradual push |
What to Read Next
| I want to... | Go to |
|---|---|
| Understand the complete withdrawal flow | Withdrawal Lifecycle |
| See detailed explanation of each rule | Withdrawal Rules Manual |
| Look up what a status code means | Withdrawal Data Dictionary |
| See what deposit-side change scenarios exist | Deposit Change Guide |
| Understand a specific bank's integration details | Bank Capability Matrix |