# 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 OrbiQuant
**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)
