- Add TASK-2026-01-25-OQI-005-PAYMENTS-ADVANCED folder - Update FRONTEND_INVENTORY: payments 4→8, progress 50%→65% - Update MASTER_INVENTORY: frontend 135→139 - Update _INDEX.yml: total 14→15 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
255 lines
5.3 KiB
Markdown
255 lines
5.3 KiB
Markdown
# 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
|