Webhooks explicados: payloads firmados y reintentos

Backend2026-10-27TryQuickToolBox

Acabas de integrar el webhook de un proveedor de pagos para recibir actualizaciones de transacciones. Todo funciona en las pruebas, pero en producción notas eventos faltantes durante picos de tráfico o cargos duplicados cuando el proveedor reintenta. Los webhooks son simples en concepto pero complicados en la práctica: cruzan límites de red, pueden retrasarse, duplicarse o falsificarse. Este artículo explica cómo construir consumidores y productores de webhooks robustos utilizando payloads firmados y estrategias de reintento inteligentes.

¿Qué son los webhooks?

Los webhooks son callbacks HTTP definidos por el usuario que se activan por eventos. Cuando algo sucede en un sistema de origen (por ejemplo, un nuevo pedido), envía una solicitud HTTP POST a una URL que proporcionas. A diferencia del polling, los webhooks envían datos casi en tiempo real, reduciendo la latencia y la carga del servidor.

Sin embargo, los webhooks introducen desafíos: asegurar que la solicitud realmente provenga del remitente esperado, manejar fallos con elegancia y evitar el procesamiento duplicado.

Asegurando webhooks con payloads firmados

Sin verificación, cualquiera puede enviar solicitudes falsas a tu endpoint de webhook. Los payloads firmados resuelven esto incluyendo una firma criptográfica que puedes validar.

Cómo funcionan las firmas HMAC

El remitente calcula un código de autenticación de mensaje basado en hash (HMAC) usando un secreto compartido y el cuerpo de la solicitud. La firma se envía en un encabezado (por ejemplo, X-Signature). Tú recalculas el HMAC de tu lado y comparas.

// Ejemplo en Node.js: verificando una firma de webhook
const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Siempre usa una función de comparación de tiempo constante como timingSafeEqual para prevenir ataques de temporización.

Incluye una marca de tiempo

Para prevenir ataques de repetición, incluye una marca de tiempo en el payload firmado y rechaza solicitudes con más de unos minutos de antigüedad (por ejemplo, 5 minutos). La marca de tiempo debe ser parte de los datos firmados.

Implementando reintentos confiables

Problemas de red o errores temporales del servidor pueden causar que la entrega del webhook falle. Un remitente robusto reintenta las entregas fallidas con retroceso exponencial.

Estrategia de reintentos

Ejemplo: Reintento con retroceso en Python

import time
import requests
from requests.exceptions import RequestException

def send_webhook(url, payload, max_retries=5):
    for attempt in range(max_retries):
        try:
            response = requests.post(url, json=payload, timeout=5)
            if response.status_code < 500:
                return True  # éxito o error del cliente (sin reintento)
        except RequestException:
            pass
        time.sleep(2 ** attempt)  # retroceso exponencial
    return False

Mejores prácticas para consumidores de webhooks

Comparación: Webhooks vs Polling

AspectoWebhooksPolling
LatenciaCasi en tiempo realDepende del intervalo
Carga del servidorBaja (solo push)Alta (solicitudes frecuentes)
ComplejidadMayor (necesita endpoint, seguridad)Menor
ConfiabilidadRequiere reintentosReintentos inherentes

Preguntas frecuentes

¿Qué es un payload de webhook firmado?

Un payload firmado incluye una firma criptográfica (generalmente HMAC) que permite al receptor verificar la autenticidad e integridad de la solicitud.

¿Cuántas veces debo reintentar un webhook fallido?

Una práctica común es de 3 a 5 reintentos con retroceso exponencial, pero depende de tu SLA y la criticidad del evento.

¿Puedo usar webhooks sin HTTPS?

No, siempre usa HTTPS para proteger el payload y la firma de intercepciones. HTTP simple expone datos sensibles.

Al depurar payloads de webhooks, es posible que necesites formatear JSON rápidamente. Prueba nuestro Formateador JSON para imprimir y validar respuestas JSON de manera legible.