# 06-DOCUMENTACION.md - OQI-005 Payments Advanced Components

## Documentación Técnica

### Componentes Creados

| Componente | LOC | Tipos | Descripción |
|------------|-----|-------|-------------|
| StripeElementsWrapper | 220 | 1 | Foundation PCI-DSS |
| InvoicePreview | 350 | 4 | Vista previa factura |
| RefundRequestModal | 480 | 3 | Modal reembolsos |
| RefundList | 450 | 2 | Historial reembolsos |
| **Total** | **1500** | **10** | |

---

## API de Componentes

### StripeElementsWrapper

```typescript
interface StripeConfig {
  publicKey: string;
  locale?: 'en' | 'es' | 'auto';
  appearance?: 'stripe' | 'night' | 'flat';
}

interface StripeElementsWrapperProps {
  config: StripeConfig;
  children: React.ReactNode;
}

// Uso
<StripeElementsWrapper config={{ publicKey: 'pk_test_...' }}>
  <PaymentForm />
</StripeElementsWrapper>

// HOC
const WrappedComponent = withStripeElements(MyComponent, config);

// Hook
const isAvailable = useStripeAvailable();
```

### InvoicePreview

```typescript
interface InvoiceLineItem {
  id: string;
  description: string;
  quantity: number;
  unitPrice: number;
  total: number;
}

interface InvoiceDiscount {
  code?: string;
  description: string;
  type: 'percentage' | 'fixed';
  value: number;
  amount: number;
}

interface InvoiceTax {
  name: string;
  rate: number;
  amount: number;
}

interface InvoicePreviewData {
  invoiceNumber?: string;
  items: InvoiceLineItem[];
  subtotal: number;
  discounts?: InvoiceDiscount[];
  taxes?: InvoiceTax[];
  total: number;
  currency?: string;
  periodStart?: string;
  periodEnd?: string;
  notes?: string;
}

interface InvoicePreviewProps {
  data: InvoicePreviewData;
  onConfirm?: () => void;
  onCancel?: () => void;
  confirmLabel?: string;
  cancelLabel?: string;
  isLoading?: boolean;
  showActions?: boolean;
}
```

### RefundRequestModal

```typescript
type RefundReason =
  | 'duplicate'
  | 'fraudulent'
  | 'customer_request'
  | 'product_issue'
  | 'other';

interface RefundEligibility {
  eligible: boolean;
  maxAmount: number;
  reason?: string;
  daysRemaining?: number;
}

interface RefundRequestData {
  transactionId: string;
  amount: number;
  reason: RefundReason;
  explanation: string;
}

interface RefundRequestModalProps {
  isOpen: boolean;
  onClose: () => void;
  transactionId: string;
  transactionAmount: number;
  transactionDate: string;
  eligibility: RefundEligibility;
  onSubmit: (data: RefundRequestData) => Promise<void>;
  currency?: string;
}
```

### RefundList

```typescript
type RefundStatus =
  | 'pending'
  | 'processing'
  | 'completed'
  | 'failed'
  | 'cancelled';

interface Refund {
  id: string;
  transactionId: string;
  amount: number;
  currency: string;
  status: RefundStatus;
  reason: string;
  explanation?: string;
  createdAt: string;
  processedAt?: string;
  failureReason?: string;
}

interface RefundListProps {
  refunds: Refund[];
  totalCount: number;
  currentPage: number;
  pageSize: number;
  onPageChange: (page: number) => void;
  onStatusFilter?: (status: RefundStatus | 'all') => void;
  selectedStatus?: RefundStatus | 'all';
  isLoading?: boolean;
  onRefundClick?: (refund: Refund) => void;
}
```

---

## Integración con Backend

### Endpoints Requeridos

| Endpoint | Método | Componente |
|----------|--------|------------|
| `/api/payments/stripe/config` | GET | StripeElementsWrapper |
| `/api/invoices/preview` | POST | InvoicePreview |
| `/api/refunds/eligibility/:txId` | GET | RefundRequestModal |
| `/api/refunds` | POST | RefundRequestModal |
| `/api/refunds` | GET | RefundList |

### Ejemplo de Integración

```typescript
// pages/payments/refunds.tsx
import { RefundList, RefundRequestModal } from '@/components/payments';

export default function RefundsPage() {
  const [refunds, setRefunds] = useState<Refund[]>([]);
  const [selectedTx, setSelectedTx] = useState<string | null>(null);

  // Fetch refunds
  useEffect(() => {
    fetch('/api/refunds')
      .then(res => res.json())
      .then(data => setRefunds(data.refunds));
  }, []);

  return (
    <>
      <RefundList
        refunds={refunds}
        totalCount={100}
        currentPage={1}
        pageSize={10}
        onPageChange={handlePageChange}
      />

      {selectedTx && (
        <RefundRequestModal
          isOpen={true}
          onClose={() => setSelectedTx(null)}
          transactionId={selectedTx}
          // ...other props
        />
      )}
    </>
  );
}
```

---

## Consideraciones de Seguridad

### PCI-DSS Compliance

1. **StripeElementsWrapper** asegura que:
   - Datos de tarjeta nunca tocan nuestros servidores
   - Tokenización manejada por Stripe
   - Comunicación directa cliente-Stripe

2. **Recomendación**: Migrar `PaymentMethodForm` existente para usar `CardElement` de Stripe Elements en lugar de inputs manuales.

### Validaciones

- RefundRequestModal valida montos contra elegibilidad
- Explicación requerida para todas las solicitudes
- Estados de error manejados apropiadamente

---

## Próximos Pasos

1. **Backend Integration**
   - Implementar endpoints de refunds
   - Configurar webhooks de Stripe para status updates

2. **Frontend Enhancements**
   - Migrar PaymentMethodForm a Stripe Elements
   - Agregar tests unitarios
   - Implementar páginas de gestión de reembolsos

3. **OQI-005 Remaining**
   - Progress actual: 65%
   - Pendiente: Dispute management, Advanced billing
