Stripe en una app construida con IA: cinco bugs de pago que corregir

Las apps hechas con IA suelen marcar pedidos como pagados desde el navegador. Los cinco bugs de Stripe que cuestan dinero, cómo detectarlos y qué hacer.

En esta página · 6 secciones
  1. 1. El acceso se otorga en la página de éxito
  2. 2. El webhook no verifica la firma
  3. 3. El mismo pago se procesa dos veces
  4. 4. El precio viene del navegador
  5. 5. Solo se maneja el primer pago
  6. ¿Qué debes revisar antes de salir a producción?

Puntos clave

  • El bug de pago más común en las apps construidas con IA es dar acceso cuando el navegador llega a la página de éxito. La propia documentación de Stripe dice que no puedes confiar en esa página.
  • Procesa los pedidos desde un webhook verificado, haz que el procesamiento sea seguro de ejecutar dos veces y toma los precios de tu servidor, nunca del navegador.
  • Cada bug de abajo se puede detectar en pocos minutos leyendo una función o haciendo una compra de prueba.

Agregar Stripe a una app construida con IA parece fácil: la herramienta de IA genera un botón de checkout, haces un pago de prueba y aparece una página de éxito. El problema es lo que pasa detrás de esa página. En muchos prototipos, la app decide que un cliente pagó porque el navegador lo dijo, y cualquiera que pueda editar una solicitud en el navegador también puede decirlo.

Estos son los cinco bugs de pago que vale la pena corregir antes de cobrar dinero real, cada uno con lo que recomienda la documentación de Stripe. Este artículo forma parte de la guía para preparar un prototipo construido con IA para usuarios reales.

1. El acceso se otorga en la página de éxito

La app muestra una página de “Gracias por tu compra” después del checkout y, en esa página, marca el pedido como pagado o activa la suscripción. Fallan dos cosas: los clientes que pagan y cierran la pestaña nunca reciben lo que pagaron, y cualquiera que encuentre la URL de éxito puede visitarla sin pagar.

Stripe lo dice sin rodeos: “No puedes depender de activar el procesamiento del pedido solo desde la página de destino del checkout, porque no está garantizado que los clientes visiten esa página” (Stripe). La solución es un webhook: Stripe llama a tu servidor con un evento checkout.session.completed y tu servidor otorga el acceso. La página de éxito puede entonces mostrar el resultado, pero ya no es la que lo decide.

Cómo detectarlo: busca en el código dónde un pedido o una suscripción pasa a estar “pagado” o “activo”. Si ocurre en un componente de página o después de una redirección, es este bug.

2. El webhook no verifica la firma

Una vez que el webhook existe, cualquiera puede enviar solicitudes a su URL. Stripe firma cada evento con un secreto que solo tú y Stripe conocen, y advierte que “sin verificación, un atacante podría enviar eventos de webhook falsos a tu endpoint para activar acciones como procesar pedidos, otorgar acceso a cuentas o modificar registros” (Stripe).

La verificación es una sola llamada a una función en las bibliotecas de Stripe, usando el cuerpo sin procesar de la solicitud, el header Stripe-Signature y tu signing secret whsec_…. Una falla común en el código generado por IA es convertir primero el cuerpo a JSON, lo que lo modifica y hace que la verificación falle; la “solución” termina siendo quitar la verificación.

Cómo detectarlo: abre el handler del webhook. Si lee event.type sin llamar antes a una función de verificación, cualquiera puede falsificar un pago.

3. El mismo pago se procesa dos veces

Stripe reintenta los eventos que no reciben una respuesta de éxito rápida, hasta por tres días en modo live, y dice que los endpoints “pueden recibir ocasionalmente el mismo evento más de una vez” (Stripe). Si tu handler agrega créditos, envía una clave de licencia o crea un pedido cada vez que se ejecuta, algunos clientes los recibirán dos veces.

La recomendación de Stripe es registrar los IDs de los eventos que ya procesaste y omitir los que ya viste, y hacer que el procesamiento sea “seguro de ejecutar varias veces, incluso de forma concurrente” (Stripe). En la práctica: guarda el ID de la Checkout Session con el pedido y usa una restricción de unicidad para que una segunda inserción falle.

Cómo detectarlo: reenvía un evento desde el panel de Stripe. Si el cliente recibe algo por duplicado, es este bug.

4. El precio viene del navegador

El botón de checkout envía el monto a tu servidor, o directamente a Stripe desde el frontend. Cualquiera puede cambiar 4900 por 100 en la solicitud y comprar por un dólar.

La solución es crear los precios en Stripe (o mantenerlos en tu servidor) y que el navegador envíe solo qué producto y cuántas unidades. Tu servidor consulta el precio y crea la Checkout Session. Lo mismo aplica a descuentos, nombres de planes y cantidades: el navegador pide, el servidor decide.

Cómo detectarlo: mira la solicitud que envía el botón de checkout. Si contiene un monto o un precio, es este bug.

5. Solo se maneja el primer pago

Los prototipos suelen manejar un solo evento: el primer checkout exitoso. Los pagos reales tienen vida después de eso. Las transferencias bancarias y otros métodos diferidos se completan más tarde, y Stripe envía checkout.session.async_payment_succeeded o …_failed cuando eso ocurre (Stripe). Las suscripciones se renuevan, fallan, se cancelan y se disputan, cada caso con su propio evento.

Si la app solo escucha el primer evento, los clientes cuya tarjeta falla el mes siguiente conservan el acceso para siempre, y los que pagaron por transferencia bancaria nunca lo reciben. Haz una lista de los eventos de los que depende tu negocio y maneja cada uno, sin suponer que llegan en orden: Stripe no garantiza el orden de los eventos.

Cómo detectarlo: en el panel de Stripe, revisa a qué tipos de evento está suscrito tu endpoint de webhook. Si es solo checkout.session.completed y vendes suscripciones, es este bug.

¿Qué debes revisar antes de salir a producción?

  • Usa claves de prueba y de producción separadas, guardadas solo en el servidor. La clave secreta (sk_live_…) nunca va en el frontend; consulta claves secretas en tu frontend.
  • Registra por separado el endpoint de webhook de producción: los endpoints de prueba y de producción tienen signing secrets distintos.
  • Haz una compra real con una tarjeta real, reembólsala y comprueba que el acceso se otorgó y luego se manejó correctamente.

Preguntas frecuentes

¿Necesito webhooks de Stripe si uso Stripe Checkout?

Sí. Stripe dice que no puedes depender solo de la página de éxito para procesar pedidos, porque es posible que los clientes nunca lleguen a ella. Los webhooks son necesarios si vendes suscripciones o aceptas métodos de pago que se confirman más tarde, como las transferencias bancarias.

¿Cómo evito solicitudes falsas de webhook de Stripe?

Verifica la firma de cada evento con la biblioteca de Stripe, usando el cuerpo sin procesar de la solicitud, el header Stripe-Signature y el signing secret de tu endpoint. Rechaza cualquier evento que no pase la verificación antes de hacer nada con él.

¿Por qué a mi cliente se le cobró una vez pero recibió dos pedidos?

Stripe puede entregar el mismo evento más de una vez y reintenta los eventos que exceden el tiempo de espera. Registra el ID de cada Checkout Session o evento cuando lo procesas y omite cualquier ID que ya hayas procesado.

Fuentes

  1. Stripe — Fulfill orders
  2. Stripe — Receive Stripe events in your webhook endpoint
AIPaymentsStripeWebhooks

Filipe Eduardo

Ingeniero de Software Sénior. Siete años creando productos web y móviles de punta a punta y liderando los equipos que los entregan.

Sígueme

¿Quieres hablar
de esto?

Trabajo en problemas así todos los días. Cuéntame el tuyo.

Contáctame