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:

  1. Customer navigates to the withdrawal page on the merchant's website
  2. Customer enters the desired withdrawal amount
  3. Customer verifies their registered bank account details
  4. 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:

  1. Account Balance Verification:

    • Verify customer has sufficient balance for withdrawal
    • Check against any withdrawal limits or restrictions
    • Validate minimum withdrawal amount requirements
  2. 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
  3. 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:

  1. 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
  2. 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)
  3. Generate HMAC-SHA256 signature using the merchant's secret key

  4. 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:

  1. Authentication Validation:

    • Validates merchant credentials (merchant_id, token)
    • Verifies HMAC-SHA256 signature
    • Checks timestamp freshness to prevent replay attacks
  2. 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
  3. Creates Withdrawal Order:

    • Generates unique platform order ID
    • Records all withdrawal details
    • Sets initial status to "pending"
  4. 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:

Step 5: Merchant Updates Customer Interface

Upon receiving the pending response, the merchant's system should:

  1. Update order status in database:

    • Store the platform_order_id for reference
    • Set withdrawal status to "pending"
    • Record the request timestamp
  2. 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)
  3. 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:

  1. Queue Management:

    • Withdrawal enters processing queue
    • Queued orders processed in order (typically FIFO)
    • Processing time varies based on volume and banking hours
  2. Fraud and Risk Checks:

    • Automated fraud detection algorithms
    • Unusual pattern detection
    • High-risk transaction flagging
    • AML/CFT compliance verification
  3. Fund Disbursement:

    • Initiates bank transfer to customer's account
    • Uses bank API or manual processing depending on bank and amount
    • Monitors transfer status
  4. 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:

  1. Webhook Triggered:

    • the payment gateway sends POST request to the notify_url
    • Includes complete withdrawal details
    • Status indicated as "success"
  2. 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": "สมชาย ใสสว่าง"
}
  1. Merchant's Webhook Handler Should:

    • Validate the webhook signature (if implemented)
    • Verify the merchant_order_id matches 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
  2. 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:

  1. Webhook Triggered:

    • the payment gateway sends POST request to the notify_url
    • Includes withdrawal details and failure reason
    • Status indicated as "failed"
  2. 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"
}
  1. Merchant's Webhook Handler Should:

    • Validate the webhook signature (if implemented)
    • Verify the merchant_order_id matches 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
  2. 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:

  1. Implement Polling Mechanism:

    • After a reasonable timeout (e.g., 30-60 minutes)
    • Send request to /withdraw/query endpoint
    • Include merchant_order_id or platform_order_id
  2. Process Response:

    • Receive current withdrawal status
    • Update order status accordingly
    • Take appropriate action based on status
  3. 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:

  1. Customer contacts merchant support
  2. Merchant support queries withdrawal status via API
  3. Manual resolution if necessary
  4. Coordinate with the support team if needed

Withdrawal Status States

Status: pending

Status: success

Status: failed

Common Failure Reasons

Invalid Account Information

Causes:

Resolution:

Insufficient Merchant Balance

Causes:

Resolution:

Bank System Issues

Causes:

Resolution:

Regulatory or Compliance Blocks

Causes:

Resolution:

Important Considerations

Balance Management

Immediate Deduction (Recommended Approach):

When customer requests withdrawal, immediately:

  1. Deduct amount from available balance
  2. Move to "pending withdrawal" ledger
  3. Prevents customer from spending same funds twice

On Webhook Receipt:

Rationale:

Webhook Reliability

Implement Robust Webhook Handler:

  1. Idempotency:

    • Check if order already processed
    • Prevent duplicate processing
    • Use database transactions
  2. Quick Response:

    • Return HTTP 200 quickly
    • Process business logic asynchronously
    • Don't keep connection open
  3. Error Handling:

    • Log all webhook receipts
    • Handle malformed requests gracefully
    • Implement retry mechanism for failed processing
  4. Security:

    • Validate webhook signature
    • Verify request origin
    • Use HTTPS for notify_url

Processing Time Expectations

Normal Processing:

Factors Affecting Speed:

Merchant Should:

Customer Communication

Proactive Updates:

Clear Instructions:

Error Handling Best Practices

For Merchants

  1. Webhook Timeout Handling:

    • Implement fallback query mechanism
    • Set reasonable timeout (e.g., 1-2 hours)
    • Query status if webhook not received
  2. Failed Withdrawal Handling:

    • Always refund to customer balance
    • Provide clear failure reason
    • Enable easy resubmission with corrected details
  3. Pending Status Too Long:

    • Query status after reasonable time
    • Contact support if needed
    • Keep customer informed
  4. Database Consistency:

    • Use database transactions
    • Implement proper locking mechanisms
    • Maintain audit trail of all status changes

For Customer Support

  1. Status Inquiry:

    • Use query API to check real-time status
    • Provide accurate status to customer
    • Set appropriate expectations
  2. Escalation Path:

    • Define when to escalate to the payment gateway
    • Maintain communication log
    • Follow up until resolution

Security Considerations

Fraud Prevention

  1. Withdrawal Limits:

    • Implement daily/monthly limits
    • Higher limits may require additional verification
    • Progressive limits based on account age/activity
  2. Velocity Checks:

    • Monitor withdrawal frequency
    • Flag unusual patterns
    • Implement cooling-off periods
  3. Account Verification:

    • Verify bank account ownership
    • Require verification before first withdrawal
    • Periodic re-verification for high-value accounts

Data Protection

  1. Sensitive Information:

    • Encrypt bank account details
    • Log access to sensitive data
    • Comply with data protection regulations
  2. 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