# UPI & Top-Up Request API Documentation

Base URL: `https://api.alldigtalseva.com`

---

## Table of Contents

1. [UPI Management APIs (Admin)](#upi-management-apis-admin)
2. [UPI List API (Public/User)](#upi-list-api-publicuser)
3. [Top-Up Request APIs (User)](#top-up-request-apis-user)
4. [Top-Up Request Management APIs (Admin)](#top-up-request-management-apis-admin)

---

## UPI Management APIs (Admin)

All UPI management endpoints require admin authentication via Bearer token.

### Get All UPIs

Retrieve all available UPIs.

**Endpoint:** `GET /api/admin/upi`

**Headers:**
```
Authorization: Bearer {admin_token}
```

**Success Response (200):**
```json
{
    "success": true,
    "data": [
        {
            "id": 1,
            "upi_id": "user@paytm",
            "name": "Main UPI",
            "status": "active",
            "is_default": true,
            "created_by": 1,
            "created_at": "2025-12-04T07:10:45.000000Z",
            "updated_at": "2025-12-04T07:10:45.000000Z"
        }
    ]
}
```

**cURL Example:**
```bash
curl -X GET https://api.alldigtalseva.com/api/admin/upi \
  -H "Authorization: Bearer {admin_token}"
```

---

### Add New UPI

Add a new UPI for users to use for top-up requests.

**Endpoint:** `POST /api/admin/upi`

**Headers:**
```
Authorization: Bearer {admin_token}
Content-Type: application/json
```

**Request Body:**
```json
{
    "upi_id": "user@paytm",
    "name": "Main UPI Account",
    "status": "active",
    "is_default": true
}
```

**Parameters:**
- `upi_id` (required, string, unique): The UPI ID (e.g., "user@paytm", "user@phonepe")
- `name` (optional, string): Display name for the UPI
- `status` (optional, enum): `"active"` or `"inactive"` (default: `"active"`)
- `is_default` (optional, boolean): Set as default UPI (default: `false`)

**Success Response (201):**
```json
{
    "success": true,
    "message": "UPI added successfully",
    "data": {
        "id": 1,
        "upi_id": "user@paytm",
        "name": "Main UPI Account",
        "status": "active",
        "is_default": true,
        "created_by": 1,
        "created_at": "2025-12-04T07:10:45.000000Z",
        "updated_at": "2025-12-04T07:10:45.000000Z"
    }
}
```

**cURL Example:**
```bash
curl -X POST https://api.alldigtalseva.com/api/admin/upi \
  -H "Authorization: Bearer {admin_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "upi_id": "user@paytm",
    "name": "Main UPI Account",
    "status": "active",
    "is_default": true
  }'
```

---

### Update UPI

Update an existing UPI.

**Endpoint:** `PUT /api/admin/upi/{id}` or `PATCH /api/admin/upi/{id}`

**Headers:**
```
Authorization: Bearer {admin_token}
Content-Type: application/json
```

**Request Body (all fields optional):**
```json
{
    "upi_id": "updated@paytm",
    "name": "Updated UPI Name",
    "status": "inactive",
    "is_default": false
}
```

**Success Response (200):**
```json
{
    "success": true,
    "message": "UPI updated successfully",
    "data": {
        "id": 1,
        "upi_id": "updated@paytm",
        "name": "Updated UPI Name",
        "status": "inactive",
        "is_default": false,
        "created_by": 1,
        "created_at": "2025-12-04T07:10:45.000000Z",
        "updated_at": "2025-12-04T07:11:00.000000Z"
    }
}
```

**cURL Example:**
```bash
curl -X PUT https://api.alldigtalseva.com/api/admin/upi/1 \
  -H "Authorization: Bearer {admin_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "upi_id": "updated@paytm",
    "status": "inactive"
  }'
```

---

### Get Single UPI

Get details of a specific UPI.

**Endpoint:** `GET /api/admin/upi/{id}`

**Headers:**
```
Authorization: Bearer {admin_token}
```

**Success Response (200):**
```json
{
    "success": true,
    "data": {
        "id": 1,
        "upi_id": "user@paytm",
        "name": "Main UPI",
        "status": "active",
        "is_default": true,
        "created_by": 1,
        "created_at": "2025-12-04T07:10:45.000000Z",
        "updated_at": "2025-12-04T07:10:45.000000Z"
    }
}
```

---

### Delete UPI

Delete a UPI.

**Endpoint:** `DELETE /api/admin/upi/{id}`

**Headers:**
```
Authorization: Bearer {admin_token}
```

**Success Response (200):**
```json
{
    "success": true,
    "message": "UPI deleted successfully"
}
```

---

## UPI List API (Public/User)

### Get Available UPIs

Get list of all active UPIs that users can select for top-up requests. This is a public endpoint - no authentication required.

**Endpoint:** `GET /api/upi/list`

**Success Response (200):**
```json
{
    "success": true,
    "data": [
        {
            "id": 1,
            "upi_id": "user@paytm",
            "name": "Main UPI",
            "is_default": true
        },
        {
            "id": 2,
            "upi_id": "payment@phonepe",
            "name": "PhonePe UPI",
            "is_default": false
        }
    ]
}
```

**Note:** Only active UPIs are returned. Inactive UPIs are filtered out.

**cURL Example:**
```bash
curl -X GET https://api.alldigtalseva.com/api/upi/list
```

**JavaScript/Fetch Example:**
```javascript
fetch('https://api.alldigtalseva.com/api/upi/list')
  .then(response => response.json())
  .then(data => {
    if (data.success) {
      console.log('Available UPIs:', data.data);
      // Display UPIs in dropdown/select for user to choose
      data.data.forEach(upi => {
        console.log(`UPI ID: ${upi.upi_id}, Name: ${upi.name}`);
      });
    }
  })
  .catch(error => {
    console.error('Error fetching UPIs:', error);
  });
```

**Angular Example:**
```typescript
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class UpiService {
  private apiUrl = 'https://api.alldigtalseva.com/api';

  constructor(private http: HttpClient) {}

  getAvailableUpis(): Observable<any> {
    return this.http.get<any>(`${this.apiUrl}/upi/list`);
  }
}

// Usage in Component
this.upiService.getAvailableUpis().subscribe({
  next: (response) => {
    if (response.success) {
      this.upis = response.data;
      // Set default UPI if available
      const defaultUpi = this.upis.find((u: any) => u.is_default);
      if (defaultUpi) {
        this.selectedUpiId = defaultUpi.id;
      }
    }
  },
  error: (error) => {
    console.error('Failed to load UPIs:', error);
  }
});
```

**React Example:**
```javascript
import { useState, useEffect } from 'react';

function TopUpForm() {
  const [upis, setUpis] = useState([]);
  const [selectedUpi, setSelectedUpi] = useState('');

  useEffect(() => {
    fetch('https://api.alldigtalseva.com/api/upi/list')
      .then(res => res.json())
      .then(data => {
        if (data.success) {
          setUpis(data.data);
          // Set default UPI
          const defaultUpi = data.data.find(u => u.is_default);
          if (defaultUpi) {
            setSelectedUpi(defaultUpi.id);
          }
        }
      });
  }, []);

  return (
    <select value={selectedUpi} onChange={(e) => setSelectedUpi(e.target.value)}>
      <option value="">Select UPI</option>
      {upis.map(upi => (
        <option key={upi.id} value={upi.id}>
          {upi.name} - {upi.upi_id}
        </option>
      ))}
    </select>
  );
}
```

---

## Top-Up Request APIs (User)

### Request Top-Up

Submit a top-up request. User selects a UPI and requests a top-up amount. Admin will approve or reject the request.

**Note:** Before making a top-up request, use `GET /api/upi/list` to get available UPIs and their IDs.

**Endpoint:** `POST /api/top-up/request`

**Headers:**
```
Content-Type: application/json
```

**Request Body:**
```json
{
    "user_id": 1,
    "upi_id": 1,
    "amount": 500.00,
    "recharge_offer_id": 1
}
```

**Parameters:**
- `user_id` (required, integer): ID of the user requesting top-up
- `upi_id` (required, integer): ID of the UPI to use for payment
- `amount` (required, numeric, min: 0.01): Top-up amount
- `recharge_offer_id` (optional, integer): ID of the recharge offer to apply (see [Recharge Offer API](#recharge-offer-integration))
- `amount` (required, numeric, min: 0.01): Amount to top-up

**Success Response (201):**
```json
{
    "success": true,
    "message": "Top-up request submitted successfully. Waiting for admin approval.",
    "data": {
        "request_id": 1,
        "user_id": 1,
        "upi_id": 1,
        "upi_details": {
            "upi_id": "user@paytm",
            "name": "Main UPI"
        },
        "amount": "500.00",
        "status": "pending",
        "created_at": "2025-12-04T07:20:00.000000Z",
        "offer_applied": {
            "offer_id": 1,
            "offer_title": "Festive Recharge Offer",
            "discount_amount": 50,
            "cashback_amount": "25.00",
            "final_credited_amount": 575,
            "benefit_description": "10.00% discount = ₹50 + ₹25.00 cashback"
        }
    }
}
```

**Note:** The `offer_applied` field is only present if a recharge offer was applied. If no offer is applied, this field will not be included in the response.
```

**Error Response (400) - Pending Request Exists:**
```json
{
    "success": false,
    "message": "You already have a pending top-up request. Please wait for admin approval."
}
```

**Error Response (400) - UPI Not Active:**
```json
{
    "success": false,
    "message": "Selected UPI is not active"
}
```

**Error Response (403) - User Not Verified:**
```json
{
    "success": false,
    "message": "User is not verified. Please complete signup first."
}
```

**cURL Example:**
```bash
curl -X POST https://api.alldigtalseva.com/api/top-up/request \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": 1,
    "upi_id": 1,
    "amount": 500.00
  }'
```

---

### Get User's Top-Up Requests

Get all top-up requests for a specific user.

**Endpoint:** `GET /api/top-up/requests?user_id={user_id}`

**Query Parameters:**
- `user_id` (required, integer): ID of the user

**Success Response (200):**
```json
{
    "success": true,
    "data": [
        {
            "id": 1,
            "user_id": 1,
            "upi_id": 1,
            "amount": "500.00",
            "status": "approved",
            "rejection_reason": null,
            "approved_by": 1,
            "approved_at": "2025-12-04T07:25:00.000000Z",
            "created_at": "2025-12-04T07:20:00.000000Z",
            "updated_at": "2025-12-04T07:25:00.000000Z",
            "upi": {
                "id": 1,
                "upi_id": "user@paytm",
                "name": "Main UPI"
            },
            "admin": {
                "id": 1,
                "username": "admin",
                "email": "admin@alldigtalseva.com"
            }
        }
    ]
}
```

**cURL Example:**
```bash
curl -X GET "https://api.alldigtalseva.com/api/top-up/requests?user_id=1" \
  -H "Content-Type: application/json"
```

---

### Get Single Top-Up Request

Get details of a specific top-up request.

**Endpoint:** `GET /api/top-up/request/{id}`

**Success Response (200):**
```json
{
    "success": true,
    "data": {
        "id": 1,
        "user_id": 1,
        "upi_id": 1,
        "amount": "500.00",
        "status": "pending",
        "rejection_reason": null,
        "approved_by": null,
        "approved_at": null,
        "created_at": "2025-12-04T07:20:00.000000Z",
        "updated_at": "2025-12-04T07:20:00.000000Z",
        "user": {
            "id": 1,
            "email": "user@example.com",
            "phone_number": "1234567890"
        },
        "upi": {
            "id": 1,
            "upi_id": "user@paytm",
            "name": "Main UPI"
        },
        "admin": null
    }
}
```

---

### Get Wallet Top-Up History

Get complete history of wallet top-up requests with summary statistics.

**Endpoint:** `GET /api/wallet/top-up/history`

**Query Parameters:**
- `user_id` (required, integer): ID of the user
- `status` (optional, enum): Filter by status - `"pending"`, `"approved"`, or `"rejected"`
- `limit` (optional, integer, 1-100): Number of records to return (default: 50)

**Success Response (200):**
```json
{
    "success": true,
    "summary": {
        "total_requests": 10,
        "pending": 2,
        "approved": 7,
        "rejected": 1,
        "total_approved_amount": "5000.00"
    },
    "data": [
        {
            "id": 10,
            "user_id": 1,
            "upi_id": 1,
            "amount": "1000.00",
            "status": "approved",
            "rejection_reason": null,
            "approved_by": 1,
            "approved_at": "2025-12-04T08:00:00.000000Z",
            "created_at": "2025-12-04T07:55:00.000000Z",
            "updated_at": "2025-12-04T08:00:00.000000Z",
            "upi": {
                "id": 1,
                "upi_id": "user@paytm",
                "name": "Main UPI"
            },
            "admin": {
                "id": 1,
                "username": "admin",
                "email": "admin@alldigtalseva.com"
            }
        },
        {
            "id": 9,
            "user_id": 1,
            "upi_id": 2,
            "amount": "500.00",
            "status": "pending",
            "rejection_reason": null,
            "approved_by": null,
            "approved_at": null,
            "created_at": "2025-12-04T07:50:00.000000Z",
            "updated_at": "2025-12-04T07:50:00.000000Z",
            "upi": {
                "id": 2,
                "upi_id": "payment@phonepe",
                "name": "PhonePe UPI"
            },
            "admin": null
        }
    ]
}
```

**Get Only Pending Requests:**
```bash
GET /api/wallet/top-up/history?user_id=1&status=pending
```

**Get Only Approved Requests:**
```bash
GET /api/wallet/top-up/history?user_id=1&status=approved
```

**Get Last 20 Requests:**
```bash
GET /api/wallet/top-up/history?user_id=1&limit=20
```

**cURL Example:**
```bash
# Get all history
curl -X GET "https://api.alldigtalseva.com/api/wallet/top-up/history?user_id=1" \
  -H "Content-Type: application/json"

# Get only approved requests
curl -X GET "https://api.alldigtalseva.com/api/wallet/top-up/history?user_id=1&status=approved" \
  -H "Content-Type: application/json"

# Get last 10 pending requests
curl -X GET "https://api.alldigtalseva.com/api/wallet/top-up/history?user_id=1&status=pending&limit=10" \
  -H "Content-Type: application/json"
```

**JavaScript/Fetch Example:**
```javascript
// Get wallet top-up history
fetch('https://api.alldigtalseva.com/api/wallet/top-up/history?user_id=1')
  .then(response => response.json())
  .then(data => {
    if (data.success) {
      console.log('Summary:', data.summary);
      console.log('Total Requests:', data.summary.total_requests);
      console.log('Total Approved Amount:', data.summary.total_approved_amount);
      console.log('History:', data.data);
      
      // Display history
      data.data.forEach(request => {
        console.log(`${request.status}: ${request.amount} on ${request.created_at}`);
      });
    }
  });
```

**Angular Example:**
```typescript
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class WalletService {
  private apiUrl = 'https://api.alldigtalseva.com/api';

  constructor(private http: HttpClient) {}

  getTopUpHistory(userId: number, status?: string, limit?: number): Observable<any> {
    let params = new HttpParams().set('user_id', userId.toString());
    
    if (status) {
      params = params.set('status', status);
    }
    
    if (limit) {
      params = params.set('limit', limit.toString());
    }

    return this.http.get<any>(`${this.apiUrl}/wallet/top-up/history`, { params });
  }
}

// Usage in Component
this.walletService.getTopUpHistory(1, 'approved', 20).subscribe({
  next: (response) => {
    if (response.success) {
      this.summary = response.summary;
      this.history = response.data;
      console.log('Total approved:', this.summary.total_approved_amount);
    }
  },
  error: (error) => {
    console.error('Failed to load history:', error);
  }
});
```

**React Example:**
```javascript
import { useState, useEffect } from 'react';

function WalletHistory({ userId }) {
  const [history, setHistory] = useState([]);
  const [summary, setSummary] = useState(null);
  const [statusFilter, setStatusFilter] = useState('');

  useEffect(() => {
    let url = `https://api.alldigtalseva.com/api/wallet/top-up/history?user_id=${userId}`;
    if (statusFilter) {
      url += `&status=${statusFilter}`;
    }

    fetch(url)
      .then(res => res.json())
      .then(data => {
        if (data.success) {
          setHistory(data.data);
          setSummary(data.summary);
        }
      });
  }, [userId, statusFilter]);

  return (
    <div>
      {summary && (
        <div className="summary">
          <h3>Summary</h3>
          <p>Total Requests: {summary.total_requests}</p>
          <p>Approved: {summary.approved}</p>
          <p>Pending: {summary.pending}</p>
          <p>Rejected: {summary.rejected}</p>
          <p>Total Approved Amount: ₹{summary.total_approved_amount}</p>
        </div>
      )}
      
      <select value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}>
        <option value="">All</option>
        <option value="pending">Pending</option>
        <option value="approved">Approved</option>
        <option value="rejected">Rejected</option>
      </select>

      <table>
        <thead>
          <tr>
            <th>Date</th>
            <th>Amount</th>
            <th>UPI</th>
            <th>Status</th>
          </tr>
        </thead>
        <tbody>
          {history.map(request => (
            <tr key={request.id}>
              <td>{new Date(request.created_at).toLocaleDateString()}</td>
              <td>₹{request.amount}</td>
              <td>{request.upi?.upi_id}</td>
              <td>{request.status}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}
```

**Notes:**
- Returns history sorted by most recent first
- Includes summary statistics (total requests, counts by status, total approved amount)
- Can filter by status (pending, approved, rejected)
- Can limit number of records returned (default: 50, max: 100)
- Includes UPI details and admin information for each request

---

## Top-Up Request Management APIs (Admin)

All admin endpoints require admin authentication via Bearer token.

### Get All Top-Up Requests

Get all top-up requests with optional status filter.

**Endpoint:** `GET /api/admin/top-up/requests`

**Headers:**
```
Authorization: Bearer {admin_token}
```

**Query Parameters:**
- `status` (optional, enum): Filter by status - `"pending"`, `"approved"`, `"rejected"`, or `"all"` (default: `"all"`)

**Success Response (200):**
```json
{
    "success": true,
    "data": [
        {
            "id": 1,
            "user_id": 1,
            "upi_id": 1,
            "amount": "500.00",
            "status": "pending",
            "rejection_reason": null,
            "approved_by": null,
            "approved_at": null,
            "created_at": "2025-12-04T07:20:00.000000Z",
            "updated_at": "2025-12-04T07:20:00.000000Z",
            "user": {
                "id": 1,
                "email": "user@example.com",
                "phone_number": "1234567890",
                "wallet_balance": "100.00"
            },
            "upi": {
                "id": 1,
                "upi_id": "user@paytm",
                "name": "Main UPI"
            },
            "admin": null
        }
    ]
}
```

**cURL Example:**
```bash
# Get all requests
curl -X GET https://api.alldigtalseva.com/api/admin/top-up/requests \
  -H "Authorization: Bearer {admin_token}"

# Get only pending requests
curl -X GET "https://api.alldigtalseva.com/api/admin/top-up/requests?status=pending" \
  -H "Authorization: Bearer {admin_token}"
```

---

### Get Single Top-Up Request

Get details of a specific top-up request.

**Endpoint:** `GET /api/admin/top-up/request/{id}`

**Headers:**
```
Authorization: Bearer {admin_token}
```

**Success Response (200):**
```json
{
    "success": true,
    "data": {
        "id": 1,
        "user_id": 1,
        "upi_id": 1,
        "amount": "500.00",
        "status": "pending",
        "rejection_reason": null,
        "approved_by": null,
        "approved_at": null,
        "created_at": "2025-12-04T07:20:00.000000Z",
        "updated_at": "2025-12-04T07:20:00.000000Z",
        "user": {
            "id": 1,
            "email": "user@example.com",
            "phone_number": "1234567890",
            "wallet_balance": "100.00"
        },
        "upi": {
            "id": 1,
            "upi_id": "user@paytm",
            "name": "Main UPI"
        },
        "admin": null
    }
}
```

---

### Approve Top-Up Request

Approve a pending top-up request. This will add the amount to the user's wallet balance.

**Endpoint:** `POST /api/admin/top-up/request/{id}/approve`

**Headers:**
```
Authorization: Bearer {admin_token}
```

**Success Response (200):**
```json
{
    "success": true,
    "message": "Top-up request approved successfully",
    "data": {
        "request": {
            "id": 1,
            "user_id": 1,
            "upi_id": 1,
            "amount": "500.00",
            "status": "approved",
            "rejection_reason": null,
            "approved_by": 1,
            "approved_at": "2025-12-04T07:25:00.000000Z",
            "created_at": "2025-12-04T07:20:00.000000Z",
            "updated_at": "2025-12-04T07:25:00.000000Z",
            "user": {
                "id": 1,
                "email": "user@example.com",
                "phone_number": "1234567890",
                "wallet_balance": "600.00"
            },
            "upi": {
                "id": 1,
                "upi_id": "user@paytm",
                "name": "Main UPI"
            },
            "admin": {
                "id": 1,
                "username": "admin",
                "email": "admin@alldigtalseva.com"
            }
        },
        "user_new_balance": "600.00"
    }
}
```

**Error Response (400) - Request Not Pending:**
```json
{
    "success": false,
    "message": "Top-up request is not pending. Current status: approved"
}
```

**cURL Example:**
```bash
curl -X POST https://api.alldigtalseva.com/api/admin/top-up/request/1/approve \
  -H "Authorization: Bearer {admin_token}"
```

---

### Reject Top-Up Request

Reject a pending top-up request. Optionally provide a rejection reason.

**Endpoint:** `POST /api/admin/top-up/request/{id}/reject`

**Headers:**
```
Authorization: Bearer {admin_token}
Content-Type: application/json
```

**Request Body (optional):**
```json
{
    "rejection_reason": "Payment not received"
}
```

**Parameters:**
- `rejection_reason` (optional, string, max: 500): Reason for rejection

**Success Response (200):**
```json
{
    "success": true,
    "message": "Top-up request rejected successfully",
    "data": {
        "id": 1,
        "user_id": 1,
        "upi_id": 1,
        "amount": "500.00",
        "status": "rejected",
        "rejection_reason": "Payment not received",
        "approved_by": 1,
        "approved_at": "2025-12-04T07:25:00.000000Z",
        "created_at": "2025-12-04T07:20:00.000000Z",
        "updated_at": "2025-12-04T07:25:00.000000Z",
        "user": {
            "id": 1,
            "email": "user@example.com",
            "phone_number": "1234567890"
        },
        "upi": {
            "id": 1,
            "upi_id": "user@paytm",
            "name": "Main UPI"
        },
        "admin": {
            "id": 1,
            "username": "admin",
            "email": "admin@alldigtalseva.com"
        }
    }
}
```

**cURL Example:**
```bash
curl -X POST https://api.alldigtalseva.com/api/admin/top-up/request/1/reject \
  -H "Authorization: Bearer {admin_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "rejection_reason": "Payment not received"
  }'
```

---

## Top-Up Request Status Flow

```
pending → approved (wallet balance updated)
       ↘ rejected (no balance change)
```

1. **Pending**: User submits request, waiting for admin action
2. **Approved**: Admin approves → Wallet balance increased
3. **Rejected**: Admin rejects → No balance change

---

## Important Notes

1. **User Verification**: Users must be verified (completed signup) before requesting top-up.

2. **Pending Requests**: Users can only have one pending top-up request at a time.

3. **UPI Status**: Only active UPIs can be selected for top-up requests.

4. **Wallet Update**: Wallet balance is automatically updated when admin approves a request.

5. **Admin Authentication**: All admin endpoints require Bearer token authentication.

6. **Request Status**: Once a request is approved or rejected, it cannot be changed.

7. **Default UPI**: Only one UPI can be set as default at a time.

---

## Error Codes

| Status Code | Description |
|------------|-------------|
| 200 | Success |
| 201 | Created - Request submitted successfully |
| 400 | Bad Request - Invalid operation or status |
| 401 | Unauthorized - Invalid or missing admin token |
| 403 | Forbidden - User not verified |
| 404 | Not Found - Resource not found |
| 422 | Validation Error - Invalid input data |

---

## Workflow Example

1. **Admin adds UPI:**
   ```bash
   POST /api/admin/upi
   {
     "upi_id": "payment@paytm",
     "name": "Payment UPI",
     "status": "active",
     "is_default": true
   }
   ```

2. **User views available UPIs:**
   ```bash
   GET /api/upi/list
   ```
   Response shows all active UPIs that user can select.

3. **User requests top-up (using UPI ID from step 2):**
   ```bash
   POST /api/top-up/request
   {
     "user_id": 1,
     "upi_id": 1,  // UPI ID from /api/upi/list response
     "amount": 1000.00
   }
   ```

3. **Admin views pending requests:**
   ```bash
   GET /api/admin/top-up/requests?status=pending
   ```

4. **Admin approves request:**
   ```bash
   POST /api/admin/top-up/request/1/approve
   ```

5. **User's wallet balance is updated automatically**

---

**Last Updated:** December 4, 2025

