--- id: "US-PAY-006" title: "Agregar Método de Pago" type: "User Story" status: "Done" priority: "Media" epic: "OQI-005" project: "trading-platform" story_points: 3 created_date: "2025-12-05" updated_date: "2026-01-04" --- # US-PAY-006: Agregar Método de Pago **Version:** 1.0.0 **Fecha:** 2025-12-05 **Estado:** ✅ Implementado **Story Points:** 3 **Prioridad:** P0 (Crítica) **Épica:** [OQI-005](../_MAP.md) --- ## Historia de Usuario **Como** usuario registrado de Trading Platform **Quiero** agregar y gestionar mis métodos de pago **Para** realizar compras y renovar suscripciones sin fricciones --- ## Criterios de Aceptación ### AC-001: Ver Métodos de Pago **Dado** que estoy en mi configuración de cuenta **Cuando** navego a la sección "Métodos de Pago" **Entonces** debería ver: - Lista de métodos de pago guardados - Para cada método: - Marca de tarjeta (Visa, Mastercard, Amex) - Últimos 4 dígitos - Fecha de expiración - Badge "Predeterminado" si aplica - Opciones: "Hacer predeterminado" | "Eliminar" - Botón "Agregar Método de Pago" - Mensaje si no tengo métodos: "No tienes métodos de pago guardados" ### AC-002: Agregar Nueva Tarjeta **Dado** que quiero agregar un método de pago **Cuando** hago click en "Agregar Método de Pago" **Entonces** debería ver modal con: - Stripe Elements para ingresar tarjeta - Número de tarjeta - Fecha de expiración (MM/YY) - CVC - Nombre del titular - Checkbox "Hacer predeterminado" - Botón "Guardar Tarjeta" - Botón "Cancelar" ### AC-003: Validación de Tarjeta **Dado** que estoy agregando una tarjeta **Cuando** ingreso datos inválidos **Entonces** debería ver errores específicos: - "Número de tarjeta inválido" - "Fecha de expiración inválida o pasada" - "Código de seguridad inválido" - "Nombre del titular requerido" ### AC-004: Guardar Tarjeta Exitosamente **Dado** que ingresé datos válidos de tarjeta **Cuando** hago click en "Guardar Tarjeta" **Entonces** debería: - Ver indicador de procesamiento - Ver mensaje de éxito: "Método de pago agregado" - Ver la nueva tarjeta en la lista - Cerrar modal automáticamente - Si es mi primera tarjeta → Marcarla como predeterminada ### AC-005: Verificación 3D Secure al Agregar **Dado** que mi tarjeta requiere verificación 3DS **Cuando** intento guardar la tarjeta **Entonces** debería: - Ver modal/iframe de autenticación del banco - Completar autenticación (SMS, app, etc.) - Ver confirmación después de autenticación exitosa - Ver error si autenticación falla ### AC-006: Cambiar Método Predeterminado **Dado** que tengo múltiples métodos de pago **Cuando** hago click en "Hacer predeterminado" en una tarjeta **Entonces** debería: - Ver confirmación: "Método predeterminado actualizado" - Ver badge "Predeterminado" en tarjeta seleccionada - Remover badge de tarjeta anterior - Usar esta tarjeta en futuras compras/renovaciones ### AC-007: Eliminar Método de Pago **Dado** que quiero eliminar una tarjeta **Cuando** hago click en "Eliminar" **Entonces** debería: - Ver confirmación: "¿Eliminar tarjeta •••• 4242?" - Opciones: "Cancelar" | "Eliminar" - Al confirmar → Tarjeta desaparece de la lista - Si era predeterminada y hay más tarjetas → Auto-seleccionar otra ### AC-008: No Eliminar si Suscripción Activa **Dado** que tengo suscripción activa **Cuando** intento eliminar mi único método de pago **Entonces** debería: - Ver error: "No puedes eliminar tu único método de pago mientras tienes una suscripción activa" - Sugerencia: "Agrega otro método de pago primero o cancela tu suscripción" - NO permitir eliminación ### AC-009: Tarjeta Expirada **Dado** que tengo una tarjeta que expira pronto (< 30 días) **Cuando** veo mis métodos de pago **Entonces** debería: - Ver badge "⚠️ Por Expirar" en la tarjeta - Ver mensaje: "Tu tarjeta expira en {X} días. Actualízala para evitar interrupciones." - Botón "Actualizar Tarjeta" ### AC-010: Actualizar Tarjeta Expirada **Dado** que mi tarjeta expiró o está por expirar **Cuando** hago click en "Actualizar Tarjeta" **Entonces** debería: - Ver formulario pre-llenado con últimos 4 dígitos (solo lectura) - Poder ingresar nueva fecha de expiración y CVC - Guardar actualización sin agregar nueva tarjeta - Ver confirmación: "Tarjeta actualizada" --- ## Mockup ``` ┌─────────────────────────────────────────────────────────────┐ │ │ │ Métodos de Pago │ │ │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ [Visa] •••• 4242 Exp: 12/25 │ │ │ │ Juan Pérez │ │ │ │ │ │ │ │ [Predeterminado] [Eliminar] │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ [Mastercard] •••• 5555 Exp: 08/26 │ │ │ │ Juan Pérez │ │ │ │ │ │ │ │ [Hacer Predeterminado] [Eliminar] │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ [Amex] •••• 0005 Exp: 03/25 ⚠️ │ │ │ │ Juan Pérez Por Expirar │ │ │ │ │ │ │ │ [Actualizar Tarjeta] [Eliminar] │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ ➕ Agregar Método de Pago │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ℹ️ Tu método predeterminado se usará para renovaciones │ │ automáticas y compras rápidas. │ │ │ └─────────────────────────────────────────────────────────────┘ ───────────── Modal: Agregar Método de Pago ───────────── ┌─────────────────────────────────────────────────────────────┐ │ [X] │ │ Agregar Método de Pago │ │ │ │ Número de tarjeta │ │ ┌───────────────────────────────────────────────────┐ │ │ │ 4242 4242 4242 4242 [Visa] │ │ │ └───────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────┐ ┌──────────────────────┐ │ │ │ Vencimiento │ │ CVC │ │ │ │ ┌──────────────────┐ │ │ ┌──────────────────┐ │ │ │ │ │ 12 / 25 │ │ │ │ 123 │ │ │ │ │ └──────────────────┘ │ │ └──────────────────┘ │ │ │ └──────────────────────┘ └──────────────────────┘ │ │ │ │ Nombre del titular │ │ ┌───────────────────────────────────────────────────┐ │ │ │ Juan Pérez │ │ │ └───────────────────────────────────────────────────┘ │ │ │ │ ☑ Hacer predeterminado │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Guardar Tarjeta │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ [Cancelar] │ │ │ │ 🔒 Tus datos están protegidos con encriptación Stripe │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Flujo de Usuario (Gherkin) ```gherkin Feature: Gestión de Métodos de Pago Scenario: Agregar primera tarjeta Given que soy usuario logueado "juan@example.com" And NO tengo métodos de pago guardados When navego a "Configuración → Métodos de Pago" Then debería ver "No tienes métodos de pago guardados" When hago click en "Agregar Método de Pago" Then debería ver modal con formulario de tarjeta When ingreso tarjeta "4242 4242 4242 4242" And ingreso vencimiento "12/25" And ingreso CVC "123" And ingreso nombre "Juan Pérez" And hago click en "Guardar Tarjeta" Then debería ver "Método de pago agregado" And debería ver tarjeta "Visa •••• 4242" en la lista And debería tener badge "Predeterminado" Scenario: Cambiar método predeterminado Given que tengo 2 tarjetas guardadas And "Visa •••• 4242" es predeterminada When hago click en "Hacer predeterminado" en "MC •••• 5555" Then debería ver "Método predeterminado actualizado" And "MC •••• 5555" debería tener badge "Predeterminado" And "Visa •••• 4242" NO debería tener badge Scenario: No eliminar único método con suscripción activa Given que tengo suscripción "Pro" activa And tengo solo 1 método de pago When intento eliminar mi única tarjeta Then debería ver error "No puedes eliminar tu único método de pago..." And la tarjeta NO debería eliminarse Scenario: Tarjeta por expirar Given que tengo tarjeta "Amex •••• 0005" que expira en 20 días When veo mis métodos de pago Then debería ver badge "⚠️ Por Expirar" en esa tarjeta And debería ver mensaje "Tu tarjeta expira en 20 días..." ``` --- ## Notas Técnicas ### Frontend - Componente: `apps/frontend/src/pages/Settings/PaymentMethods.tsx` - Modal: `AddPaymentMethodModal.tsx` - Integrar Stripe Elements: `CardElement` o `PaymentElement` - Fetch métodos desde: `GET /api/v1/payments/payment-methods` ### Backend **Endpoints:** 1. `GET /api/v1/payments/payment-methods` - Listar payment methods del Customer - Response: ```json { "paymentMethods": [ { "id": "pm_xxx", "brand": "visa", "last4": "4242", "expMonth": 12, "expYear": 2025, "name": "Juan Pérez", "isDefault": true } ] } ``` 2. `POST /api/v1/payments/payment-methods` - Crear PaymentMethod - Adjuntar a Customer - Request: ```json { "paymentMethodId": "pm_xxx", "setAsDefault": true } ``` 3. `PUT /api/v1/payments/payment-methods/:id/default` - Cambiar default PaymentMethod 4. `DELETE /api/v1/payments/payment-methods/:id` - Validar que no sea único con suscripción activa - Desvincular de Customer en Stripe ### Stripe API **Crear PaymentMethod:** ```typescript const paymentMethod = await stripe.paymentMethods.create({ type: 'card', card: { token: 'tok_xxx', // Desde Stripe Elements }, }); // Adjuntar a Customer await stripe.paymentMethods.attach(paymentMethod.id, { customer: customerId, }); // Hacer default await stripe.customers.update(customerId, { invoice_settings: { default_payment_method: paymentMethod.id, }, }); ``` **Listar PaymentMethods:** ```typescript const paymentMethods = await stripe.paymentMethods.list({ customer: customerId, type: 'card', }); ``` **Eliminar PaymentMethod:** ```typescript await stripe.paymentMethods.detach(paymentMethodId); ``` ### Validaciones - Validar que usuario sea dueño del Customer - No permitir eliminar único método si hay suscripción activa - Validar fecha de expiración futura - Auto-marcar primera tarjeta como default --- ## Dependencias - Stripe Customer creado (se crea en primer pago o suscripción) - Sistema de suscripciones (para validar restricción) --- ## Requerimientos Relacionados - [RF-PAY-001: Sistema de Planes y Suscripciones](../requerimientos/RF-PAY-001-suscripciones.md) - [RF-PAY-002: Checkout con Stripe Elements](../requerimientos/RF-PAY-002-checkout.md) --- ## Tareas Técnicas ### Frontend - [ ] Página `PaymentMethods.tsx` - [ ] Modal `AddPaymentMethodModal.tsx` - [ ] Integrar Stripe Elements - [ ] Validación de formulario - [ ] Modal de confirmación de eliminación - [ ] Mostrar alertas de expiración ### Backend - [ ] Endpoint `GET /payment-methods` - [ ] Endpoint `POST /payment-methods` - [ ] Endpoint `PUT /payment-methods/:id/default` - [ ] Endpoint `DELETE /payment-methods/:id` - [ ] Validar no eliminar único método con suscripción - [ ] Crear Customer si no existe ### Testing - [ ] Test: Agregar tarjeta válida exitosamente - [ ] Test: Validación de tarjeta inválida - [ ] Test: Cambiar método predeterminado - [ ] Test: Eliminar tarjeta no-default - [ ] Test: No eliminar único método con suscripción activa - [ ] Test: 3DS funciona al agregar tarjeta - [ ] Test: Detectar tarjeta por expirar (< 30 días)