Staging Test: Withdrawal Flow

Test Area: Withdrawal Flow
Estimated Time: 20-25 minutes
Difficulty: Medium
Prerequisites: Complete 03-deposit-flow first. Investor needs active tranches with available profit/principal.

Overview

This guide tests the withdrawal request system. Investors can withdraw:
  • Profit from active tranches
  • Principal from matured tranches
  • Referral Bonuses from bonus wallet

Withdrawal Lifecycle

Standard Users (Individual, KYC-verified):
Submit Withdrawal → REQUESTED → Admin Approves → IN_PROCESS → Admin Sends Payout → COMPLETED

                               (If rejected) → REJECTED (funds returned)
Institution Users (require two-admin approval):
Submit Withdrawal → REQUESTED → First Admin Approves → AWAITING_SECOND_APPROVAL

                                     Second Admin Approves → IN_PROCESS → COMPLETED

                                    (Same admin cannot second-approve)

Withdrawal Types

TypeSourceWhen Available
PROFITTranche available_profitAnytime (if profit > 0)
PRINCIPALTranche principalAfter lock-in ends (matured)
REFERRAL_BONUSBonus walletAnytime (if balance > 0)
Minimum Withdrawal: $25 (enforced for all withdrawal types)

Before You Start

URLs

PageURL
Loginhttps://zestamc.savibm.com/login
Investor Withdrawalshttps://zestamc.savibm.com/investor/withdrawals
Admin Withdrawalshttps://zestamc.savibm.com/admin/withdrawals

Test Accounts

RoleEmailOTP
Investortestinvestor@zestamc.comCheck email
Adminadmin@zestamc.comCheck email

Current Test Data

UserPrincipalAvailable ProfitBonus Balance
testinvestor$10,000$0 (initial)$0 (initial)
Note: Available profit will be $0 until a profit distribution cycle is run. Test profit withdrawal after running a cycle (see 06-profit-distribution.md).

Test Cases

Test 1: View Withdrawals Page

Goal: Verify investor can access the withdrawals page Steps:
  1. Log in as testinvestor@zestamc.com
  2. Click “Withdrawals” in the left sidebar
  3. View the withdrawals page
Expected Results:
ElementWhat You Should See
Page title”Withdrawals”
Withdrawal historyList of past withdrawal requests (may be empty)
New withdrawal button”Request Withdrawal” or similar button
Available amountsShows available profit/principal/bonus
Pass Criteria: ✅ Withdrawals page loads with all elements

Test 2: View Available Withdrawal Sources

Goal: Verify investor can see what’s available to withdraw Steps:
  1. On the Withdrawals page
  2. Click “Request Withdrawal” button
  3. Look at the available sources
Expected Results:
SourceWhat You Should See
Profit sourcesList of tranches with available profit
Principal sourcesList of matured tranches (if any)
Bonus walletReferral bonus balance
AmountsDollar amounts for each source
Pass Criteria: ✅ Can see available withdrawal sources with amounts

Test 3: Submit Profit Withdrawal

Goal: Verify investor can submit a profit withdrawal Preparation: This test requires available profit. If available_profit is $0, first run a profit distribution cycle (see 06-profit-distribution.md). Steps:
  1. Log in as testinvestor@zestamc.com
  2. Go to “Withdrawals” page
  3. Click “Request Withdrawal”
  4. Select source: Choose a tranche with available profit
  5. Select type: “Profit”
  6. Enter amount (e.g., 25 or whatever’s available)
  7. Click “Submit”
  8. When OTP dialog appears, enter OTP from email
  9. Confirm
Expected Results:
StepWhat You Should See
Amount validationAccepts amount up to available profit
After OTPSuccess message “Withdrawal request submitted”
StatusNew withdrawal shows “REQUESTED” status
Pass Criteria: ✅ Profit withdrawal request submitted

Test 4: Submit Referral Bonus Withdrawal

Goal: Verify investor can withdraw from bonus wallet Preparation:
  • Feature Flag Required: This test requires the referral feature to be enabled:
    • Backend: FEATURE_REFERRAL_ENABLED=true
    • Frontend: VITE_FEATURE_REFERRAL_ENABLED=true (requires rebuild)
  • Requires bonus balance > 0. Run a profit distribution cycle with referrals to generate bonus balance.
Note: If the referral feature is disabled, this test will fail with a 403 error. The bonus wallet option will not appear in the withdrawal sources list.
Steps:
  1. Log in as testinvestor@zestamc.com
  2. Go to “Withdrawals” page
  3. Click “Request Withdrawal”
  4. Select source: “Bonus Wallet” or “Referral Bonus”
  5. Enter amount
  6. Click “Submit”
  7. Enter OTP from email
Expected Results:
StepWhat You Should See
Bonus optionBonus wallet shows as withdrawal source
Amount limitCannot exceed bonus balance
After submitSuccess message
StatusShows “REQUESTED”
Pass Criteria: ✅ Bonus withdrawal request submitted

Test 5: View Withdrawal History

Goal: Verify investor can see their withdrawal requests Steps:
  1. On the Withdrawals page
  2. Look at the withdrawal history list
  3. Find your recent withdrawal requests
Expected Results:
ElementWhat You Should See
ListShows all withdrawal requests
DetailsAmount, type, status, date visible
Status badgesColor-coded status (yellow=pending, green=completed)
Pass Criteria: ✅ Withdrawal history displays correctly

Test 6: Admin Views Pending Withdrawals

Goal: Verify admin can see pending withdrawal requests Steps:
  1. Log out and log in as admin@zestamc.com
  2. Navigate to Admin → “Withdrawals” or “Withdrawal Approvals”
  3. Look for pending withdrawals
Expected Results:
ElementWhat You Should See
Pending listWithdrawals with REQUESTED status
DetailsUser email, amount, type, wallet address
ActionsApprove/Reject buttons
Pass Criteria: ✅ Admin can see pending withdrawals

Test 7: Admin Approves Withdrawal (Standard User)

Goal: Verify admin can approve a withdrawal for standard (non-institution) users Steps:
  1. Log in as admin@zestamc.com
  2. Go to “Withdrawal Approvals” (table view)
  3. Find a pending withdrawal from a standard user
  4. Click “Approve”
  5. Confirm
Expected Results:
StepWhat You Should See
After approveSuccess message
Status changeWithdrawal status → IN_PROCESS
Wallet infoUser’s wallet address shown for payout
Payout button”Send Payout” button becomes available
Pass Criteria: ✅ Withdrawal approved and moved to IN_PROCESS (single approval)

Test 8: Admin Sends Payout

Goal: Verify admin can trigger NOWPayments payout for approved withdrawal Steps:
  1. Find the IN_PROCESS withdrawal from Test 7
  2. Click “Send Payout”
  3. Select payout network/currency if prompted
  4. Confirm
Expected Results:
StepWhat You Should See
Payout dialogShows amount, wallet address, network
After sendSuccess message “Payout initiated”
StatusStays IN_PROCESS (waiting for blockchain)
NOWPayments IDPayout ID shown for tracking
Pass Criteria: ✅ Payout triggered via NOWPayments

Test 9: Admin Completes Withdrawal Manually

Goal: Verify admin can manually complete a withdrawal (fallback if payout fails) Steps:
  1. Find an IN_PROCESS withdrawal
  2. Click “Complete Manually” or “Mark Complete”
  3. Enter transaction hash: 0xCOMPLETE1234567890abcdef1234567890abcdef1234567890abcdef12345678
  4. Add optional notes
  5. Confirm
Expected Results:
StepWhat You Should See
TX hash fieldRequired input
After completeSuccess message
Status changeWithdrawal status → COMPLETED
HistoryMoves to completed withdrawals
Pass Criteria: ✅ Withdrawal completed manually with TX hash

Test 10: Investor Sees Completed Withdrawal

Goal: Verify investor can see their completed withdrawal Steps:
  1. Log in as testinvestor@zestamc.com
  2. Go to “Withdrawals” page
  3. Find the completed withdrawal
Expected Results:
ResultWhat You Should See
StatusShows “COMPLETED” with green badge
Transaction infoMay show payment transaction hash
Pass Criteria: ✅ Investor sees completed status

Test 11: Admin Rejects Withdrawal

Goal: Verify admin can reject a withdrawal Preparation: Submit a new withdrawal request as investor first Steps:
  1. Submit a new withdrawal as testinvestor@zestamc.com
  2. Log in as admin@zestamc.com
  3. Go to “Withdrawal Approvals”
  4. Find the pending withdrawal
  5. Click “Reject”
  6. Enter reason: “Test rejection - suspicious activity”
  7. Confirm
Expected Results:
StepWhat You Should See
Reject promptRequires rejection reason
After rejectSuccess message
StatusWithdrawal shows REJECTED
FundsAmount returned to source (profit/bonus)
Pass Criteria: ✅ Withdrawal rejected and funds returned

Test 12: Withdrawal Amount Validation

Goal: Verify system validates withdrawal amounts Steps:
  1. Log in as testinvestor@zestamc.com
  2. Start a new withdrawal request
  3. Try to enter an amount greater than available
Expected Results:
TestWhat You Should See
Exceeds availableError: “Insufficient balance” or similar
FormPrevents submission
Pass Criteria: ✅ Cannot withdraw more than available

Test 13: Withdrawal Requires Wallet

Goal: Verify system requires approved wallet for withdrawal Note: Only applicable if testing with account that has no approved wallet Steps:
  1. Try to submit a withdrawal without an approved wallet
  2. Observe the error
Expected Results:
ResultWhat You Should See
Error”Please add a wallet address first”
No submissionCannot proceed without wallet
Pass Criteria: ✅ System requires approved wallet

Test 14: Institution User - First Admin Approval

Goal: Verify institution user withdrawals require two-admin approval Preparation: Need an institution user account with withdrawal capability. If not available, skip this test. Steps:
  1. Log in as an institution user
  2. Submit a withdrawal request
  3. Log in as admin@zestamc.com
  4. Go to “Withdrawal Approvals”
  5. Find the institution user’s withdrawal
  6. Click “Approve”
  7. Confirm
Expected Results:
StepWhat You Should See
User type indicatorShows “INSTITUTION” badge on the withdrawal
After first approveSuccess message: “First approval recorded”
Status changeWithdrawal status → AWAITING_SECOND_APPROVAL
UI indicationShows “Needs second approval” or similar
Pass Criteria: ✅ First approval moves to AWAITING_SECOND_APPROVAL (not IN_PROCESS)

Test 15: Institution User - Second Admin Approval

Goal: Verify second admin can complete institution withdrawal approval Preparation: Complete Test 14 first Steps:
  1. Log in as a different admin (e.g., second admin account)
  2. Go to “Withdrawal Approvals”
  3. Find the withdrawal in AWAITING_SECOND_APPROVAL status
  4. Click “Approve” (second approval)
  5. Confirm
Expected Results:
StepWhat You Should See
Second approvalSuccess message
Status changeWithdrawal status → IN_PROCESS
Ready for payout”Send Payout” button now available
Pass Criteria: ✅ Second admin approval completes the approval process

Test 16: Institution User - Same Admin Cannot Second-Approve

Goal: Verify same admin cannot provide both approvals Preparation: Have an institution withdrawal in AWAITING_SECOND_APPROVAL status Steps:
  1. Log in as the admin who gave the first approval
  2. Go to “Withdrawal Approvals”
  3. Find the withdrawal in AWAITING_SECOND_APPROVAL
  4. Try to click “Approve” again
Expected Results:
ResultWhat You Should See
Error”Same admin cannot provide second approval” or disabled
No approvalStatus remains AWAITING_SECOND_APPROVAL
Pass Criteria: ✅ System prevents same admin from second-approving

Test Results Summary

TestStatusNotes
Test 1: View Page⬜ Pass / ⬜ Fail
Test 2: View Sources⬜ Pass / ⬜ Fail
Test 3: Profit Withdrawal⬜ Pass / ⬜ Fail
Test 4: Bonus Withdrawal⬜ Pass / ⬜ Fail
Test 5: View History⬜ Pass / ⬜ Fail
Test 6: Admin View⬜ Pass / ⬜ Fail
Test 7: Admin Approve (Standard)⬜ Pass / ⬜ Fail
Test 8: Admin Send Payout⬜ Pass / ⬜ Fail
Test 9: Admin Complete Manually⬜ Pass / ⬜ Fail
Test 10: Investor Verify⬜ Pass / ⬜ Fail
Test 11: Admin Reject⬜ Pass / ⬜ Fail
Test 12: Amount Validation⬜ Pass / ⬜ Fail
Test 13: Wallet Required⬜ Pass / ⬜ Fail
Test 14: Institution First Approve⬜ Pass / ⬜ Fail
Test 15: Institution Second Approve⬜ Pass / ⬜ Fail
Test 16: Same Admin Prevention⬜ Pass / ⬜ Fail

Important Notes

Testing Withdrawals Without Profit

If available profit is $0, you need to first run a profit distribution cycle:
  1. Log in as admin
  2. Go to Cycles page
  3. Create, start, set rate, and distribute a cycle
  4. This generates profit that can be withdrawn
See 06-profit-distribution.md for detailed instructions.

Principal Withdrawal

Principal can only be withdrawn from matured tranches (lock-in period ended). The test tranches may still be in lock-in period.

Referral Bonus Withdrawal (Test 4)

Feature Flag Dependency: Referral bonus withdrawals require the referral feature to be enabled:
  • Backend: Set FEATURE_REFERRAL_ENABLED=true in environment variables
  • Frontend: Set VITE_FEATURE_REFERRAL_ENABLED=true and rebuild the application
If the feature is disabled:
  • Bonus wallet will not appear as a withdrawal source
  • Attempting to submit a referral bonus withdrawal will return a 403 error
  • The error message: “Referral bonus withdrawals are currently disabled”
To test referral bonus withdrawals, ensure both feature flags are enabled before starting Test 4.

Troubleshooting

”Minimum withdrawal is $25” error

Withdrawal amount must be at least $25.

”Insufficient balance” error

The amount you’re trying to withdraw exceeds what’s available. Check:
  1. Available profit in the selected tranche
  2. Bonus wallet balance
  3. Matured principal (if withdrawing principal)

“Please add a wallet” error

  1. Go to Wallets page and add a wallet
  2. Wait for admin approval
  3. Then try withdrawing

Withdrawal stuck in REQUESTED

Admin needs to approve the withdrawal. Log in as admin and process it.

Withdrawal stuck in AWAITING_SECOND_APPROVAL

This is an institution user withdrawal. A different admin must provide the second approval.

No profit available to withdraw

Run a profit distribution cycle first. See 06-profit-distribution.md.

Payout failed

If NOWPayments payout fails, admin can:
  1. Retry the payout with “Send Payout” button
  2. Complete manually with a transaction hash from external wallet

”Referral bonus withdrawals are currently disabled” error (Test 4)

This error occurs when trying to withdraw referral bonuses but the feature flag is disabled:
  1. Check backend environment: FEATURE_REFERRAL_ENABLED must be true
  2. Check frontend environment: VITE_FEATURE_REFERRAL_ENABLED must be true
  3. Rebuild frontend if you changed VITE_FEATURE_REFERRAL_ENABLED
  4. Restart backend if you changed FEATURE_REFERRAL_ENABLED
If you don’t need to test referral withdrawals, you can skip Test 4.

Next Steps

After completing withdrawal flow testing, proceed to: