Saltar al contenido

Lección 20 de 25 · Lectura y práctica

Quiz: Webhooks y Eventos en Tiempo Real

Tipo de lección: QuizConcepto claveLos webhooks son notificaciones HTTP que Stripe envía a tu servidor cuando ocurren eventos importantes en tu cuenta. Imagina que contratas un servicio de vigilancia para tu casa: en lugar de.

Del concepto a la práctica

Taller de esta lección

Este quiz evalúa autenticidad, orden, duplicados y responsabilidad de cada evento. La respuesta correcta siempre relaciona la notificación con una transición concreta y evita asumir que recibir un mensaje equivale a completar una operación.

Ejemplo resuelto

Si llega dos veces invoice.payment_succeeded con el mismo event.id, el resultado debe ser un solo cambio a paid. Si llega una firma inválida, el procesador no debe leer el contenido como autoridad.

Verifica también dos event.id distintos que describan el mismo efecto de facturación. La unicidad de event.id protege un duplicado idéntico; la clave de acción sobre factura/pago protege el efecto de negocio entre eventos. Prueba un fallo después de guardar received pero antes de done y demuestra que el trabajador vuelve a procesarlo.

Pruébalo

  1. Clasifica tres eventos por tipo.

  2. Indica cuál requiere cuerpo crudo.

  3. Decide qué clave evita duplicados.

  4. Describe la respuesta ante firma inválida.

Error frecuente: devolver éxito para ocultar cualquier excepción. Corrección: responde según el contrato del endpoint y registra una causa técnica sin filtrar secretos.

Comprueba tu resultado

Debes mencionar firma, event.id, despacho por tipo y transición idempotente. El caso duplicado produce un solo efecto; el caso inválido produce rechazo y cero actualizaciones.

Proveedor de pago que envía un webhook verificado al servidor; registro idempotente antes de conceder acceso.
CursaloMapa de práctica
Confirmar el pago en el servidor

El servidor concede acceso a partir de un evento verificado del proveedor y un registro persistente. La pantalla de éxito del navegador es una notificación, no una prueba suficiente de pago. La idempotencia evita duplicar la operación cuando el evento llega más de una vez.

Ver la infografía en tamaño completo ↗
Fuentes para profundizar

Tipo de lección: Quiz

Concepto clave

Los webhooks son notificaciones HTTP que Stripe envía a tu servidor cuando ocurren eventos importantes en tu cuenta. Imagina que contratas un servicio de vigilancia para tu casa: en lugar de revisar constantemente las cámaras (polling), el sistema te llama automáticamente cuando detecta movimiento (evento). En Stripe, eventos como payment_intent.succeeded o invoice.payment_failed activan estos webhooks.

Los eventos en tiempo real permiten que tu aplicación reaccione inmediatamente a cambios en el estado de pagos, suscripciones o facturas. Esto es crucial para mantener la sincronización entre Stripe y tu base de datos, enviar confirmaciones automáticas o gestionar fallos en pagos recurrentes. Sin webhooks, tendrías que consultar constantemente la API de Stripe, lo que es ineficiente y puede causar retrasos.

Cómo funciona en la práctica

El flujo típico de un webhook de Stripe sigue estos pasos:

  1. Configuras un endpoint HTTPS en tu servidor (ej: https://tudominio.com/stripe-webhook)
  2. Registras este endpoint en el Dashboard de Stripe o vía API
  3. Cuando ocurre un evento relevante, Stripe envía una petición POST a tu endpoint
  4. Tu servidor verifica la firma del webhook para asegurar autenticidad
  5. Procesas el evento según su tipo y actualizas tu sistema
  6. Respondes con HTTP 200 para confirmar recepción

Por ejemplo, cuando un cliente cancela su suscripción, Stripe envía un evento customer.subscription.deleted. Tu servidor recibe este evento, actualiza el estado del usuario en tu base de datos a "inactivo" y posiblemente envía un email de confirmación.

Código en acción

Configuración básica de un endpoint de webhook en Node.js:

const express = require('express');
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const app = express();

// Middleware para parsear JSON
app.use(express.json());

app.post('/stripe-webhook', async (req, res) => {
  const sig = req.headers['stripe-signature'];
  let event;

  try {
    // Verificar la firma del webhook
    event = stripe.webhooks.constructEvent(
      req.body,
      sig,
      process.env.STRIPE_WEBHOOK_SECRET
    );
  } catch (err) {
    console.error(`⚠️  Error de verificación: ${err.message}`);
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }

  // Manejar diferentes tipos de eventos
  switch (event.type) {
    case 'payment_intent.succeeded':
      const paymentIntent = event.data.object;
      console.log(`Pago exitoso: ${paymentIntent.id}`);
      // Actualizar base de datos aquí
      break;
    case 'invoice.payment_failed':
      const invoice = event.data.object;
      console.log(`Pago fallido para factura: ${invoice.id}`);
      // Enviar notificación al cliente
      break;
    default:
      console.log(`Evento no manejado: ${event.type}`);
  }

  res.json({received: true});
});

app.listen(3000, () => {
  console.log('Servidor escuchando en puerto 3000');
});

Mejora con manejo de reintentos y logging:

// ANTES: Sin manejo de errores robusto
// Solo console.log básico

// DESPUÉS: Con manejo profesional
try {
  switch (event.type) {
    case 'customer.subscription.created':
      await handleSubscriptionCreated(event.data.object);
      break;
    case 'charge.refunded':
      await handleRefund(event.data.object);
      break;
  }
  
  // Registrar éxito para monitoreo
  console.log(`✅ Evento procesado: ${event.type} (ID: ${event.id})`);
  
} catch (error) {
  // Log detallado para debugging
  console.error(`❌ Error procesando ${event.type}:`, {
    error: error.message,
    eventId: event.id,
    timestamp: new Date().toISOString()
  });
  
  // IMPORTANTE: Siempre responder 200 para evitar reintentos infinitos
  // Stripe reintentará automáticamente en caso de error
}

Errores comunes

  • No verificar la firma del webhook: Cualquiera podría enviar peticiones falsas a tu endpoint. Siempre usa stripe.webhooks.constructEvent() con tu webhook secret.
  • No manejar eventos duplicados: Stripe puede enviar el mismo evento múltiples veces. Implementa idempotencia almacenando event.id procesados.
  • No responder rápidamente: Tu endpoint debe responder en menos de 10 segundos. Stripe reintentará si no responde a tiempo.
  • Procesar eventos en orden incorrecto: Algunos eventos deben procesarse en secuencia (ej: invoice.created antes de invoice.paid). Implementa colas si es necesario.
  • No probar webhooks localmente: Usa la CLI de Stripe (stripe listen --forward-to localhost:3000) para probar en desarrollo.

Checklist de dominio

  1. Configuré un endpoint HTTPS seguro para recibir webhooks
  2. Implementé verificación de firmas con stripe.webhooks.constructEvent()
  3. Manejo correctamente al menos 5 tipos de eventos diferentes
  4. Mi endpoint responde en menos de 5 segundos siempre
  5. Implementé logging detallado para todos los eventos procesados
  6. Probé webhooks en ambiente local usando stripe CLI
  7. Configuré reintentos automáticos para eventos fallidos

Implementa un sistema de notificaciones por email basado en webhooks

En este ejercicio práctico, crearás un sistema que envía emails automáticos basado en eventos de Stripe. Esto simula un escenario real donde necesitas notificar a clientes sobre cambios en sus suscripciones.

  1. Configura tu entorno:
    • Crea un proyecto Node.js con Express
    • Instala las dependencias: stripe, nodemailer, dotenv
    • Configura variables de entorno para STRIPE_SECRET_KEY y STRIPE_WEBHOOK_SECRET
  2. Crea el endpoint de webhook:
    • Implementa un endpoint POST en /api/stripe-webhook
    • Agrega verificación de firma usando stripe.webhooks.constructEvent()
    • Responde con HTTP 200 inmediatamente después de recibir el evento
  3. Implementa el manejo de eventos:
    • Procesa estos 3 eventos: invoice.payment_succeeded, invoice.payment_failed, customer.subscription.deleted
    • Para cada evento, llama a una función sendNotificationEmail() con los datos relevantes
    • Usa nodemailer para enviar emails (puedes usar un servicio como Mailtrap para testing)
  4. Agrega idempotencia:
    • Crea una tabla en tu base de datos o usa un array en memoria para almacenar event.id procesados
    • Antes de procesar cualquier evento, verifica que no haya sido procesado antes
    • Si ya fue procesado, responde 200 pero no ejecutes acciones duplicadas
  5. Prueba tu implementación:
    • Usa stripe CLI para enviar eventos de prueba a tu endpoint local
    • Verifica que los emails se envíen correctamente para cada tipo de evento
    • Prueba enviando el mismo evento dos veces y verifica que no se dupliquen emails
Pistas
  • Usa el método stripe.webhooks.generateTestHeaderString() para crear firmas de prueba en desarrollo
  • Implementa un sistema de colas simple con arrays si necesitas procesar eventos en orden específico
  • Para testing, configura nodemailer con Mailtrap (es gratuito y no envía emails reales)

Evalua tu comprension

Completa el quiz interactivo de arriba para ganar XP.

Sigue con Implementación Profesional de Suscripciones y Facturación con Stripe

Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.

Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.

01 / ELEGIR UNA RUTA

El próximo paso

Aprende IA mientras construyes algo que sí necesitas.

Empieza por el curso inicial o explora el catálogo para encontrar una práctica alineada con tu trabajo.