# How Users Apply Recharge Offers

This guide explains how users can apply recharge offers when creating top-up requests to get discounts and cashback.

---

## Quick Overview

When users create a top-up request, they can include a `recharge_offer_id` to apply an offer. The system will:
1. Validate the offer is active and applicable
2. Calculate discount and cashback
3. Credit the final amount (recharge + discount + cashback) to wallet when admin approves

---

## Step-by-Step Process

### Step 1: Check Available Offers

Before creating a top-up request, users should check which offers are available for their recharge amount.

**API Endpoint:** `GET /api/recharge-offer/applicable?recharge_amount={amount}`

**Example:**
```bash
curl -X GET "https://api.alldigtalseva.com/api/recharge-offer/applicable?recharge_amount=1000"
```

**Response:**
```json
{
    "success": true,
    "recharge_amount": "1000",
    "data": [
        {
            "id": 1,
            "title": "Festive Recharge Offer",
            "description": "Get 10% discount on recharge above ₹500",
            "minimum_recharge_amount": "500.00",
            "discount_type": "percentage",
            "discount_value": "10.00",
            "cashback_amount": "50.00",
            "total_benefit": 150,
            "benefit_description": "10.00% discount = ₹100 + ₹50.00 cashback",
            "validity_start_date": "2025-12-01",
            "validity_end_date": "2025-12-31"
        }
    ]
}
```

**What to show users:**
- Offer title and description
- Total benefit amount
- Benefit description (discount + cashback breakdown)

---

### Step 2: Create Top-Up Request with Offer

When creating a top-up request, include the `recharge_offer_id` if user wants to apply an offer.

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

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

**Parameters:**
- `user_id` (required): User ID
- `upi_id` (required): UPI ID (get from `/api/upi/list`)
- `amount` (required): Recharge amount
- `recharge_offer_id` (optional): Offer ID to apply

**Success Response:**
```json
{
    "success": true,
    "message": "Top-up request submitted successfully. Waiting for admin approval.",
    "data": {
        "request_id": 2,
        "user_id": 1,
        "upi_id": 1,
        "amount": "1000.00",
        "status": "pending",
        "offer_applied": {
            "offer_id": 1,
            "offer_title": "Festive Recharge Offer",
            "discount_amount": 100,
            "cashback_amount": "50.00",
            "final_credited_amount": 1150,
            "benefit_description": "10.00% discount = ₹100 + ₹50.00 cashback"
        }
    }
}
```

**Key Points:**
- `final_credited_amount`: Total amount that will be credited to wallet (amount + discount + cashback)
- `benefit_description`: Human-readable description of benefits
- Offer is validated automatically

---

### Step 3: Admin Approves Request

When admin approves the top-up request, the wallet is credited with the final amount including benefits.

**What gets credited:**
- **Base Amount**: The recharge amount user requested
- **Discount**: Bonus credit (calculated based on offer)
- **Cashback**: Extra credit
- **Total**: `amount + discount + cashback`

**Example:**
- User requests: ₹1000
- Offer applied: 10% discount (₹100) + ₹50 cashback
- **Final credited to wallet: ₹1150**

---

## Complete User Flow Example

### Frontend Implementation (JavaScript)

```javascript
// 1. User enters recharge amount
const rechargeAmount = 1000;

// 2. Fetch applicable offers
async function getApplicableOffers(amount) {
  const response = await fetch(
    `https://api.alldigtalseva.com/api/recharge-offer/applicable?recharge_amount=${amount}`
  );
  const data = await response.json();
  
  if (data.success && data.data.length > 0) {
    // Show offers to user
    displayOffers(data.data);
    return data.data;
  }
  return [];
}

// 3. User selects an offer (optional)
const selectedOffer = offers[0]; // User selects best offer

// 4. Create top-up request with offer
async function createTopUpRequest(userId, upiId, amount, offerId = null) {
  const body = {
    user_id: userId,
    upi_id: upiId,
    amount: amount
  };
  
  // Include offer if selected
  if (offerId) {
    body.recharge_offer_id = offerId;
  }
  
  const response = await fetch('https://api.alldigtalseva.com/api/top-up/request', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(body)
  });
  
  const data = await response.json();
  
  if (data.success) {
    if (data.data.offer_applied) {
      console.log(`Offer applied! You will receive ₹${data.data.offer_applied.final_credited_amount}`);
      console.log(`Benefits: ${data.data.offer_applied.benefit_description}`);
    } else {
      console.log(`Top-up request created. You will receive ₹${data.data.amount}`);
    }
  }
  
  return data;
}

// Complete flow
async function handleTopUp(userId, upiId, amount) {
  // Get offers
  const offers = await getApplicableOffers(amount);
  
  // Show offers to user and let them select
  const selectedOfferId = await showOfferSelection(offers);
  
  // Create request
  await createTopUpRequest(userId, upiId, amount, selectedOfferId);
}
```

---

## Angular Service Example

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

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

  constructor(private http: HttpClient) {}

  // Get applicable offers for recharge amount
  getApplicableOffers(rechargeAmount: number): Observable<any> {
    const params = new HttpParams().set('recharge_amount', rechargeAmount.toString());
    return this.http.get<any>(`${this.apiUrl}/recharge-offer/applicable`, { params });
  }

  // Create top-up request with optional offer
  createTopUpRequest(
    userId: number, 
    upiId: number, 
    amount: number, 
    offerId?: number
  ): Observable<any> {
    const body: any = {
      user_id: userId,
      upi_id: upiId,
      amount: amount
    };
    
    if (offerId) {
      body.recharge_offer_id = offerId;
    }
    
    return this.http.post<any>(`${this.apiUrl}/top-up/request`, body);
  }
}
```

**Component Usage:**
```typescript
export class TopUpComponent {
  offers: any[] = [];
  selectedOffer: any = null;
  rechargeAmount: number = 0;

  constructor(private topUpService: TopUpService) {}

  onAmountChange(amount: number) {
    this.rechargeAmount = amount;
    if (amount > 0) {
      this.loadOffers(amount);
    }
  }

  loadOffers(amount: number) {
    this.topUpService.getApplicableOffers(amount).subscribe({
      next: (response) => {
        if (response.success) {
          this.offers = response.data;
          // Auto-select best offer (first one, usually sorted by benefit)
          if (this.offers.length > 0) {
            this.selectedOffer = this.offers[0];
          }
        }
      },
      error: (error) => {
        console.error('Failed to load offers:', error);
      }
    });
  }

  submitTopUp(userId: number, upiId: number) {
    const offerId = this.selectedOffer ? this.selectedOffer.id : null;
    
    this.topUpService.createTopUpRequest(userId, upiId, this.rechargeAmount, offerId)
      .subscribe({
        next: (response) => {
          if (response.success) {
            if (response.data.offer_applied) {
              alert(`Offer applied! You will receive ₹${response.data.offer_applied.final_credited_amount}`);
            } else {
              alert(`Top-up request created. You will receive ₹${response.data.amount}`);
            }
          }
        },
        error: (error) => {
          console.error('Failed to create top-up request:', error);
        }
      });
  }
}
```

---

## React Hook Example

```typescript
import { useState, useEffect } from 'react';

export function useTopUpOffers(rechargeAmount: number) {
  const [offers, setOffers] = useState([]);
  const [loading, setLoading] = useState(false);
  const [selectedOffer, setSelectedOffer] = useState(null);

  useEffect(() => {
    if (rechargeAmount > 0) {
      loadOffers(rechargeAmount);
    }
  }, [rechargeAmount]);

  const loadOffers = async (amount: number) => {
    setLoading(true);
    try {
      const response = await fetch(
        `https://api.alldigtalseva.com/api/recharge-offer/applicable?recharge_amount=${amount}`
      );
      const data = await response.json();
      
      if (data.success) {
        setOffers(data.data);
        // Auto-select best offer
        if (data.data.length > 0) {
          setSelectedOffer(data.data[0]);
        }
      }
    } catch (error) {
      console.error('Failed to load offers:', error);
    } finally {
      setLoading(false);
    }
  };

  const createTopUpRequest = async (
    userId: number, 
    upiId: number, 
    amount: number
  ) => {
    const body: any = {
      user_id: userId,
      upi_id: upiId,
      amount: amount
    };
    
    if (selectedOffer) {
      body.recharge_offer_id = selectedOffer.id;
    }
    
    const response = await fetch('https://api.alldigtalseva.com/api/top-up/request', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(body)
    });
    
    return response.json();
  };

  return {
    offers,
    loading,
    selectedOffer,
    setSelectedOffer,
    createTopUpRequest
  };
}
```

---

## Important Notes

### 1. Offer Validation

The system automatically validates:
- ✅ Offer exists
- ✅ Offer is active (`is_active = true`)
- ✅ Offer is within validity period
- ✅ Recharge amount meets minimum requirement

### 2. Error Handling

**Invalid Offer:**
```json
{
    "success": false,
    "message": "Selected offer is not currently valid or active"
}
```

**Amount Too Low:**
```json
{
    "success": false,
    "message": "Minimum recharge amount for this offer is ₹500"
}
```

**Offer Not Found:**
```json
{
    "success": false,
    "message": "Recharge offer not found"
}
```

### 3. Offer is Optional

Users can create top-up requests **without** applying any offer by simply omitting `recharge_offer_id`:

```json
{
    "user_id": 1,
    "upi_id": 1,
    "amount": 1000
}
```

### 4. Benefits Credited on Approval

- Discount and cashback are **only credited** when admin approves the request
- If request is rejected, no benefits are credited
- Final amount = `recharge_amount + discount + cashback`

### 5. Multiple Offers

If multiple offers are applicable, show all to user and let them choose the best one. Usually, offers are sorted by total benefit (highest first).

---

## UI/UX Recommendations

1. **Show Offers Dynamically**: When user enters recharge amount, automatically fetch and display applicable offers

2. **Highlight Best Offer**: Show the offer with highest total benefit prominently

3. **Clear Benefit Display**: Show clearly:
   - "You will receive: ₹X"
   - "Benefits: Discount ₹Y + Cashback ₹Z"
   - "Total Benefit: ₹W"

4. **Optional Selection**: Allow user to:
   - Select an offer
   - Skip offers (no offer applied)
   - Change selection before submitting

5. **Confirmation**: Before submitting, show:
   - Recharge amount
   - Selected offer (if any)
   - Final amount to be credited
   - Benefits breakdown

---

## Summary

1. **User enters recharge amount** → System fetches applicable offers
2. **User selects offer (optional)** → Offer ID included in request
3. **System validates offer** → Checks validity, minimum amount, etc.
4. **System calculates benefits** → Discount + cashback
5. **Request created** → Shows final credited amount
6. **Admin approves** → Wallet credited with final amount (amount + discount + cashback)

**Result:** User gets more value than they paid for! 🎉

---

**Last Updated:** December 4, 2025

