ML Engine Updates: - Updated BTCUSD with Polygon API data (2024-2025): 215,699 new records - Re-trained all ML models: Attention (R²: 0.223), Base, Metamodel (87.3% confidence) - Backtest results: +176.71R profit with aggressive_filter strategy Documentation Consolidation: - Created docs/99-analisis/_MAP.md index with 13 new analysis documents - Consolidated inventories: removed duplicates from orchestration/inventarios/ - Updated ML_INVENTORY.yml with BTCUSD metrics and training results - Added execution reports: FASE11-BTCUSD, correction issues, alignment validation Architecture & Integration: - Updated all module documentation with NEXUS v3.4 frontmatter - Fixed _MAP.md indexes across all folders - Updated orchestration plans and traces Files: 229 changed, 5064 insertions(+), 1872 deletions(-) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
406 lines
16 KiB
Markdown
406 lines
16 KiB
Markdown
---
|
||
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)
|