Configurar webhooks de Stripe te permite reaccionar en tiempo real cuando un usuario cancela su suscripción, cambia datos de pago o se da de alta. En esta guía aprenderás a conectar un webhook de Stripe con una edge function de Supabase para registrar bajas y darles seguimiento desde tu propio panel de administración.
¿Qué son los webhooks de Stripe y para qué sirven?
Un webhook es una notificación automática que Stripe envía a una URL tuya cada vez que ocurre un evento dentro de tu cuenta. En lugar de consultar la API constantemente, tú escuchas los eventos que te interesan y reaccionas cuando llegan.
En la práctica, esto te permite avisar a tu equipo de ventas o go-to-market cuando alguien actualiza su tarjeta, se suscribe o cancela. El evento clave para detectar bajas es customer.subscription.deleted, que se dispara justo cuando finaliza una suscripción [00:55].
¿Qué evento de Stripe se activa cuando un usuario cancela su suscripción? El evento customer.subscription.deleted. Se dispara automáticamente al terminar la suscripción y puedes enrutarlo a tu backend para registrar la baja.
¿Cómo conecto Stripe con una edge function de Supabase?
Dentro del dashboard de Stripe existe una herramienta llamada Workbench que se abre desde la barra inferior. Ahí puedes ver logs de pagos, inspeccionar eventos y, sobre todo, gestionar tus webhooks.
El flujo para conectar Stripe con Supabase es directo:
- Abrir Workbench y entrar a la sección de Webhooks.
- Hacer clic en Add destination y seleccionar tu cuenta como origen de eventos.
- Buscar y elegir el evento, en este caso
customer.subscription.deleted.
- Marcar webhook endpoint como tipo de destino.
- Asignar un nombre descriptivo, por ejemplo
Supabase Database.
Antes de pegar la URL, necesitas crear el endpoint del lado de Supabase. Para eso le pides a Lovable que genere una edge function que reciba el evento, extraiga la información y la guarde en una tabla nueva llamada canceled_subscriptions.
¿Qué incluye un buen plan de implementación?
Cuando trabajas con chat mode en Lovable conviene revisar el plan antes de ejecutarlo. En este caso, el plan contemplaba cuatro elementos clave:
- Crear la tabla
canceled_subscriptions en Supabase.
- Generar la edge function que recibe el webhook.
- Configurar políticas RLS para que solo administradores accedan a la tabla.
- Verificar la firma del webhook y extraer los datos relevantes.
Las políticas RLS (Row Level Security) son fundamentales aquí: garantizan que los usuarios regulares jamás puedan ver suscripciones de otras personas, algo crítico cuando manejas datos de pago.
¿Cómo funciona el signing secret y por qué lo necesitas?
Stripe firma cada webhook con un signing secret para que tu servidor pueda verificar que la petición viene realmente de Stripe y no de un atacante. Sin esa verificación, cualquiera podría llamar a tu endpoint y crear registros falsos.
El orden correcto es un poco contraintuitivo: primero generas el endpoint en Supabase, luego pegas esa URL en Stripe, y solo después Stripe te muestra el signing secret que debes guardar en tus variables de entorno.
Mientras tanto, puedes pasarle a Lovable una clave falsa temporal y reemplazarla más tarde pidiéndole replay para que vuelva a mostrar el cuadro de entrada del secret [04:30].
¿Qué es el signing secret de Stripe? Es una clave única por endpoint que Stripe usa para firmar cada webhook. Tu servidor la utiliza para validar que la petición es legítima antes de procesarla.
¿Cómo pruebo un webhook sin esperar a un cliente real?
Stripe incluye un shell dentro del Workbench que te permite disparar eventos de prueba con comandos. El comando correcto sigue este patrón:
bash
stripe trigger customer.subscription.deleted
Un detalle fácil de pasar por alto: el comando debe empezar con stripe. Si solo escribes trigger customer.subscription.deleted no se ejecuta. Además, al teclear customer el shell autocompleta con todos los eventos disponibles, lo cual ayuda mucho cuando no recuerdas el nombre exacto.
Al ejecutarlo, Stripe simula toda la cadena de eventos previos hasta llegar a la cancelación, así tu endpoint recibe un payload realista [07:30].
¿Qué hago si el webhook devuelve error 400?
Es común encontrarse con dos errores típicos en la primera implementación:
- Webhook signature verification failed: indica que la firma no coincide. Suele resolverse ajustando cómo la edge function lee y verifica el header de Stripe.
- No customer email found: ocurre cuando el usuario asociado a la suscripción ya fue eliminado y no tiene correo.
La segunda solución consistió en ajustar la lógica para insertar el registro aunque falte el email, guardando siempre el Stripe customer ID. Así el equipo de soporte puede copiar ese identificador, pegarlo en Stripe y encontrar al cliente sin depender del correo [10:45].
Desde el panel de Stripe puedes reenviar un evento fallido con Resend sin tener que volver a ejecutar el comando del shell, lo que acelera muchísimo el ciclo de depuración.
¿Qué funcionalidad puedes construir sobre esta tabla?
Una vez que los eventos llegan correctamente y se almacenan, la tabla canceled_subscriptions se convierte en la base para todo un flujo de retención. Algunas extensiones útiles que se pueden agregar:
- Marcar si un usuario ya recibió un follow-up.
- Filtrar la lista por fecha de cancelación.
- Vincular cada registro al Stripe customer ID para consultas rápidas.
- Asignar la cancelación a un representante específico del equipo.
Este tipo de integración convierte un evento técnico en una oportunidad real de negocio: contactar al cliente que se fue, entender su motivo y, cuando aplica, recuperarlo.
¿Ya implementaste webhooks de Stripe en tu producto? Cuéntame en los comentarios qué eventos estás escuchando y cómo los estás usando para mejorar tu retención.