Cómo funciona el cobro — de qué se encarga Stripe y cómo el webhook otorga el derecho de uso

Este artículo forma parte del curso Fundamentos de informática, que construye desde cero los conocimientos prácticos de informática que necesitas como mínimo para programar y hacer vibe coding.
Los datos de la tarjeta se detienen en el proveedor de servicios de pago y no pasan por tu propio servidor. Con diagramas vemos por qué la notificación del webhook es lo que justifica habilitar las funciones de pago.

Este artículo trata cómo funciona el cobro.

Se divide en dos partes: evitar que los datos de la tarjeta lleguen a tu propio servidor y reflejar el resultado del pago en tu propia aplicación.

Por dónde pasan los datos de la tarjeta y qué justifica otorgar el derecho de uso
El usuario introducela tarjetaEl proveedorla recibeEl resultado llegacomo notificaciónAquí se detiene elnúmero de tarjetamy-app registrael derecho de uso
La rama superior son los datos de la tarjeta, que se detienen dentro del proveedor de servicios de pago. La rama inferior es el resultado del pago, y my-app solo mira esta para habilitar las funciones de pago.

El número de la tarjeta se detiene en la rama superior y no llega a my-app.

Lo único que justifica habilitar las funciones de pago es la notificación que llega por la rama inferior.

El número de la tarjeta lo recibe el proveedor de servicios de pago, que también se encarga del intercambio con el emisor de la tarjeta; a my-app solo le queda escribir el resultado en un registro.

Quien recibe los datos de la tarjeta es el proveedor de servicios de pago, no tu propio servidor

Para procesar un pago hacen falta el número de la tarjeta, la fecha de vencimiento y el código de seguridad.

El estándar que cumplen las empresas que manejan datos de tarjetas es PCI DSS (Payment Card Industry Data Security Standard), y un proveedor de servicios de pago (payment service provider) es un servicio externo que se encarga de los pagos con tarjeta por ti.

Stripe y PayPal son los proveedores de servicios de pago más conocidos.

Dónde coloques los campos de entrada determina por dónde pasa el número de la tarjeta.

Dónde están los camposPor dónde pasa el númeroAlcance de PCI DSS
my-app lo recibe y lo guardamy-app y el proveedor de pagomy-app también entra
my-app lo recibe y lo reenvíamy-app y el proveedor de pagomy-app también entra
La página del proveedorSolo el proveedor de pagoEl alcance de my-app es mínimo

Solo la tercera fila mantiene el número de la tarjeta fuera del servidor de my-app.

En ese caso a my-app solo le queda el valor que identifica el pago, mientras que en las dos primeras filas quedan el número de la tarjeta o el registro de la comunicación.

Aunque solo lo reenvíes sin guardarlo, el valor pasa por tu propio servidor y en el momento en que pasa, my-app también entra en el alcance de PCI DSS.

Para que la zona que my-app tiene que proteger sea lo más pequeña posible, dejas los campos de entrada en manos del proveedor de servicios de pago.

En un solo pago, hasta dónde llega cada dato
Un pago (pay_88)
Se queda solo dentro del proveedor
  • Número de tarjeta, fecha de vencimiento, código de seguridad
  • Registro del intercambio con el emisor de la tarjeta
Llega a my-app
  • El valor que identifica el pago, pay_88
  • El importe y si el pago se completó
  • De qué usuario es el pago (u_1024)
El marco exterior es un pago, pay_88. Los datos de la tarjeta se quedan solo dentro del marco superior. Lo único que tiene my-app es el hecho de que el pago se completó y el valor que lo identifica.

El número de la tarjeta no pasa por my-app

Si nunca recibes tú el número de la tarjeta, la responsabilidad de protegerlo tampoco cae de tu lado.

Tanto si lo guardas como si lo reenvías de inmediato, en cuanto pasa por tu propio servidor la responsabilidad es la misma, así que dejas los campos de entrada en manos del proveedor de servicios de pago y haces que a my-app solo llegue el hecho de que el pago se completó.

El pago termina en una página de pago que está en el dominio del proveedor de servicios de pago

Para que los datos de la tarjeta no pasen por tu propio servidor, la pantalla de entrada se coloca en otro lugar: eso es la página de pago alojada (hosted checkout page: la pantalla de pago que prepara el proveedor de servicios de pago y que se muestra en su dominio).

Mover al usuario a una pantalla de otro dominio es una redirección (redirect).

En la segunda etapa le pasas el importe y la URL de retorno, y el proveedor de servicios de pago devuelve la URL de una página de pago dedicada a ese pago.

Este intercambio se hace llamando a una Web API, y se le adjunta la clave de API.

Los dos dominios que el navegador tiene abiertos durante un pago
Navegador
El dominio de my-app
  • La pantalla de contratación del plan de pago
  • /thanks, que se abre después del pago
El dominio del proveedor de pago
  • La página de pago donde se introduce el número de tarjeta
  • my-app no ve lo que hay dentro de esta pantalla
El marco exterior es el navegador del usuario. El marco superior es la pantalla de my-app y el inferior la pantalla del proveedor de servicios de pago; una redirección lleva del de arriba al de abajo y luego de vuelta.

La página de pago también se ofrece como un marco colocado dentro de la propia pantalla de my-app.

Se ve distinto, pero los valores introducidos van al mismo lugar.

Dos formas de colocarla: qué cambia y qué no
Ir a unapágina aparteLa URL es delproveedorTras el pago,vuelve a /thanksPoner un marcoen la pantallaLa URL es demy-appTras el pago,la misma pantallaEn ambos casosEl número va alproveedor de pagomy-app solo recibeel hecho del pago
Las dos primeras filas son las diferencias entre cada forma de colocarla, y la última fila es lo que no cambia en ninguna de las dos. De izquierda a derecha: la forma de colocarla, la URL que aparece en el navegador y lo que pasa después del pago.

La página de pago la prepara el proveedor de servicios de pago

La pantalla donde se introduce el número de la tarjeta es del proveedor de servicios de pago, no de my-app.

Una redirección lleva al usuario a esa pantalla y, cuando termina el pago, vuelve a /thanks; y aunque la coloques como un marco dentro de tu pantalla, el destino de los valores introducidos no cambia.

Lo que justifica otorgar el derecho de uso es la notificación del webhook, no la pantalla a la que vuelve el usuario

Quien decide si se pueden mostrar las funciones de pago no es el proveedor de servicios de pago sino my-app, y ese registro es el derecho de uso (entitlement: el registro del conjunto de funciones que puede usar un usuario que ya pagó).

Que la pantalla del usuario vuelva a /thanks no basta para que my-app sepa si el pago se completó.

Mira lo que pasa después del pago como dos caminos separados.

Dos caminos hacia my-app cuando termina el pago
El navegador vaa /thanksLa pantalla diceque terminóSi se cierra,no llega nadaEl pago terminaen esa páginaEl servidor llamaa /webhookNotificacióncon firmaSe reenvíaun tiempo fijado
De un mismo pago salen dos caminos. El de arriba pasa por el navegador y puede detenerse a mitad; el de abajo va de servidor a servidor y sigue hasta recibir una respuesta de éxito.

El camino de arriba se detiene ahí mismo si el usuario cierra el navegador justo después de pagar.

El de abajo va de servidor a servidor, así que si la notificación no llega se reintenta un número de veces y durante un período fijados.

Según cuál tomes como justificación, las mismas tres personas terminan con derechos distintos.

Lo que le pasó a ese usuarioSi juzgas por /thanksSi juzgas por /webhook
Pagó y abrió /thanksSe otorga el derechoSe otorga el derecho
Pagó y cerró el navegador enseguidaNo se otorga el derechoSe otorga el derecho
Abrió /thanks sin pagarSe otorga el derechoNo se otorga el derecho

Si juzgas por /thanks, quien cerró el navegador se queda sin derecho y quien no pagó lo recibe.

Lo único que sirve para justificar que se otorgue el derecho es la notificación del camino de abajo.

En los pagos, aplicar dos veces la misma notificación alarga el doble el plazo de uso.

Guarda el valor que identifica cada notificación y no cambies el derecho cuando llega la segunda vez.

Cómo clasifica my-app lo que llega a /webhook
Notificación confirma inválidaevt_7 que llegapor primera vezevt_7reenviado/webhook lorecibeSe descarta; elderecho no cambiaOtorga y registraevt_7Ya registrado:no hace nada
Los tres de la izquierda llegan al mismo /webhook. Se reciben juntos en el centro, y la firma y el valor que identifica la notificación los separan en los tres de la derecha.

Una notificación cuya firma no coincide se descarta sin cambiar el derecho.

La única diferencia entre las dos restantes es si esa notificación ya se aplicó.

Los tres tipos de registros que hay en la base de datos de my-app
La base de datos de my-app
Registro del usuario
  • El valor que identifica al usuario, u_1024
  • El hash de la contraseña
Registro de derechos
  • Tipo de plan (paid)
  • Plazo de uso
  • De qué usuario es (u_1024)
Registro de las notificaciones recibidas
  • El valor que identifica la notificación, evt_7
  • La fecha y hora en que se aplicó
El marco exterior es la base de datos de my-app. El registro de derechos del centro guarda el tipo de plan y el plazo de uso. El registro de notificaciones de abajo es lo que evita aplicar dos veces una notificación reenviada.

Aunque ocultes el botón de pago en la pantalla, ese código llega igualmente al dispositivo del usuario.

Comprobar el derecho en el servidor cada vez es la misma autorización que vimos en Cómo funciona el inicio de sesión.

El número de la tarjeta se detiene dentro del marco del centro y no entra en el marco de la derecha.

El derecho se otorga cuando llega la notificación de la flecha 2, no cuando vuelve el navegador del usuario.

Quien avisa del pago es una notificación del servidor

Lo que avisa de que el pago se completó no es la pantalla a la que vuelve el usuario, sino la notificación que llega desde el servidor del proveedor de servicios de pago.

Se verifica la firma de lo que llega, no se cambia el derecho si esa notificación ya se aplicó, se escribe el resultado en tu propia base de datos y con eso se decide si se muestran las funciones de pago.

En una suscripción llega una notificación cada período y el derecho cambia

Un contrato que se cobra cada mes o cada año es una suscripción (subscription: un contrato en el que el pago se repite automáticamente cada cierto período).

Entre un pago único y una suscripción, lo que cambia es cuántas notificaciones llegan
Forma de pagoPago únicoUna notificaciónEl plazo delderecho no cambiaSuscripciónLlega en cadaperíodoEl plazo llegaal siguiente pago
A la izquierda está la forma de pago. El camino de arriba es de una sola vez, el de abajo es una suscripción. En los dos, lo que justifica el derecho es la notificación del webhook; lo que cambia es cuántas llegan y el plazo.

Un pago que se repite no siempre sale bien.

En la fila del fallo, el proveedor de servicios de pago deja pasar unos días y reintenta el cobro.

my-app decide si durante ese tiempo deja el acceso o lo corta enseguida.

Lo que te permite comprobarlo antes de publicar es el modo de prueba (test mode: un estado que prepara el proveedor de servicios de pago para comprobar el funcionamiento sin generar un cobro real).

Las claves de API de prueba y las de producción son distintas, así que cambias entre ellas con el valor de una variable de entorno.

Decide la notificación que quita el derecho antes de publicar

En una suscripción se cobra cada vez que llega el período, y en cada una llega una notificación.

Si solo procesas la notificación que otorga el derecho, los usuarios cuyos pagos se detuvieron se quedan usando la aplicación, así que decide para cada notificación que llega si otorga, alarga o quita, y antes de publicar recorre todo el flujo en el modo de prueba.

QUIZ

Verificación de conocimientos

Responde cada pregunta una a una.

Pregunta 1¿Por dónde pasan los datos de la tarjeta cuando cobras a través de un proveedor de servicios de pago?

Pregunta 2¿En qué te apoyas para dar por completado el pago y otorgar el derecho al usuario?

Pregunta 3¿Qué hace tu aplicación cuando llega una notificación de pago fallido en un cobro recurrente?