# 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 // 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; 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([]); const [selectedTx, setSelectedTx] = useState(null); // Fetch refunds useEffect(() => { fetch('/api/refunds') .then(res => res.json()) .then(data => setRefunds(data.refunds)); }, []); return ( <> {selectedTx && ( 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