Skip to content

Latest commit

 

History

History
438 lines (349 loc) · 11.6 KB

File metadata and controls

438 lines (349 loc) · 11.6 KB

Manual Payment System - Complete Implementation

🎉 Features Implemented

1. ✅ Pending Payments Dashboard for Admin

Location: /dashboard/admin/payment-requests

Features:

  • Real-time payment request tracking
  • Filter by status (Pending, Contacted, Payment Received, Completed)
  • Statistics cards showing counts by status
  • Total revenue from completed manual payments
  • Sortable table with student details
  • Quick access to manage each request

Status Workflow:

  1. Pending - Student submitted request, awaiting admin response
  2. Contacted - Admin sent payment instructions
  3. Payment Received - Admin confirmed payment
  4. Completed - Student enrolled in courses
  5. Cancelled - Request cancelled

2. ✅ Manual Enrollment Workflow

Complete Process:

Step 1: Student Requests Payment Info

  • Student clicks "Contact for Payment" on manual product
  • Fills form with name, email, phone, message
  • Request saved to database with status = 'pending'

Step 2: Admin Reviews Request

  • Navigate to /dashboard/admin/payment-requests
  • See pending request in table
  • Click "Manage" to open details dialog

Step 3: Admin Sends Payment Instructions

  • Fill in payment method (e.g., "Bank Transfer")
  • Add payment instructions (bank details, etc.)
  • Update status to "Contacted"
  • System sends email to student (TODO: email integration)

Step 4: Student Makes Payment

  • Student receives payment instructions
  • Makes payment via agreed method
  • Informs admin (email, phone, etc.)

Step 5: Admin Confirms Payment

  • Admin marks request as "Payment Received"
  • Optionally generates invoice
  • Clicks "Confirm Payment & Enroll Student"

Step 6: Automatic Enrollment

  • System enrolls student in all courses linked to product
  • Creates transaction record
  • Updates request status to "Completed"
  • Student immediately gets access to courses

3. ✅ Invoice Generation

Features:

  • Professional HTML invoice template
  • Automatic invoice numbering (format: INV-{timestamp}-{requestId})
  • Company branding (customizable via env vars)
  • Student details (name, email, phone)
  • Product details with description
  • Payment instructions included
  • Print-friendly CSS styling
  • Accessible via URL: /api/invoices/{invoiceNumber}

How to Generate:

  1. Open payment request in admin panel
  2. Click "Generate Invoice"
  3. Invoice number created and saved
  4. View invoice at /api/invoices/INV-...
  5. Print or save as PDF using browser

Customization: Add to .env.local:

COMPANY_NAME="Your LMS Platform"
COMPANY_ADDRESS="123 Main St, City, Country"
COMPANY_EMAIL="billing@yourlms.com"
COMPANY_PHONE="+1 234 567 8900"

📊 Database Schema

payment_requests Table

CREATE TABLE payment_requests (
  request_id BIGSERIAL PRIMARY KEY,
  user_id UUID NOT NULL REFERENCES profiles(id),
  product_id INTEGER NOT NULL REFERENCES products(product_id),

  -- Contact info
  contact_name TEXT NOT NULL,
  contact_email TEXT NOT NULL,
  contact_phone TEXT,
  message TEXT,

  -- Status tracking
  status VARCHAR(20) NOT NULL DEFAULT 'pending',

  -- Payment details (admin fills)
  payment_method TEXT,
  payment_instructions TEXT,
  payment_deadline TIMESTAMPTZ,
  payment_confirmed_at TIMESTAMPTZ,
  payment_amount NUMERIC(10, 2),
  payment_currency VARCHAR(3),

  -- Invoice
  invoice_number TEXT UNIQUE,
  invoice_generated_at TIMESTAMPTZ,

  -- Admin tracking
  processed_by UUID REFERENCES profiles(id),
  admin_notes TEXT,

  -- Timestamps
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

🎯 User Flows

Student Flow

  1. Browse available courses
  2. Find product with "Manual/Offline Payment"
  3. Click "Contact for Payment"
  4. Fill contact form and submit
  5. Receive payment instructions via email
  6. Make payment
  7. Get enrolled automatically after admin confirmation

Admin Flow

  1. Receive notification of new payment request
  2. Navigate to Payment Requests dashboard
  3. Review student details and product
  4. Generate invoice (optional)
  5. Send payment instructions
  6. Mark as "Contacted"
  7. Wait for student payment
  8. Confirm payment received
  9. Click "Confirm Payment & Enroll Student"
  10. Student automatically enrolled

🚀 Quick Start Guide

For Admins

Create Manual Payment Product:

1. Go to /dashboard/admin/products/new
2. Fill product details
3. Select "Manual/Offline Payment" as payment method
4. Add courses
5. Save

Process Payment Requests:

1. Go to /dashboard/admin/payment-requests
2. Click "Manage" on pending request
3. Fill payment instructions
4. Update status to "Contacted"
5. Wait for payment
6. Mark as "Payment Received"
7. Click "Confirm Payment & Enroll Student"

For Students

Request Payment Info:

1. Browse courses
2. Find course with "Contact for Payment" button
3. Click and fill form
4. Submit request
5. Wait for payment instructions
6. Make payment
7. Get enrolled

📁 Files Created

Database

  • supabase/migrations/20260201160000_create_payment_requests_table.sql

Server Actions

  • app/actions/payment-requests.ts - CRUD operations for payment requests
    • createPaymentRequest() - Student creates request
    • updatePaymentRequest() - Admin updates status/details
    • confirmPaymentAndEnroll() - Admin enrolls student
    • generateInvoice() - Creates invoice

Pages

  • app/dashboard/admin/payment-requests/page.tsx - Dashboard with stats and tabs
  • app/api/invoices/[invoiceNumber]/route.ts - Invoice viewer

Components

  • components/admin/payment-requests-table.tsx - Requests table
  • components/admin/payment-request-dialog.tsx - Management dialog
  • components/student/manual-payment-dialog.tsx - Contact form (updated)

Libraries

  • lib/invoice-generator.ts - HTML invoice template

🧪 Testing

Manual Testing Checklist

Student Side:

  • Find manual payment product
  • Open contact form
  • Submit payment request
  • Verify success message
  • Check database has pending request

Admin Side:

  • See pending request in dashboard
  • Stats show correct counts
  • Open payment request dialog
  • Generate invoice
  • View invoice HTML
  • Update payment instructions
  • Change status to "Contacted"
  • Mark as "Payment Received"
  • Confirm and enroll student
  • Verify student has access to courses

Database Verification:

-- Check payment requests
SELECT * FROM payment_requests ORDER BY created_at DESC;

-- Check enrollments created
SELECT e.*, c.title
FROM enrollments e
JOIN courses c ON e.course_id = c.course_id
WHERE e.user_id = (SELECT user_id FROM payment_requests WHERE request_id = X);

-- Check transactions
SELECT * FROM transactions
WHERE metadata->>'payment_request_id' = 'X';

Playwright Tests

Create test file:

// tests/admin/payment-workflow.spec.ts

test('complete manual payment workflow', async ({ page }) => {
  // Student creates request
  await loginAsStudent(page)
  await page.goto('/dashboard/student')
  await page.click('text=Contact for Payment')
  await page.fill('input[name="name"]', 'Test Student')
  await page.fill('input[name="email"]', 'test@example.com')
  await page.click('button:has-text("Request Payment Info")')

  // Admin processes request
  await loginAsAdmin(page)
  await page.goto('/dashboard/admin/payment-requests')
  await page.click('button:has-text("Manage")')
  await page.fill('textarea[name="paymentInstructions"]', 'Bank details...')
  await page.click('button:has-text("Update Request")')

  // Admin enrolls student
  await page.click('button:has-text("Confirm Payment & Enroll Student")')
  await expect(page.locator('text=Student enrolled')).toBeVisible()
})

🔧 Configuration

Environment Variables

Optional (for invoice branding):

COMPANY_NAME="Your LMS Platform"
COMPANY_ADDRESS="123 Education Street, Learning City"
COMPANY_EMAIL="billing@yourlms.com"
COMPANY_PHONE="+1 (555) 123-4567"

Email Integration (Future)

To enable email notifications, implement in app/actions/payment-requests.ts:

// After creating payment request
await sendEmail({
  to: 'admin@yourlms.com',
  subject: 'New Payment Request',
  template: 'payment-request-admin',
  data: { request }
})

// After admin sends instructions
await sendEmail({
  to: request.contact_email,
  subject: 'Payment Instructions',
  template: 'payment-instructions',
  data: { instructions, request }
})

// After enrollment
await sendEmail({
  to: request.contact_email,
  subject: 'Welcome! You're Enrolled',
  template: 'enrollment-confirmation',
  data: { courses, request }
})

📈 Statistics & Reporting

Admin Dashboard Stats

The admin dashboard now shows:

  • Pending Payments - Count of requests awaiting action
  • Total Revenue - Includes manual payment transactions
  • Quick access button to Payment Requests

Payment Request Stats

Payment Requests page shows:

  • Pending count
  • Contacted count
  • Payment Received count
  • Completed count
  • Total revenue from completed payments

🎨 UI Components

Status Badges

Each status has a color-coded badge:

  • 🟡 Pending - Yellow
  • 🔵 Contacted - Blue
  • 🟣 Payment Received - Purple
  • 🟢 Completed - Green
  • 🔴 Cancelled - Red

Payment Request Dialog

Features:

  • Student details section
  • Product and amount info
  • Status selector
  • Payment method input
  • Payment instructions textarea
  • Internal admin notes
  • Quick action buttons
  • Generate invoice button
  • Enroll student button (when payment received)

🚨 Important Notes

Security

  • ✅ RLS policies protect payment requests
  • ✅ Only admins can update requests
  • ✅ Only admins can confirm payments
  • ✅ Students can only view their own requests
  • ✅ Invoice access verified (student or admin only)

Data Integrity

  • ✅ Enrollment prevents duplicates
  • ✅ Transaction records created for audit trail
  • ✅ Timestamps track all status changes
  • ✅ Admin who processed request is tracked

Future Enhancements

  • Email notifications (admin and student)
  • SMS notifications option
  • PDF invoice generation (currently HTML)
  • Payment receipt upload
  • Bulk payment processing
  • Export payment requests to CSV
  • Payment reminder system
  • Automatic invoice numbering sequences
  • Multi-currency support
  • Payment plan options

📚 API Reference

Server Actions

createPaymentRequest(data)

  • Creates new payment request
  • Returns: { success, data: PaymentRequest }
  • Validates: product exists, no duplicate requests

updatePaymentRequest(requestId, updates)

  • Updates request status and details
  • Returns: { success }
  • Admin only

confirmPaymentAndEnroll(requestId)

  • Enrolls student in courses
  • Creates transaction record
  • Marks request as completed
  • Returns: { success }
  • Admin only

generateInvoice(requestId)

  • Creates invoice number
  • Returns: { success, data: { invoiceNumber, invoiceUrl } }
  • Admin only

API Routes

GET /api/invoices/[invoiceNumber]

  • Returns HTML invoice
  • Accessible by student (owner) or admin
  • Print-friendly format

✨ Summary

You now have a complete manual payment system that:

  1. Tracks all payment requests in a dedicated dashboard
  2. Provides step-by-step workflow from request to enrollment
  3. Generates professional invoices with company branding
  4. Automates enrollment after payment confirmation
  5. Maintains full audit trail of all actions
  6. Integrates seamlessly with existing product system
  7. Scales easily for future payment providers

Perfect for offline sales while maintaining infrastructure for future online payments!