Withdraw Flow
This document provides a comprehensive explanation of the withdrawal workflow when integrating with the payment gateway.
Overview
The withdrawal flow describes the complete process from when a customer initiates a withdrawal request on a merchant's website through to the final fund disbursement. This process involves API communication, withdrawal processing, and webhook notifications to inform the merchant of the withdrawal status.
Withdrawal Workflow Steps
Step 1: Customer Initiates Withdrawal Request
The withdrawal process begins when a customer on the merchant's website decides to withdraw funds:
- Customer navigates to the withdrawal page on the merchant's website
- Customer enters the desired withdrawal amount
- Customer verifies their registered bank account details
- Customer submits the withdrawal request
Step 2: Merchant Backend Validates Request
Before submitting to the payment gateway, the merchant's system should perform preliminary validations:
Account Balance Verification:
- Verify customer has sufficient balance for withdrawal
- Check against any withdrawal limits or restrictions
- Validate minimum withdrawal amount requirements
Account Information Validation:
- Confirm customer's bank account is verified
- Ensure account details are complete and accurate
- Check if account is not blocked or suspended
Business Rules Validation:
- Apply any cooling-off period requirements
- Check daily/monthly withdrawal limits
- Verify KYC/AML compliance status
Step 3: Merchant Backend Submits Withdrawal Request
Once validations pass, the merchant's backend system proceeds:
Deduct customer balance (recommended):
- Immediately deduct the withdrawal amount from customer's available balance
- Move funds to a "pending withdrawal" state
- This prevents double-spending while withdrawal is processing
Prepare the withdrawal request payload:
- Merchant credentials (
merchant_id,token) - Current timestamp (
time) - Unique merchant order ID (
merchant_order_id) - Withdrawal amount (
amount) - Customer's bank details for fund disbursement (
bank,account_name,account_no) - Webhook notification URL (
notify_url)
- Merchant credentials (
Generate HMAC-SHA256 signature using the merchant's secret key
Send POST request to the API endpoint:
/withdraw/create
Example API Request:
{
"merchant_id": "AA12345678",
"token": "testtokentesttokentesttokentesttokentesttoken",
"time": 1656272222,
"merchant_order_id": "WITHDRAW0123456789",
"amount": "5000.00",
"bank": "KBANK",
"account_name": "สมชาย ใสสว่าง",
"account_no": "1234567890",
"notify_url": "https://merchant.com/callback/withdraw"
}
Step 4: The Payment Gateway Receives and Validates Request
The payment gateway processes the withdrawal request:
Authentication Validation:
- Validates merchant credentials (
merchant_id,token) - Verifies HMAC-SHA256 signature
- Checks timestamp freshness to prevent replay attacks
- Validates merchant credentials (
Request Validation:
- Validates all required fields are present
- Checks amount format and minimum withdrawal threshold
- Validates bank code and account number format
- Verifies merchant has sufficient balance for withdrawal
Creates Withdrawal Order:
- Generates unique platform order ID
- Records all withdrawal details
- Sets initial status to "pending"
Returns Immediate Response:
- Confirms withdrawal request received
- Provides platform order ID for tracking
- Indicates status as "pending"
Example API Response:
{
"success": 200,
"data": {
"platform_order_id": "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"merchant_order_id": "WITHDRAW0123456789",
"status": "pending",
"amount": "5000.00",
"order_datetime": "2024-04-28 14:30:15"
}
}
Important Response Fields:
platform_order_id: the gateway's unique withdrawal order identifierstatus: Initial status is always "pending"order_datetime: Timestamp when withdrawal order was created
Step 5: Merchant Updates Customer Interface
Upon receiving the pending response, the merchant's system should:
Update order status in database:
- Store the
platform_order_idfor reference - Set withdrawal status to "pending"
- Record the request timestamp
- Store the
Display pending status to customer:
- Show clear "withdrawal pending" message
- Display estimated processing time (if applicable)
- Provide the order reference number
- Show updated account balance (with amount already deducted)
Set up status monitoring:
- Prepare to receive webhook notification
- Optionally implement polling mechanism as backup
Example User Message:
✓ Withdrawal Request Submitted
Order ID: WITHDRAW0123456789
Amount: 5,000.00 THB
Status: Pending Processing
Bank: Kasikorn Bank (KBANK)
Account: 1234567890
Your withdrawal is being processed. You will be notified once
the transfer is completed. This typically takes 5-30 minutes
during banking hours.
Step 6: The Payment Gateway Processes Withdrawal
The gateway's system proceeds with the withdrawal processing:
Queue Management:
- Withdrawal enters processing queue
- Queued orders processed in order (typically FIFO)
- Processing time varies based on volume and banking hours
Fraud and Risk Checks:
- Automated fraud detection algorithms
- Unusual pattern detection
- High-risk transaction flagging
- AML/CFT compliance verification
Fund Disbursement:
- Initiates bank transfer to customer's account
- Uses bank API or manual processing depending on bank and amount
- Monitors transfer status
Processing Outcomes:
Scenario A: Successful Disbursement
- Bank confirms successful transfer
- the payment gateway updates order status to "success"
- Proceeds to Step 7 (Success Webhook)
Scenario B: Failed Disbursement
- Bank rejects transfer (invalid account, closed account, etc.)
- Technical issues prevent transfer completion
- the payment gateway updates order status to "failed"
- Proceeds to Step 8 (Failed Webhook)
Step 7: The Payment Gateway Sends Success Webhook
When withdrawal is successfully completed:
Webhook Triggered:
- the payment gateway sends POST request to the
notify_url - Includes complete withdrawal details
- Status indicated as "success"
- the payment gateway sends POST request to the
Webhook Payload:
Example Success Webhook:
{
"platform_order_id": "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"merchant_order_id": "WITHDRAW0123456789",
"status": "success",
"amount": "5000.00",
"completed_datetime": "2024-04-28 14:45:32",
"bank": "KBANK",
"account_no": "1234567890",
"account_name": "สมชาย ใสสว่าง"
}
Merchant's Webhook Handler Should:
- Validate the webhook signature (if implemented)
- Verify the
merchant_order_idmatches a pending withdrawal - Confirm the order hasn't been processed already
- Update order status to "success" in database
- Log the completion timestamp
- Send notification to customer
- Return HTTP 200 OK response to acknowledge receipt
Customer Notification:
- Email/SMS notification of successful withdrawal
- Update account transaction history
- Display success message in user interface
Example Success Message to Customer:
✓ Withdrawal Completed Successfully
Order ID: WITHDRAW0123456789
Amount: 5,000.00 THB
Bank: Kasikorn Bank (KBANK)
Account: 1234567890
Completed: 2024-04-28 14:45:32
The funds have been successfully transferred to your registered
bank account. Please check your bank account to confirm receipt.
For detailed webhook specifications, see Withdraw Callback documentation.
Step 8: The Payment Gateway Sends Failure Webhook
When withdrawal cannot be completed:
Webhook Triggered:
- the payment gateway sends POST request to the
notify_url - Includes withdrawal details and failure reason
- Status indicated as "failed"
- the payment gateway sends POST request to the
Webhook Payload:
Example Failed Webhook:
{
"platform_order_id": "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"merchant_order_id": "WITHDRAW0123456789",
"status": "failed",
"amount": "5000.00",
"failed_datetime": "2024-04-28 14:40:18",
"bank": "KBANK",
"account_no": "1234567890",
"account_name": "สมชาย ใสสว่าง",
"error_message": "Invalid account number or account closed"
}
Merchant's Webhook Handler Should:
- Validate the webhook signature (if implemented)
- Verify the
merchant_order_idmatches a pending withdrawal - Update order status to "failed" in database
- Return withdrawn amount to customer's available balance
- Log the failure reason
- Notify customer of the failure
- Return HTTP 200 OK response to acknowledge receipt
Customer Notification:
- Immediate notification of withdrawal failure
- Clear explanation of the failure reason
- Instructions for resolution
- Confirmation that balance has been restored
Example Failure Message to Customer:
✗ Withdrawal Failed
Order ID: WITHDRAW0123456789
Amount: 5,000.00 THB
Failed: 2024-04-28 14:40:18
Reason: Invalid account number or account closed
Your withdrawal could not be completed. The amount has been
returned to your available balance. Please verify your bank
account details and try again. If the problem persists,
please contact customer support.
Available Balance: 5,000.00 THB (restored)
Alternative Flow: Webhook Not Received
In cases where the webhook notification is not received by the merchant's system:
Option 1: Manual Query Withdrawal Status
The merchant can actively query the withdrawal status:
Implement Polling Mechanism:
- After a reasonable timeout (e.g., 30-60 minutes)
- Send request to
/withdraw/queryendpoint - Include
merchant_order_idorplatform_order_id
Process Response:
- Receive current withdrawal status
- Update order status accordingly
- Take appropriate action based on status
Polling Best Practices:
- Don't poll too frequently (respect rate limits)
- Implement exponential backoff
- Set maximum polling duration
- Stop polling once final status received
Example Query Request:
{
"merchant_id": "AA12345678",
"token": "testtokentesttokentesttokentesttokentesttoken",
"time": 1656272222,
"merchant_order_id": "WITHDRAW0123456789"
}
For detailed specifications, see Query Withdraw Order documentation.
Option 2: Customer Support Escalation
For prolonged pending status without webhook:
- Customer contacts merchant support
- Merchant support queries withdrawal status via API
- Manual resolution if necessary
- Coordinate with the support team if needed
Withdrawal Status States
Status: pending
- Description: Withdrawal request received and queued for processing
- Customer Action: Wait for processing
- Merchant Action: Monitor for webhook notification
- Typical Duration: 5-60 minutes during banking hours
Status: success
- Description: Funds successfully transferred to customer's bank account
- Customer Action: Check bank account for receipt
- Merchant Action: Update order status, notify customer
- Typical Duration: Final state
Status: failed
- Description: Withdrawal could not be completed
- Customer Action: Verify bank details, resubmit if needed
- Merchant Action: Refund amount to customer balance, notify customer
- Typical Duration: Final state
Common Failure Reasons
Invalid Account Information
Causes:
- Incorrect account number
- Account name mismatch
- Closed or suspended account
- Invalid bank code
Resolution:
- Customer updates bank account details
- Merchant revalidates account information
- Resubmit withdrawal request
Insufficient Merchant Balance
Causes:
- Merchant's balance too low
- Pending settlements not yet cleared
Resolution:
- Merchant adds funds to their account
- Wait for pending settlements to clear
- Contact account management
Bank System Issues
Causes:
- Bank API temporarily unavailable
- Banking hours restriction (outside operating hours)
- Bank system maintenance
Resolution:
- Automatic retry by the payment gateway
- Manual processing during next banking hours
- Customer waits for retry/reprocessing
Regulatory or Compliance Blocks
Causes:
- Transaction flagged by fraud detection
- AML/CFT compliance holds
- Regulatory restrictions
Resolution:
- Additional verification required
- Contact the compliance team
- Provide requested documentation
Important Considerations
Balance Management
Immediate Deduction (Recommended Approach):
When customer requests withdrawal, immediately:
- Deduct amount from available balance
- Move to "pending withdrawal" ledger
- Prevents customer from spending same funds twice
On Webhook Receipt:
- If success: Finalize withdrawal, no balance change needed
- If failed: Return amount from "pending" back to "available"
Rationale:
- Prevents overdraft scenarios
- Simplifies accounting
- Protects against system timing issues
Webhook Reliability
Implement Robust Webhook Handler:
Idempotency:
- Check if order already processed
- Prevent duplicate processing
- Use database transactions
Quick Response:
- Return HTTP 200 quickly
- Process business logic asynchronously
- Don't keep connection open
Error Handling:
- Log all webhook receipts
- Handle malformed requests gracefully
- Implement retry mechanism for failed processing
Security:
- Validate webhook signature
- Verify request origin
- Use HTTPS for notify_url
Processing Time Expectations
Normal Processing:
- During Banking Hours: 5-30 minutes
- Outside Banking Hours: Next business day
- Weekends/Holidays: Next business day
Factors Affecting Speed:
- Bank processing capabilities
- Transaction amount (larger amounts may require additional verification)
- Time of day and day of week
- Current transaction volume
Merchant Should:
- Set realistic customer expectations
- Display estimated processing time
- Provide status tracking mechanism
Customer Communication
Proactive Updates:
- Immediate confirmation of withdrawal request
- Status updates at key milestones
- Final confirmation or failure notification
Clear Instructions:
- Expected processing timeline
- What customer should do while waiting
- How to verify receipt in bank account
- Who to contact for issues
Error Handling Best Practices
For Merchants
Webhook Timeout Handling:
- Implement fallback query mechanism
- Set reasonable timeout (e.g., 1-2 hours)
- Query status if webhook not received
Failed Withdrawal Handling:
- Always refund to customer balance
- Provide clear failure reason
- Enable easy resubmission with corrected details
Pending Status Too Long:
- Query status after reasonable time
- Contact support if needed
- Keep customer informed
Database Consistency:
- Use database transactions
- Implement proper locking mechanisms
- Maintain audit trail of all status changes
For Customer Support
Status Inquiry:
- Use query API to check real-time status
- Provide accurate status to customer
- Set appropriate expectations
Escalation Path:
- Define when to escalate to the payment gateway
- Maintain communication log
- Follow up until resolution
Security Considerations
Fraud Prevention
Withdrawal Limits:
- Implement daily/monthly limits
- Higher limits may require additional verification
- Progressive limits based on account age/activity
Velocity Checks:
- Monitor withdrawal frequency
- Flag unusual patterns
- Implement cooling-off periods
Account Verification:
- Verify bank account ownership
- Require verification before first withdrawal
- Periodic re-verification for high-value accounts
Data Protection
Sensitive Information:
- Encrypt bank account details
- Log access to sensitive data
- Comply with data protection regulations
Webhook Security:
- Use HTTPS for all webhook URLs
- Implement signature verification
- Validate all incoming data
Sequence Diagram
Customer Merchant Website Merchant Backend Payment API
| | | |
|--[Request Withdraw]>| | |
| | | |
| |----[Validate Request]--->| |
| | | |
| | [Deduct Balance] |
| | | |
| | |--[POST /withdraw]------>|
| | | |
| | | [Create Order]
| | | [Set PENDING]
| | | |
| | |<--[Pending Response]---|
| | | |
| |<---[Show Pending]--------| |
| | | |
|<--[Pending Status]--| | |
| | | |
| [Wait for Processing...] | |
| | | [Process]
| | | [Bank Transfer]
| | | |
| | | [SUCCESS/FAIL]
| | | |
| | |<--[Webhook Callback]---|
| | | |
| | [Update Status / Refund if Failed] |
| | | |
| | |---[HTTP 200 OK]-------->|
| | | |
|<--[Final Status]----|<---[Notify Customer]-----| |
| | | |
Related Documentation
- Create Withdraw Order - API specification for withdrawal creation
- Withdraw Callback - Webhook notification format and handling
- Query Withdraw Order - Withdrawal status verification
- Authentication - API authentication and signature generation
- Get Balance - Check merchant account balance before withdrawal