Saltar al contenido principal

RF45: Sistema valida pago

Descripción

El sistema valida que un pago de suscripción se haya completado correctamente antes de activar o mantener el acceso premium, usando como fuente de verdad los webhooks firmados de Stripe (no la respuesta del cliente).

Procesa invoice.payment_succeeded (pago confirmado) e invoice.payment_failed (fallo → dunning), siempre tras verificar la firma con stripe.webhooks.constructEvent() (Stripe §Webhooks).

CampoValor
MóduloSubscription Module
ActorSistema (handler de webhooks)
EndpointPOST /webhooks/stripe
PrecondicionesStripe emite un evento de pago
PrioridadAlta (MVP)
EtapaMVP
Requisitos relacionadosRF38, RF41, RF42, RF46

Reglas de negocio

  • RN-45.1 — Todo evento se valida con la firma del webhook (STRIPE_WEBHOOK_SECRET) antes de procesarse.
  • RN-45.2 — El acceso premium se concede/mantiene solo con un pago confirmado por webhook.
  • RN-45.3 — Un pago fallido activa el dunning y la notificación (RF41); no concede acceso.
  • RN-45.4 — El procesamiento es idempotente: reintentos del mismo evento no duplican efectos.
  • RN-45.5 — Los eventos se registran (auditoría) sin datos de tarjeta.

Validaciones / consideraciones

AspectoRegla
FirmaconstructEvent obligatorio.
IdempotenciaPor event.id (no reprocesar).
TiposSolo eventos soportados; el resto se ignora seguro.

Criterios de aceptación

Escenario 1: Pago confirmado

Dado que Stripe emite invoice.payment_succeeded con firma válida, Cuando el backend lo procesa, Entonces confirma el pago, mantiene/activa el acceso premium, Y registra el pago (RF41 notifica).

Escenario 2: Pago fallido

Dado que Stripe emite invoice.payment_failed con firma válida, Cuando el backend lo procesa, Entonces marca la suscripción en gracia (dunning) y notifica al usuario (RF41), Y no concede acceso premium adicional.

Escenario 3: Firma inválida (seguridad)

Dado que llega un webhook con firma inválida o cuerpo manipulado, Cuando el backend lo verifica, Entonces lo rechaza con 400 y no altera ningún estado.

Escenario 4: Evento duplicado (idempotencia)

Dado que Stripe reintenta el mismo event.id, Cuando el backend lo recibe de nuevo, Entonces no duplica la activación ni la notificación.

Criterios no funcionales

  • Respuesta rápida al webhook (procesamiento pesado en segundo plano si aplica).
  • Sin datos de tarjeta en logs; comunicación TLS 1.2+.

Diagrama de secuencia