# INSTALLMENT PAYMENT SYSTEM - IMPLEMENTATION GUIDE

## Overview
This system enables automatic monthly payment processing for installment orders. Customers provide their card once, and you charge them automatically each month.

## Architecture

### Key Components

1. **Models** (Already exist in your code):
   - `Order` - Enhanced with payment_type, total_installments, installments_paid
   - `InstallmentSchedule` - Manages the payment schedule
   - `ScheduledPayment` - Individual payment records
   - `RecurringPaymentToken` - Stores customer's card token securely

2. **Views** (New file: `installment_views.py`):
   - `checkout_with_installment` - Customer selects payment plan
   - `setup_installment_payment` - Customer authorizes card
   - `installment_schedule_detail` - View payment history
   - `retry_failed_payment` - Manual retry option
   - `update_payment_method` - Change card

3. **Management Command** (New):
   - `process_installment_payments` - Automatically charges customers

4. **Forms** (New file: `installment_forms.py`):
   - Validation for installment options

5. **Templates** (New):
   - Checkout flow
   - Payment setup
   - Schedule management
   - Email notifications

---

## STEP-BY-STEP INTEGRATION

### Step 1: Update URLs
Add to your main `nexusmart/urls.py`:

```python
from django.urls import path, include

urlpatterns = [
    # ... existing patterns ...
    path('installment/', include('shop.installment_urls')),
]
```

### Step 2: Update Order Views
Update your existing `shop/order_views.py` or `shop/views.py` to redirect to installment checkout:

```python
from django.shortcuts import redirect
from django.urls import reverse

def checkout(request):
    # Check if customer selected installment
    num_installments = request.POST.get('num_installments', 1)
    
    if int(num_installments) > 1:
        # Redirect to installment checkout
        return redirect('installment:checkout')
    
    # Otherwise process full payment
    # ... existing checkout logic ...
```

### Step 3: Create Periodic Task (Choose One)

#### Option A: Using Celery (Recommended for production)
Create `shop/tasks.py`:

```python
from celery import shared_task
from django.core.management import call_command

@shared_task
def process_monthly_payments():
    """Process scheduled installment payments"""
    call_command('process_installment_payments')

# Configure in settings.py:
from celery.schedules import crontab

CELERY_BEAT_SCHEDULE = {
    'process-installment-payments': {
        'task': 'shop.tasks.process_monthly_payments',
        'schedule': crontab(hour=2, minute=0),  # Daily at 2 AM
    },
}
```

#### Option B: Using Django-Crontab
Install: `pip install django-cron`

Create `shop/cron.py`:

```python
from django_cron import CronJobBase, Schedule
from django.core.management import call_command

class ProcessInstallmentPayments(CronJobBase):
    RUN_AT_TIMES = ['02:00']  # Run daily at 2 AM
    schedule = Schedule(run_at_times=RUN_AT_TIMES)
    code = 'shop.process_installment_payments'
    
    def do(self):
        call_command('process_installment_payments')
```

Register in `settings.py`:
```python
CRON_CLASSES = [
    'shop.cron.ProcessInstallmentPayments',
]
```

#### Option C: Using APScheduler (Lightweight)
Install: `pip install apscheduler`

Create a startup script or add to `manage.py`:

```python
from apscheduler.schedulers.background import BackgroundScheduler
from django.core.management import call_command
import atexit

def start_scheduler():
    scheduler = BackgroundScheduler()
    scheduler.add_job(
        lambda: call_command('process_installment_payments'),
        'cron',
        hour=2,
        minute=0,
        id='process_payments'
    )
    scheduler.start()
    atexit.register(lambda: scheduler.shutdown())
```

### Step 4: Create Payment Token Handler
Add to `shop/views.py` or create payment callback handler:

```python
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import RecurringPaymentToken

@csrf_exempt
def flutterwave_webhook(request):
    """Handle Flutterwave webhook for payment status"""
    if request.method != 'POST':
        return JsonResponse({'status': 'error'}, status=405)
    
    import json
    data = json.loads(request.body)
    
    if data.get('event') == 'charge.completed':
        # Update payment status
        pass
    
    return JsonResponse({'status': 'success'})
```

### Step 5: Create Admin Interface
Create `shop/admin_views.py` (if not already):

```python
from django.contrib import admin
from .models import InstallmentSchedule, ScheduledPayment

@admin.register(InstallmentSchedule)
class InstallmentScheduleAdmin(admin.ModelAdmin):
    list_display = ('order', 'payment_token', 'status', 'paid_installments', 'total_installments')
    list_filter = ('status', 'created_at')
    readonly_fields = ('created_at', 'updated_at')
    search_fields = ('order__id', 'order__user__email')
    
    def has_add_permission(self, request):
        return False  # Create via orders only

@admin.register(ScheduledPayment)
class ScheduledPaymentAdmin(admin.ModelAdmin):
    list_display = ('installment_number', 'order', 'amount', 'status', 'due_date')
    list_filter = ('status', 'due_date')
    readonly_fields = ('transaction_reference', 'gateway_response', 'created_at', 'updated_at')
    search_fields = ('order__id', 'transaction_reference')
```

### Step 6: Create Filter for Admin
Add to `shop/models.py` Admin section:

```python
class InstallmentFilter(admin.SimpleListFilter):
    title = 'Installment Status'
    parameter_name = 'installment_status'
    
    def lookups(self, request, model_admin):
        return [
            ('active', 'Active'),
            ('completed', 'Completed'),
            ('suspended', 'Suspended'),
            ('cancelled', 'Cancelled'),
        ]
    
    def queryset(self, request, queryset):
        if self.value():
            return queryset.filter(installment_schedule__status=self.value())
        return queryset

# Add to Order admin:
class OrderAdmin(admin.ModelAdmin):
    list_filter = [InstallmentFilter, ...]
```

---

## CUSTOMER FLOW

### 1. Checkout
- Customer selects 3, 6, or 12 month plan
- System calculates monthly payment
- Customer confirms order

### 2. Payment Authorization
- Redirect to Flutterwave payment page
- Customer enters card details
- Card is tokenized (not stored on your server)
- Customer returns to confirmation page

### 3. Ongoing Payments
- Cron job runs daily at 2 AM
- System checks for due payments
- Charges saved card automatically
- Handles failures with retry logic

### 4. Customer Dashboard
- View payment schedule
- See payment history
- Retry failed payments
- Update payment method

---

## FEATURES

### Automatic Retry Logic
```
Retry Schedule:
- 1st failure: Retry after 5 minutes
- 2nd failure: Retry after 15 minutes  
- 3rd failure: Retry after 60 minutes
- 4th+ failure: Suspend and notify customer
```

### Email Notifications
- Payment success confirmation
- Payment failure warning
- Schedule suspension notice
- Payment reminders (optional)

### Security
- No card details stored on server
- Flutterwave handles PCI compliance
- Tokens are encrypted
- Each transaction verified

---

## TESTING

### Test the Management Command
```bash
# Dry run (shows what would happen)
python manage.py process_installment_payments --dry-run

# Process specific order
python manage.py process_installment_payments --order-id=123

# Process specific schedule
python manage.py process_installment_payments --schedule-id=456
```

### Manual Testing Steps
1. Create test order with installment
2. Set payment method manually in admin
3. Run `process_installment_payments` command
4. Verify payment records created
5. Check email notifications

---

## DEPLOYMENT CHECKLIST

- [ ] Run migrations (existing models are ready)
- [ ] Add URL patterns
- [ ] Create cron/scheduler task
- [ ] Test payment processing
- [ ] Set up email templates
- [ ] Configure Flutterwave webhook (optional)
- [ ] Update navbar with installment link
- [ ] Create help documentation for customers
- [ ] Test retry logic with failed transactions
- [ ] Monitor logs for errors

---

## CONFIGURATION

### Settings (settings.py)
```python
# Flutterwave Config (already configured)
FLW_PUBLIC_KEY = 'your_public_key'
FLW_SECRET_KEY = 'your_secret_key'  
FLW_ENCRYPTION_KEY = 'your_encryption_key'

# Email Config
DEFAULT_FROM_EMAIL = 'noreply@nexusmart.com'
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

# Installment Settings
MAX_INSTALLMENT_MONTHS = 12
MIN_INSTALLMENT_AMOUNT = 50  # Minimum order value for installment
```

---

## API ENDPOINTS

### Calculate Monthly Payment (AJAX)
```
POST /installment/api/calculate/
Parameters:
  - amount: float
  - months: int
Returns:
  - monthly_payment: float
  - total_amount: float
  - num_months: int
```

### Get Payment Status (AJAX)
```
GET /installment/api/status/{order_id}/
Returns:
  - status: string
  - total_installments: int
  - paid_installments: int
  - remaining: int
  - monthly_amount: float
  - next_payment_date: date
```

---

## TROUBLESHOOTING

### Payment not processing
1. Check if scheduled date has passed
2. Verify payment token is authorized
3. Check Flutterwave API credentials
4. Run command manually to see errors
5. Check logs in `logs/` directory

### Customer not receiving emails
1. Verify EMAIL_BACKEND is configured
2. Check email template syntax
3. Verify customer email address
4. Test with `manage.py send_test_email`

### Card token not working
1. Verify token is valid in Flutterwave
2. Check if token expired
3. Customer may need to re-authorize
4. Check card hasn't been cancelled

---

## NEXT STEPS

1. **SMS Notifications**: Add Twilio for SMS alerts
2. **Payment Reminders**: Send email 3 days before due date
3. **Late Fee Logic**: Add late payment penalties
4. **Flexible Rescheduling**: Allow customer to reschedule payment
5. **Analytics Dashboard**: Track installment metrics
6. **Partial Payment Support**: Allow additional payments to finish early

---

## SUPPORT

For issues or questions:
1. Check Django logs
2. Review management command output
3. Verify Flutterwave API status
4. Contact Flutterwave support for gateway issues
