socorrist.app

Stripe webhook 401

Cuando alguien te paga, Stripe llama a tu app para avisarla. Tu app está contestando que no está autorizado a hablar, y Stripe se da por vencido. El dinero ha entrado y está en tu cuenta de Stripe; lo que no ha pasado es todo lo que tu app hacía después: dar de alta al cliente, activar su acceso, mandarle el correo.

Ya de paso: ¿tu app está exponiendo datos?

Analízala gratis mientras lees. Tarda treinta segundos y no toca nada.

Solo leemos lo que tu app ya le entrega a cualquier visitante.

Por qué te pasa

El caso más frecuente es el secreto de firma. Stripe firma cada aviso y tu app comprueba esa firma antes de fiarse, que es exactamente lo que debe hacer. Si el secreto que tiene tu app no es el de ese endpoint concreto, la comprobación falla y responde con un 401. Y hay dos trampas dentro: cada endpoint tiene su propio secreto, y el modo de prueba y el real tienen secretos distintos. Copiar el del endpoint equivocado es sorprendentemente fácil.

El segundo caso es más sutil y desespera a mucha gente: el secreto es correcto pero la comprobación falla igual. Ocurre cuando algo lee y transforma el contenido del aviso antes de verificarlo. La firma se calcula sobre el texto exacto que envió Stripe, así que si tu app lo convierte a otro formato por el camino, aunque el contenido sea el mismo, ya no coincide.

El tercero no tiene nada que ver con Stripe: que la ruta esté detrás de una protección general. Si tu app exige sesión iniciada para todo, Stripe no tiene sesión y recibe un 401. Y hay una versión de esto que despista muchísimo: si tienes activada la protección de despliegues en Vercel, tu propio hosting responde con un 401 antes de que la petición llegue siquiera a tu código. Puedes tener todo perfecto y seguir viendo el error.

El cuarto es de entorno cruzado: el endpoint apunta a una dirección de preview que ya no existe, o está configurado en modo real mientras tu app usa claves de prueba.

Lo que este error no significa

Arréglalo tú, gratis

Primero mira cuánto se ha perdido, luego arregla, y al final recupera. Ese último paso es el que casi nadie hace y es el que devuelve a tus clientes lo que pagaron.

  1. 1En Stripe, ve a Developers y luego Webhooks, y abre tu endpoint. Ahí verás los intentos fallidos y, pulsando en uno, la respuesta exacta que devolvió tu app. Apunta cuántos hay y de cuándo: esos son los clientes que han pagado y no han recibido nada.
  2. 2Comprueba lo más tonto antes que nada: que la dirección del endpoint sea la de tu dominio actual y esté bien escrita, y que el modo del endpoint (prueba o real) coincida con las claves que usa tu app.
  3. 3En esa misma pantalla del endpoint, revela el secreto de firma y cópialo. Asegúrate de que es el de este endpoint y no el de otro que crearas antes. Pégalo en la variable de entorno de tu hosting, sustituyendo el valor anterior por completo, y vuelve a desplegar.
  4. 4Si sigue dando 401, comprueba si tienes activada la protección de despliegues en Vercel, en Settings y luego Deployment Protection. Si está activa, tu hosting rechaza a Stripe antes de llegar a tu código: hay que desactivarla o dejar esa ruta fuera de la protección.
  5. 5Manda un evento de prueba desde el propio panel de Stripe, con el botón de enviar evento de prueba, y comprueba que ahora responde correctamente.
  6. 6Y ahora lo importante: vuelve a la lista de avisos fallidos y reenvíalos uno a uno con el botón de reenviar. Tu app los procesará como si acabaran de ocurrir, y cada cliente recibirá por fin lo que pagó. Hazlo cuanto antes: Stripe no guarda los eventos indefinidamente.

Antes de reenviar en masa, comprueba que tu código aguanta recibir dos veces el mismo aviso sin duplicar nada. Si no lo has comprobado, reenvía uno solo y mira qué pasa.

Y esto para la parte de código

Pégaselo tal cual al agente que escribió tu app. Está redactado para que te diga lo que ha hecho, no solo para que lo haga.

Prompt para pegarle a tu agente

Mi endpoint de webhook de Stripe responde 401 y los pagos no se están registrando en la app.

Necesito que hagas esto:
1. Enséñame el código del endpoint del webhook y dime en qué orden hace las cosas: si lee el contenido de la petición tal cual llegó o si lo transforma antes de verificar la firma. Si lo transforma antes, corrígelo: la firma se calcula sobre el texto exacto que envía Stripe.
2. Comprueba que la verificación de firma se hace siempre y que un fallo de verificación devuelve un error sin procesar nada. No la quites nunca ni la hagas opcional.
3. Comprueba si esa ruta está afectada por algún middleware de autenticación o por cualquier comprobación de sesión, y déjala accesible sin sesión: quien llama es Stripe, no un usuario.
4. Haz el manejo del evento idempotente: si llega dos veces el mismo identificador de evento, no debe duplicar nada. Voy a reenviar avisos antiguos y necesito estar seguro de esto antes.
5. Añade un registro de cada evento recibido con su identificador y su tipo, para poder comprobar después qué se procesó y qué no.

Dime al terminar qué variable de entorno guarda el secreto de firma y confírmame que se lee del servidor y no lleva prefijo público.

¿Lo has intentado y sigue sin salir?

O el escáner de arriba ha encontrado algo y prefieres no tocarlo solo. En cualquiera de los dos casos esto ya es de los gordos y merece un humano: no es que no hayas sabido, es que has llegado al punto en que hace falta alguien que entre y lo vea por dentro.

Cita a partir de mañana

Agendar revisión

99 €

Elegimos hueco, miro tu app con calma y te digo qué pasa y cómo se arregla.

  • Sesión de trabajo en directo contigo
  • Diagnóstico del error y del riesgo real
  • Te quedas con el arreglo aplicado

Hoy, en cola prioritaria

Rescate exprés

199 €

Entras en la cola de hoy. Reservas hueco y lo dejamos resuelto en el día.

  • Hueco el mismo día
  • Prioridad sobre las revisiones agendadas
  • Mismo trabajo, antes

Quién lo arregla

Marc Sala

IT Manager

  • Analista de ciberseguridad certificado por Google

No es un rating anónimo de un marketplace: es la persona que va a entrar en tu app. Reviso el código, encuentro qué falla y lo arreglo contigo delante.