RF39: Usuario cancela suscripción
Descripción
Como usuario autenticado con suscripción de pago, quiero cancelar mi suscripción para dejar de pagar manteniendo el acceso hasta el fin del periodo ya pagado.
Se usa subscriptions.update({ cancel_at_period_end: true }) para no interrumpir el acceso hasta el vencimiento; el webhook customer.subscription.deleted revoca el acceso premium cuando vence (Stripe §4 Cancelación). Al vencer, el usuario es degradado a Free (RF42).
| Campo | Valor |
|---|---|
| Módulo | Subscription Module |
| Actor | Usuario autenticado |
| Endpoint | POST /subscription/cancel |
| Precondiciones | Sesión activa; suscripción de pago activa |
| Prioridad | Alta (MVP) |
| Etapa | MVP |
| Requisitos relacionados | RF41, RF42, RF44 |
Reglas de negocio
- RN-39.1 — La cancelación es
cancel_at_period_end: el acceso premium se mantiene hasta el fin del periodo pagado. - RN-39.2 — No se generan reembolsos automáticos del periodo en curso (salvo política específica).
- RN-39.3 — El usuario puede reactivar antes del vencimiento (deshacer la cancelación programada).
- RN-39.4 — Al vencer, el webhook
customer.subscription.deleteddispara la degradación a Free (RF42) y la notificación (RF41).
Validaciones de entrada
| Campo | Reglas | Mensaje de error |
|---|---|---|
Authorization | Bearer válido. | "Sesión no válida." (401) |
| Estado | Debe existir una suscripción de pago activa. | "No tienes una suscripción activa para cancelar." (409) |
Criterios de aceptación
Escenario 1: Cancelación exitosa
Dado que tengo una suscripción de pago activa,
Cuando confirmo la cancelación,
Entonces el sistema marca cancel_at_period_end: true en Stripe,
Y responde 200 OK indicando hasta cuándo conservo el acceso,
Y mantengo premium hasta el fin del periodo.
Escenario 2: Reactivación antes del vencimiento
Dado que cancelé pero aún no vence el periodo, Cuando reactivo la suscripción, Entonces el sistema deshace la cancelación programada y la renovación vuelve a estar activa.
Escenario 3: Sin suscripción activa
Dado que estoy en plan Free,
Cuando intento cancelar,
Entonces el sistema responde 409 con "No tienes una suscripción activa para cancelar".
Escenario 4: Degradación al vencer
Dado que llega el fin del periodo de una suscripción cancelada,
Cuando Stripe emite customer.subscription.deleted,
Entonces el sistema me degrada a Free (RF42) y me notifica (RF41).
Criterios no funcionales
- Idempotencia en la llamada de cancelación; comunicación TLS 1.2+.
- El estado premium se sincroniza por webhook validado.