# Payment Consolidation Implementation Guide

## Overview
This guide consolidates all payment points in the portal to use a unified payment system with a single modal component.

## Files Created

### 1. `/src/hooks/use-payment.js`
✅ Created - Unified payment hook that handles:
- Order payments (`initiateOrderPayment`)
- Invoice payments (`initiateInvoicePayment`)
- Generic payment initiator (`initiatePayment`)
- Payment status polling (`usePaymentStatus`)
- Payment history (`usePaymentHistory`)
- Payment details (`usePaymentDetails`)

### 2. `/src/components/modals/unified-payment-modal.js`
✅ Created - Unified payment modal that:
- Handles all payment types (orders, invoices, quotations)
- Shows payment method selection
- Displays processing states
- Polls for payment status
- Shows success/error states
- Redirects to Pesepay when needed

## Files to Update

### 3. Update Checkout Page
**File:** `/src/app/(portal)/checkout/page.js`

**Changes needed:**
1. Replace `useInitiatePayment` import with `usePayment`
2. Add state for payment modal
3. Update order submission to open modal instead of direct payment
4. Add UnifiedPaymentModal component

**Key changes:**
```javascript
// OLD imports
import { useInitiatePayment } from '@/hooks/use-payments';

// NEW imports
import { UnifiedPaymentModal } from '@/components/modals/unified-payment-modal';

// Add state
const [paymentModalOpen, setPaymentModalOpen] = useState(false);
const [paymentData, setPaymentData] = useState(null);

// In handleSubmitOrder, replace payment initiation with:
setPaymentData({
  type: 'order',
  id: response.data.order.id,
  amount: initialPaymentDue,
  reference: response.data.order.order_number,
  description: `Payment for Order #${response.data.order.order_number}`,
  metadata: {
    orderNumber: response.data.order.order_number,
  },
});
setPaymentModalOpen(true);

// Add modal before closing </MainLayout>
<UnifiedPaymentModal
  isOpen={paymentModalOpen}
  onClose={() => setPaymentModalOpen(false)}
  paymentData={paymentData}
  onSuccess={(result) => {
    toast.success('Payment completed!');
    router.push(`/orders/${paymentData.metadata.orderNumber}`);
  }}
  onError={() => {
    toast.error('Payment failed. You can retry from orders page.');
    router.push(`/orders/${paymentData.metadata.orderNumber}`);
  }}
/>
```

### 4. Update Order Details Page
**File:** `/src/app/(portal)/orders/[order_number]/page.js`

**Changes:**
```javascript
// Replace useInitiatePayment with usePayment
import { usePayment } from '@/hooks/use-payment';
import { UnifiedPaymentModal } from '@/components/modals/unified-payment-modal';

// Add state
const [paymentModalOpen, setPaymentModalOpen] = useState(false);
const [paymentData, setPaymentData] = useState(null);

// Replace handlePayment function
const handlePayment = () => {
  setPaymentData({
    type: 'order',
    id: order.id,
    amount: order.total_amount,
    reference: order.order_number,
    description: `Payment for Order #${order.order_number}`,
  });
  setPaymentModalOpen(true);
};

// Add modal
<UnifiedPaymentModal
  isOpen={paymentModalOpen}
  onClose={() => setPaymentModalOpen(false)}
  paymentData={paymentData}
  onSuccess={() => {
    toast.success('Payment completed!');
    refetch(); // Refresh order data
  }}
  onError={() => toast.error('Payment failed')}
/>
```

### 5. Update Invoice Details Page
**File:** `/src/app/(portal)/invoices/[id]/page.js`

**Changes:**
```javascript
import { usePayment } from '@/hooks/use-payment';
import { UnifiedPaymentModal } from '@/components/modals/unified-payment-modal';

const [paymentModalOpen, setPaymentModalOpen] = useState(false);
const [paymentData, setPaymentData] = useState(null);

const handlePayNow = () => {
  setPaymentData({
    type: 'invoice',
    id: invoice.id,
    amount: invoice.total_amount,
    reference: invoice.invoice_number,
    description: `Payment for Invoice #${invoice.invoice_number}`,
  });
  setPaymentModalOpen(true);
};

// Add modal
<UnifiedPaymentModal
  isOpen={paymentModalOpen}
  onClose={() => setPaymentModalOpen(false)}
  paymentData={paymentData}
  onSuccess={() => {
    toast.success('Payment completed!');
    refetch();
  }}
  onError={() => toast.error('Payment failed')}
/>
```

### 6. Update Invoices List Page
**File:** `/src/app/(portal)/invoices/page.js`

**Changes:**
```javascript
import { useState } from 'react';
import { UnifiedPaymentModal } from '@/components/modals/unified-payment-modal';

const [paymentModalOpen, setPaymentModalOpen] = useState(false);
const [paymentData, setPaymentData] = useState(null);

// Update "Pay Now" button in table
{isPayable && (
  <button 
    onClick={() => {
      setPaymentData({
        type: 'invoice',
        id: invoice.id,
        amount: invoice.total_amount,
        reference: invoice.invoice_number,
        description: `Payment for Invoice #${invoice.invoice_number}`,
      });
      setPaymentModalOpen(true);
    }}
    className="text-green-600 hover:text-green-900"
  >
    <CreditCard className="h-4 w-4" />
  </button>
)}

// Add modal
<UnifiedPaymentModal
  isOpen={paymentModalOpen}
  onClose={() => setPaymentModalOpen(false)}
  paymentData={paymentData}
  onSuccess={() => {
    toast.success('Payment completed!');
    refetch();
  }}
  onError={() => toast.error('Payment failed')}
/>
```

### 7. Update Payments Page
**File:** `/src/app/(portal)/payments/page.js`

**Changes:**
```javascript
import { useState } from 'react';
import { UnifiedPaymentModal } from '@/components/modals/unified-payment-modal';

const [paymentModalOpen, setPaymentModalOpen] = useState(false);
const [paymentData, setPaymentData] = useState(null);

// Update "Pay Now" button in arrears section
<button 
  onClick={() => {
    // You'll need to determine which invoice to pay
    // For now, we can pay the total arrears
    setPaymentData({
      type: 'invoice',
      id: arrears.overdue_invoices[0]?.id, // First overdue invoice
      amount: arrears.total,
      reference: 'Arrears Payment',
      description: `Payment for ${arrears.count} overdue invoice(s)`,
    });
    setPaymentModalOpen(true);
  }}
  className="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition"
>
  Pay Now
</button>

// Add modal
<UnifiedPaymentModal
  isOpen={paymentModalOpen}
  onClose={() => setPaymentModalOpen(false)}
  paymentData={paymentData}
  onSuccess={() => {
    toast.success('Payment completed!');
    reload();
  }}
  onError={() => toast.error('Payment failed')}
/>
```

### 8. Update Payment Interface Component (Optional)
**File:** `/src/components/payments/payment-interface.js`

**Decision:** This component can be deprecated in favor of UnifiedPaymentModal, or kept for specific use cases. If keeping it, update it to use the new `usePayment` hook.

## Files to Deprecate (Optional)

These files can be kept for backward compatibility or removed:

1. `/src/hooks/use-payments.js` - Old payment hook
2. `/src/hooks/use-payments-enhanced.js` - Enhanced payment hook
3. `/src/components/payments/payment-interface.js` - Old payment interface

## Benefits of This Consolidation

1. **Single Source of Truth**: All payments go through one hook and one modal
2. **Consistent UX**: Same payment experience everywhere
3. **Easier Maintenance**: Update payment logic in one place
4. **Better Error Handling**: Centralized error handling and retry logic
5. **Status Polling**: Built-in payment status polling
6. **Type Safety**: Clear payment types (order, invoice, quotation)

## Testing Checklist

- [ ] Checkout page payment flow
- [ ] Order details page payment
- [ ] Invoice details page payment
- [ ] Invoices list page payment
- [ ] Payments page arrears payment
- [ ] Payment status polling
- [ ] Pesepay redirect
- [ ] Success state handling
- [ ] Error state handling
- [ ] Modal close behavior

## Migration Steps

1. ✅ Create unified hook (`use-payment.js`)
2. ✅ Create unified modal (`unified-payment-modal.js`)
3. ⏳ Update checkout page
4. ⏳ Update order details page
5. ⏳ Update invoice details page
6. ⏳ Update invoices list page
7. ⏳ Update payments page
8. ⏳ Test all payment flows
9. ⏳ Remove old hooks (optional)
10. ⏳ Update documentation

## Next Steps

Run the following command to apply all changes:
```bash
# This will be done manually by updating each file
```

Or I can update each file individually for you. Would you like me to proceed with updating all the files?
