# Deploy — Wallet History + Wallet to Bank (withdrawal system)

## 1. NEW files (4)

| File | Purpose |
|---|---|
| `includes/bank.php` | Withdrawal engine — schema, bank account CRUD, KYC prefill, withdrawal create/approve/reject with refund, settings |
| `includes/bank_view.php` | The two user-facing tabs (Wallet to Bank + Wallet History), fully mobile responsive |
| `admin/withdrawals.php` | Admin page — Bank Request Pending / Transaction Update / Settings |
| `wallettomigration.php` | Migration — run once, then delete |

## 2. MODIFIED files (21)

| File | What changed |
|---|---|
| `includes/theme.php` | Wallet menu: added **Wallet History** and **Wallet to Bank** |
| `wallet.php` | New `#to_bank` and `#wallet_history` tabs, POST handler |
| `seller/wallet.php` | Same, seller side |
| 18 × `admin/*.php` | Sidebar links to **Bank Request Pending** and **Transaction Update** |

Admin files touched for the sidebar: `commissions, index, orders, pending_services, profile, refer, reports, roles, sellers, services, settings, staff, tickets, transactions, upgrade_requests, users, wallet, wallet_history`.

## 3. Also create this folder

```
uploads/bank/          permission 755
```

The migration creates it automatically, but check it exists — passbook and cheque uploads go here.

## 4. Run the migration

```
https://yourdomain.com/wallettomigration.php
```

**Delete the file afterwards.**

### New table `bank_accounts` — one row per user

| Column | Type | Notes |
|---|---|---|
| `id` | `INT AUTO_INCREMENT PK` | |
| `user_id` | `INT NOT NULL` | **UNIQUE** — one bank account per user |
| `holder_name` | `VARCHAR(150)` | |
| `bank_name` / `branch_name` | `VARCHAR(150)` | |
| `account_number` / `confirm_account` | `VARCHAR(50)` | |
| `ifsc_code` | `VARCHAR(30)` | |
| `account_type` | `VARCHAR(20)` | savings / current |
| `mobile` | `VARCHAR(20)` | |
| `upi_id` | `VARCHAR(120)` | optional |
| `passbook` | `VARCHAR(255)` | uploaded file path |
| `status` | `TINYINT(1)` | **0 = pending, 1 = verified, 2 = rejected** |
| `admin_remark` | `TEXT` | rejection reason |
| `reviewed_by` / `reviewed_by_name` / `reviewed_at` | | audit |
| `created_at` / `updated_at` | | |

### New table `withdrawal_requests`

| Column | Type | Notes |
|---|---|---|
| `id` | `INT AUTO_INCREMENT PK` | |
| `user_id`, `bank_account_id` | `INT` | |
| `reference_no` | `VARCHAR(40) UNIQUE` | e.g. `WD2608014F2A9C` |
| `amount` | `DECIMAL(10,2)` | what the user asked for |
| `charge` | `DECIMAL(10,2)` | service charge |
| `net_amount` | `DECIMAL(10,2)` | what actually gets transferred |
| `bank_name`, `account_number`, `ifsc_code`, `holder_name` | | snapshot, so later bank edits don't rewrite history |
| `status` | `VARCHAR(20)` | **pending / processing / approved / rejected** |
| `utr_number` | `VARCHAR(60)` | bank transfer reference |
| `admin_remark` | `TEXT` | |
| `reviewed_by` / `reviewed_by_name` / `reviewed_at` | | |
| `created_at` | | |

### New `settings` rows

| Key | Default | Meaning |
|---|---|---|
| `withdraw_enabled` | `1` | 1 = on, 0 = temporarily off |
| `withdraw_min` | `100` | Minimum per request (₹) |
| `withdraw_max` | `50000` | Maximum per request, `0` = no limit |
| `withdraw_charge_type` | `none` | `none` / `percent` / `fixed` |
| `withdraw_charge_value` | `0` | e.g. `2` = 2%, or `10` = ₹10 |
| `withdraw_note` | text | Message shown to users |

All editable from **Admin → Wallet Management → Transaction Update → Settings**.

No existing table or column is altered.

## 5. How the flow works

### Step 1 — user adds a bank account

**Wallet → Wallet to Bank**

- **Bank details already in KYC** → the popup opens **pre-filled** with the KYC bank name, branch, account number, IFSC and full name. A green banner says "Filled in from your KYC bank details".
- **Nothing on file** → blank popup, every field mandatory.

Fields: holder name, bank name, branch, account number, **re-enter account number** (live match check — red/green), IFSC (format validated `SBIN0001234`), account type, registered mobile (10 digits), UPI (optional), passbook/cheque upload.

Submitting creates the record with **status = pending**.

### Step 2 — admin verifies

**Admin → Wallet Management → Bank Request Pending**

Each request card shows the user, bank and account. **Details** opens a panel that also shows the KYC name/account and a **"Match with KYC"** line so you can cross-check in one glance.

- **Approve** → status verified, user notified, withdrawal unlocks
- **Reject** → reason required (5 quick-reason buttons), user sees it and can correct and resubmit

### Step 3 — user withdraws

Once verified, the withdrawal form appears:

- Bank shown as a selectable card
- Amount field with quick chips (₹500 / ₹1000 / ₹2000 / ₹5000 / All)
- **Live breakdown**: requested → service charge → you will receive → wallet after this
- Live validation for min, max and insufficient balance — the submit button stays disabled until valid

On submit the money leaves the **main wallet immediately** and a request is created with **status = Pending**.

> Only the **main wallet** is withdrawable. The **virtual (referral) wallet is never touched**, even if it has a balance — the error message says so explicitly.

A second request is blocked while one is still pending.

### Step 4 — admin updates the transaction

**Admin → Wallet Management → Transaction Update**

- **Update** → shows the exact payable amount, asks for the **UTR / reference number** (mandatory), then marks it **Approved & Sent Successfully**
- **Processing** → intermediate state while the transfer is in flight
- **Reject** → reason mandatory, and the **full requested amount is refunded** to the user's main wallet with a `refund` ledger entry

Every action notifies the user.

### Step 5 — what the user sees

A **Transaction Status** card shows the latest request: big status icon, net amount, reference no., requested date, charge, bank, UTR, and last-updated time.

- Approved → green "Money sent to your bank successfully"
- Rejected → red "₹X refunded to your wallet" with the admin's reason

Below it, the full **Transaction History** — a table on desktop, stacked cards on mobile.

### Wallet History tab

Reads the `wallet_ledger` — every movement in **both** wallets. Four summary cards (total balance, money in, money out, entries), filters for wallet / type / category / date range, and a running-balance column. Table on desktop, stacked cards on mobile.

## 6. Mobile responsiveness

- Popups slide up from the bottom on phones, centre on desktop
- Every table has a card-based mobile layout (no horizontal scrolling)
- The 3-step progress rail (Add Bank → Admin Verify → Withdraw) shrinks on narrow screens
- Grids collapse 4 → 2 columns, forms 2 → 1 column
- Touch-friendly button and input sizes throughout

## 7. Post-deploy check

1. Run `wallettomigration.php` → verification table at the bottom should be all green → delete the file.
2. **Wallet → Wallet to Bank** as a user with bank details in KYC → the popup should open pre-filled.
3. Submit → status shows "Awaiting Verification", withdrawal form hidden.
4. **Admin → Bank Request Pending** → open **Details**, check the "Match with KYC" line → **Approve**.
5. Back as the user → withdrawal form appears. Try ₹50 → blocked by the minimum. Try more than the main wallet → blocked with the shortfall shown.
6. Submit a valid amount → main wallet drops immediately, status card shows **Pending**.
7. **Admin → Transaction Update** → **Update** → enter a UTR → status becomes **Approved & Sent Successfully** on the user's side.
8. Make another request and **Reject** it → the full amount returns to the user's wallet and appears in Wallet History as a `Refund`.
9. **Settings** tab → set charge to 2% → the user's live breakdown should show the fee and net amount.
