Saltar al contenido principal

Stripe — Suscripciones en Plataforma Web

Finnova usa Stripe como procesador de pagos para la gestión de suscripciones de la plataforma web. Stripe asume la responsabilidad de cumplimiento PCI-DSS en el procesamiento de tarjetas, lo que reduce significativamente la superficie de riesgo en nuestra infraestructura (ver Compliance y Privacidad).


Casos de uso

1. Alta de suscripción

Cuando un usuario nuevo elige un plan de pago:

  • Se crea un Customer en Stripe asociado a su cuenta Finnova.
  • El usuario introduce sus datos de tarjeta directamente en Stripe Elements (nunca pasan por nuestros servidores).
  • Se crea una Subscription en Stripe vinculada al plan (Price) correspondiente.
  • El webhook customer.subscription.created activa el acceso a funcionalidades premium en nuestra base de datos.

2. Renovación automática

Las suscripciones se renuevan automáticamente según el ciclo del plan (mensual / anual):

  • Stripe intenta el cobro al inicio del nuevo período.
  • El webhook invoice.payment_succeeded confirma la renovación y extiende el acceso.
  • Si el cobro falla, invoice.payment_failed activa el flujo de dunning (reintentos automáticos de Stripe) y se notifica al usuario por email.

3. Cambio de plan (upgrade / downgrade)

  • Se llama a stripe.subscriptions.update() con el nuevo Price.
  • Stripe calcula el prorrateo automáticamente.
  • El webhook customer.subscription.updated sincroniza el plan activo en nuestra BD.

4. Cancelación

  • El usuario puede cancelar desde la app en cualquier momento.
  • Se llama a stripe.subscriptions.update({ cancel_at_period_end: true }) para no interrumpir el acceso hasta fin del período ya pagado.
  • El webhook customer.subscription.deleted revoca el acceso premium cuando vence.

5. Actualización de método de pago

  • El usuario accede al Customer Portal de Stripe (hosted page) para actualizar su tarjeta sin que nosotros manejemos los datos.
  • Se genera la sesión con stripe.billingPortal.sessions.create() y se redirige al usuario.

Planes definidos

PlanCicloDescripción
FreeAcceso básico sin costo
Pro MensualMensualAcceso completo; renovación cada mes
Pro AnualAnualAcceso completo; precio reducido vs. mensual

Los Price IDs de Stripe se almacenan como variables de entorno y nunca se hardcodean en el código.


Integración

Flujo general

Frontend

  • Usar Stripe.js + Stripe Elements para el formulario de tarjeta.
  • Nunca manejar números de tarjeta en nuestro código.
  • Confirmar el pago con stripe.confirmPayment() o stripe.confirmCardSetup() para 3D Secure si aplica.

Backend

  • SDK oficial de Stripe para Node.js (stripe npm package).
  • Crear un Customer la primera vez que un usuario inicia una suscripción de pago y persistir el stripe_customer_id en la tabla de usuarios.
  • Todos los endpoints de pagos requieren autenticación previa del usuario.
  • La clave secreta de Stripe (STRIPE_SECRET_KEY) solo vive en variables de entorno del servidor — nunca en el cliente.

Webhooks

Registrar un único endpoint en el backend (p. ej. POST /webhooks/stripe) que reciba y valide todos los eventos con la Webhook Signing Secret.

Eventos a manejar:

EventoAcción en nuestra BD
customer.subscription.createdActivar plan premium
customer.subscription.updatedActualizar plan activo
customer.subscription.deletedRevocar acceso premium
invoice.payment_succeededRegistrar pago exitoso
invoice.payment_failedMarcar suscripción en gracia / notificar usuario

Validación: siempre verificar la firma del webhook con stripe.webhooks.constructEvent() antes de procesar cualquier payload.


Variables de entorno requeridas

STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_PRICE_PRO_MONTHLY=price_...
STRIPE_PRICE_PRO_ANNUAL=price_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...

NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY es la única variable que puede exponerse al cliente.


Consideraciones de seguridad

  • PCI-DSS: Stripe maneja el procesamiento de tarjetas. Nuestro scope queda reducido a SAQ A (el más simple).
  • Idempotency keys: usar en todas las llamadas de creación a la API de Stripe para evitar cargos duplicados ante reintentos.
  • Modo test: usar claves sk_test_ / pk_test_ en desarrollo y staging; nunca mezclar con producción.
  • Logs: no registrar en logs ni almacenar números de tarjeta, CVV ni datos de autenticación de pago.