Saltar al contenido principal

RF33: Usuario selecciona modelo de suscripción

Descripción

Como usuario autenticado, quiero seleccionar un plan de suscripción para iniciar el proceso de contratación y obtener acceso premium.

Al seleccionar un plan de pago se inicia el flujo de checkout: se asegura un Customer de Stripe y se prepara la creación de la Subscription con el Price correspondiente. El pago efectivo se realiza en RF38.

CampoValor
MóduloSubscription Module
ActorUsuario autenticado
EndpointPOST /subscription/checkout
PrecondicionesSesión activa; plan válido seleccionado
PrioridadAlta (MVP)
EtapaMVP
Requisitos relacionadosRF32, RF35, RF38

Reglas de negocio

  • RN-33.1 — Si el usuario no tiene stripe_customer_id, se crea un Customer en Stripe y se persiste (idempotente).
  • RN-33.2 — Seleccionar el plan Free no requiere pago; aplica de inmediato.
  • RN-33.3 — Para planes de pago, se prepara el checkout y se solicita método de pago si no existe (RF35).
  • RN-33.4 — Un cambio entre planes de pago (upgrade/downgrade) usa subscriptions.update() con prorrateo automático de Stripe.
  • RN-33.5 — En móvil, si el cobro es in-app, se usa el flujo de la tienda; si es web-first, se redirige a la web (Suscripciones Mobile).

Validaciones de entrada

CampoReglasMensaje de error
planIdObligatorio. Plan válido del catálogo."Selecciona un plan válido."
AuthorizationBearer válido."Sesión no válida." (401)

Criterios de aceptación

Escenario 1: Selección de plan de pago

Dado que selecciono Pro Mensual, Cuando confirmo la selección, Entonces el sistema asegura mi Customer de Stripe, Y prepara el checkout para ese Price, Y me solicita registrar un método de pago si no tengo uno (RF35), Y responde 200 OK con el siguiente paso.

Escenario 2: Selección de plan Free

Dado que selecciono el plan Free, Cuando confirmo, Entonces el sistema aplica el plan Free sin requerir pago.

Escenario 3: Cambio de plan (upgrade/downgrade)

Dado que ya tengo un plan de pago activo, Cuando selecciono otro plan de pago, Entonces el sistema usa subscriptions.update() y Stripe calcula el prorrateo.

Escenario 4: Plan inválido

Dado que envío un planId inexistente, Cuando el backend valida, Entonces responde 400 con "Selecciona un plan válido".

Criterios no funcionales

  • Llamadas de creación a Stripe con idempotency key para evitar duplicar customers/subscriptions.
  • STRIPE_SECRET_KEY solo en el servidor; comunicación TLS 1.2+.

Diagrama de secuencia