Skip to main content
El checkout custom de Reval existe porque el checkout nativo de Shopify no puede crear autorizaciones de débito automático con Mercado Pago. Es una página embebida en el theme de la tienda que maneja tres responsabilidades críticas: validar que el acceso sea legítimo (link firmado), tokenizar la tarjeta en el navegador sin que los datos toquen el servidor de Reval, y orquestar la creación del mandato (preapproval) con monto libre en MP. Todo el flujo está diseñado para que la tarjeta del suscriptor nunca salga de su navegador en texto claro.

Flujo técnico del checkout

1

El suscriptor llega al checkout con un link firmado

El buy box genera un link firmado con HMAC-SHA256 que contiene los parámetros de la suscripción. El servidor de Reval valida la firma y la expiración antes de renderizar la página. Si la firma es inválida o el link expiró, el usuario es redirigido a la página de producto con un mensaje de error.
2

El checkout carga el SDK JS de Mercado Pago

La página inyecta el SDK de MP desde el CDN oficial de Mercado Pago. El SDK se inicializa con la public key del merchant (no la secret key — esa nunca sale del servidor). La public key solo sirve para tokenizar tarjetas; no puede ejecutar cobros.
3

El usuario ingresa sus datos de tarjeta y el SDK tokeniza en el navegador

El SDK de MP monta un formulario de tarjeta con campos PCI-compliant directamente en el DOM usando mp.fields.create(). Cada campo sensible (número de tarjeta, CVV, vencimiento) se renderiza dentro de un iframe alojado en los servidores de MP — los datos de tarjeta nunca existen como texto plano en el JavaScript de la página. Al confirmar, el SDK los envía directamente a MP y devuelve un token opaco de un solo uso.
El token de MP es de uso único y de vida corta (expira en minutos). Si el suscriptor recarga la página después de que el SDK generó el token pero antes de que el servidor lo procesara, el token queda inválido. En ese caso, el usuario debe ingresar su tarjeta nuevamente desde cero — el checkout detecta el error de token expirado devuelto por la API de MP y muestra el formulario vacío.
4

El frontend envía el token al servidor de Reval

El checkout hace un POST al endpoint del servidor de Reval enviando el card_token_id junto con los metadatos de la suscripción. Los datos de tarjeta nunca viajan en este request — solo el token opaco generado por el SDK.
El servidor re-valida la firma del payload antes de continuar. Si alguien forjó el request omitiendo el link firmado, la operación se rechaza.
5

El servidor crea el preapproval (mandato) en MP con monto libre

Con el card_token_id, el servidor de Reval llama a la API de preapprovals de MP. El mandato se crea con transaction_amount libre — es decir, sin un monto fijo por ciclo. Esto permite cobrar el monto exacto (producto + envío + impuestos calculados en vivo) en cada ciclo futuro.
El campo transaction_amount: null es lo que habilita el mandato con monto libre. A diferencia de los planes fijos de MP (donde el monto se define al crear el mandato), un mandato con monto libre permite que el servidor especifique el monto en el momento de ejecutar cada cobro. Esto es indispensable para que el precio cobrado refleje siempre los valores actuales de la tienda.
6

MP devuelve el preapproval_id

Si la creación del mandato es exitosa, MP responde con el objeto preapproval que incluye el id (conocido en Reval como preapproval_id o ID del mandato). Este ID es la referencia permanente que el servidor usará en todos los cobros futuros de esa suscripción.
7

El servidor guarda el mandato, programa el primer ciclo y redirige

Con el preapproval_id confirmado, el servidor de Reval:
  1. Persiste el mandato en la base de datos, vinculado al customer_id de Shopify y al plan_id
  2. Calcula la fecha del primer cobro según la frecuencia del plan
  3. Crea el primer ciclo con status scheduled
  4. Redirige al suscriptor a la página de agradecimiento de la tienda
A partir de este momento, la suscripción está activa y el job de cobros se encargará de ejecutar cada ciclo en la fecha programada.

Los links firmados son el mecanismo de autenticación del checkout. Garantizan que solo el buy box — y nunca un actor externo — pueda iniciar una suscripción válida.

Estructura del payload firmado

Proceso de validación en el servidor

Usá siempre una función de comparación en tiempo constante (como crypto.timingSafeEqual en Node.js o hmac.compare_digest en Python) para comparar la firma recibida con la calculada. Una comparación byte a byte convencional puede filtrar información sobre la firma válida a través de ataques de timing.

Envío e impuestos en tiempo real

Antes de que el suscriptor confirme la suscripción, el checkout consulta la API de Shopify para calcular el costo de envío y los impuestos aplicables.

Flujo de cálculo

Los valores calculados en el checkout son estimados para mostrar al usuario antes de confirmar. El monto definitivo de cada ciclo se recalcula en vivo en el momento del cobro (no en el momento de la alta). Esto garantiza que si los precios o las tasas impositivas cambian entre ciclos, el cobro siempre refleja los valores vigentes al momento del pago.

¿Por qué recalcular en cada ciclo y no guardar el monto?

Guardar un monto fijo al momento del alta generaría inconsistencias cuando:
  • El merchant actualiza el precio de un producto
  • La alícuota de un impuesto provincial cambia
  • El merchant agrega o elimina zonas de envío
  • El suscriptor actualiza su dirección de envío desde el portal
Al consultar la API de Shopify en cada ciclo, el monto cobrado siempre es correcto sin intervención manual.