--- id: "US-INV-003" title: "Realizar Depósito" type: "User Story" status: "Done" priority: "Media" epic: "OQI-004" project: "trading-platform" story_points: 3 created_date: "2025-12-05" updated_date: "2026-01-04" --- # US-INV-003: Realizar Depósito ## Metadata | Campo | Valor | |-------|-------| | **ID** | US-INV-003 | | **Épica** | OQI-004 - Cuentas de Inversión | | **Módulo** | investment | | **Prioridad** | P0 | | **Story Points** | 5 | | **Sprint** | Sprint 5 | | **Estado** | Pendiente | | **Asignado a** | Por asignar | --- ## Historia de Usuario **Como** inversor con cuenta activa, **quiero** realizar depósitos a mi cuenta de inversión, **para** incrementar mi capital invertido y aumentar mis potenciales retornos. ## Descripción Detallada El usuario debe poder depositar fondos en su cuenta de inversión mediante Stripe. El proceso incluye seleccionar método de pago, ingresar monto, confirmar la transacción, y recibir confirmación. Los fondos deben reflejarse en el balance inmediatamente tras confirmación de Stripe. ## Mockups/Wireframes ``` ┌─────────────────────────────────────────────────────────────────┐ │ DEPOSITAR EN ATLAS │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ Balance actual: $500.00 USD │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Monto a depositar │ │ │ │ ┌──────────────────────────────────────────────┐ │ │ │ │ │ $ │ │ │ │ │ └──────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ [ ] $100 [ ] $500 [ ] $1,000 [ ] Otro │ │ │ │ │ │ │ │ Mínimo: $50 USD │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Método de pago │ │ │ │ │ │ │ │ ( ) Tarjeta de crédito/débito │ │ │ │ ( ) Transferencia bancaria (ACH) │ │ │ │ │ │ │ │ [+ Agregar nuevo método de pago] │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ 📋 Resumen │ │ │ │ Monto: $1,000.00 │ │ │ │ Comisión Stripe: $30.00 (3%) │ │ │ │ ───────────────────────────── │ │ │ │ Total a pagar: $1,030.00 │ │ │ │ │ │ │ │ Nuevo balance: $1,500.00 │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ CONFIRMAR DEPÓSITO │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## Criterios de Aceptación **Escenario 1: Depósito exitoso con tarjeta** ```gherkin DADO que el usuario tiene cuenta de inversión activa Y tiene método de pago guardado CUANDO ingresa monto de $1,000 Y selecciona tarjeta guardada Y hace click en "Confirmar depósito" ENTONCES se procesa el pago con Stripe Y se actualiza balance de cuenta (+$1,000) Y se crea transacción tipo "deposit" con status "completed" Y se muestra mensaje de confirmación Y se envía email de confirmación ``` **Escenario 2: Monto menor al mínimo** ```gherkin DADO que el usuario está en página de depósito CUANDO ingresa monto de $25 Y el mínimo es $50 ENTONCES se muestra error "El monto mínimo es $50 USD" Y el botón de confirmar está deshabilitado ``` **Escenario 3: Pago rechazado por Stripe** ```gherkin DADO que el usuario intenta depositar $1,000 CUANDO Stripe rechaza el pago (fondos insuficientes) ENTONCES se muestra mensaje "Pago rechazado: fondos insuficientes" Y NO se actualiza el balance Y se crea transacción con status "failed" Y se registra el error en logs ``` **Escenario 4: Primer depósito (sin método de pago)** ```gherkin DADO que el usuario no tiene método de pago guardado CUANDO intenta depositar ENTONCES se redirige a formulario de Stripe Y ingresa datos de tarjeta Y se guarda el método de pago para futuro Y se procesa el depósito ``` **Escenario 5: Depósito con cuenta inactiva** ```gherkin DADO que la cuenta de inversión está en status "closed" CUANDO intenta acceder a /deposit ENTONCES se muestra error "Cuenta cerrada" Y se redirige a página de cuentas ``` ## Criterios Adicionales - [ ] Mostrar estimado de nuevo balance antes de confirmar - [ ] Permitir guardar método de pago para futuros depósitos - [ ] Mostrar comisiones de Stripe claramente - [ ] Implementar rate limiting (máx 5 depósitos/hora) - [ ] Enviar notificación push tras depósito exitoso --- ## Tareas Técnicas **Database:** - [ ] DB-INV-001: Verificar schema de investment.transactions - [ ] DB-INV-002: Verificar schema de payments.payment_methods - [ ] DB-INV-003: Índice en (account_id, transaction_type) **Backend:** - [ ] BE-INV-001: Crear endpoint POST /investment/accounts/:id/deposit - [ ] BE-INV-002: Implementar DepositService.processDeposit() - [ ] BE-INV-003: Integración con Stripe Payment Intent - [ ] BE-INV-004: Implementar DepositService.updateBalance() - [ ] BE-INV-005: Webhook Stripe para confirmaciones - [ ] BE-INV-006: Enviar email de confirmación - [ ] BE-INV-007: Validación de monto mínimo/máximo **Frontend:** - [ ] FE-INV-001: Crear página DepositPage.tsx - [ ] FE-INV-002: Integrar Stripe Elements - [ ] FE-INV-003: Crear componente AmountSelector.tsx - [ ] FE-INV-004: Crear componente PaymentMethodSelector.tsx - [ ] FE-INV-005: Crear componente DepositSummary.tsx - [ ] FE-INV-006: Implementar depositStore **Tests:** - [ ] TEST-INV-001: Test unitario DepositService - [ ] TEST-INV-002: Test integración Stripe - [ ] TEST-INV-003: Test webhook handling - [ ] TEST-INV-004: Test E2E flujo depósito completo --- ## Dependencias **Depende de:** - [ ] US-INV-002: Abrir cuenta - Estado: Pendiente - [ ] OQI-005: Integración Stripe - Estado: Pendiente **Bloquea:** - [ ] US-INV-004: Ver dashboard portfolio - [ ] US-INV-006: Solicitar retiro --- ## Notas Técnicas **Endpoints involucrados:** | Método | Endpoint | Descripción | |--------|----------|-------------| | POST | /investment/accounts/:id/deposit | Iniciar depósito | | GET | /investment/accounts/:id/payment-methods | Métodos de pago | | POST | /webhooks/stripe/deposit | Webhook Stripe | **Entidades/Tablas:** - `investment.accounts`: Actualizar balance - `investment.transactions`: Registrar depósito - `payments.payment_methods`: Métodos de pago Stripe **Request Body POST /deposit:** ```typescript { amount: 1000, paymentMethodId: "pm_xxx", // Stripe Payment Method ID currency: "USD", savePaymentMethod: true } ``` **Response:** ```typescript { transaction: { id: "uuid", accountId: "uuid", type: "deposit", amount: 1000, status: "completed", stripePaymentIntentId: "pi_xxx", createdAt: "2025-12-05T..." }, account: { id: "uuid", balance: 1500, // balance actualizado updatedAt: "2025-12-05T..." } } ``` **Flujo Stripe:** 1. Frontend crea Payment Intent via backend 2. Stripe Elements captura datos de pago 3. Backend confirma Payment Intent 4. Stripe envía webhook de confirmación 5. Backend actualiza balance y transacción **Límites:** - Depósito mínimo: $50 USD - Depósito máximo: $50,000 USD por transacción - Rate limit: 5 depósitos/hora por usuario --- ## Definition of Ready (DoR) - [x] Historia claramente escrita - [x] Criterios de aceptación definidos - [x] Story points estimados - [x] Dependencias identificadas - [ ] Integración Stripe documentada - [ ] Diseño/mockup disponible - [x] API spec disponible ## Definition of Done (DoD) - [ ] Código implementado según criterios - [ ] Tests unitarios escritos y pasando - [ ] Tests de integración pasando - [ ] Integración Stripe funcionando - [ ] Webhooks configurados - [ ] Code review aprobado - [ ] Documentación actualizada - [ ] QA aprobado - [ ] Desplegado en ambiente de pruebas --- ## Historial de Cambios | Fecha | Cambio | Autor | |-------|--------|-------| | 2025-12-05 | Creación | Requirements-Analyst | --- **Creada por:** Requirements-Analyst **Fecha:** 2025-12-05 **Última actualización:** 2025-12-05