Error: firma de webhook inválida
Agentes SaaS valida la firma HMAC de todos los webhooks entrantes de ElevenLabs y de PayPal para garantizar que los eventos son legítimos. Si la firma no coincide, el webhook se rechaza con un 403 Forbidden.
¿Dónde ver los errores de firma?
- Vercel Logs: ve a tu proyecto en vercel.com → Logs → filtra por
/api/webhooks/. - ElevenLabs: en tu cuenta ElevenLabs → Agents → tu agente → Webhook → Delivery Attempts, verás los intentos fallidos con código de respuesta.
- PayPal: en el Developer Dashboard → Webhooks → Recent deliveries.
---
Webhook ElevenLabs — firma inválida
Causa 1: Secret incorrecto o no configurado
El secret de webhook debe coincidir exactamente entre ElevenLabs y tu variable de entorno.
1. En ElevenLabs → Agents → tu agente → Webhook → copia el Signing Secret.
2. En Vercel → Settings → Environment Variables, busca ELEVENLABS_WEBHOOK_SECRET.
3. Pega el valor exacto. Cualquier espacio en blanco extra causa falla.
4. Redespliega el proyecto para que la variable tome efecto.
ELEVENLABS_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Causa 2: Cuerpo del request modificado por middleware
La validación HMAC se hace sobre el raw body del request. Si algún middleware de Next.js parsea el JSON antes de llegar al handler, la firma fallará.
Verifica que el API route del webhook tenga el body parsing deshabilitado:
// app/api/webhooks/elevenlabs/route.ts
export const config = {
api: {
bodyParser: false,
},
};
En el App Router de Next.js 16, el raw body se obtiene con request.arrayBuffer() antes de parsear.
Causa 3: Secret rotado en ElevenLabs sin actualizar en Vercel
Si rotaste el signing secret en ElevenLabs, debes actualizar ELEVENLABS_WEBHOOK_SECRET en Vercel y redesplegar. Ver Rotar secrets.
---
Webhook PayPal — firma inválida
PayPal usa su propio sistema de verificación (verify-webhook-signature) que requiere cuatro variables:
PAYPAL_WEBHOOK_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
PAYPAL_CLIENT_ID=AXxxxxxxxxxxxxxxxxxxxxxxxxxxxx
PAYPAL_CLIENT_SECRET=EGxxxxxxxxxxxxxxxxxxxxxxxxxxxx
PAYPAL_MODE=live
Diagnóstico
1. Confirma que PAYPAL_WEBHOOK_ID corresponde al webhook registrado en el Developer Dashboard de PayPal, no a un evento individual.
2. Confirma que PAYPAL_MODE coincide con el entorno: live para producción, sandbox para pruebas.
3. PayPal sandbox y producción tienen Client IDs y Secrets distintos. No los mezcles.
Probar manualmente
curl -X POST https://agentes-saas-ten.vercel.app/api/webhooks/paypal \
-H "Content-Type: application/json" \
-H "PAYPAL-TRANSMISSION-ID: test-123" \
-H "PAYPAL-CERT-URL: https://api.paypal.com/v1/notifications/certs/CERT-..." \
-d '{"event_type":"PAYMENT.CAPTURE.COMPLETED","resource":{}}'
Una respuesta 200 indica que el endpoint está activo; la firma inválida devolverá 403.
---
Si el problema persiste
Exporta los últimos 10 intentos de webhook desde ElevenLabs o PayPal y envíalos junto con los Vercel Logs a soporte@cognitex.app. Incluye el request-id del header para trazabilidad.