Diagrama del ciclo de cobro recurrente
Webhook de pago de MP
Endpoint receptor
x-signature.
Verificación de firma
MP incluye dos headers en cada webhook:
El proceso de verificación:
Estructura del payload del webhook
MP envía un payload minimalista — contiene el tipo de evento y el ID del objeto, pero no el detalle completo del pago:MP envía el ID del pago (
data.id), no el payload completo. El servidor de Reval debe hacer un GET /v1/payments/{id} a la API de MP para obtener el detalle completo: monto, status, método de pago, external_reference (que vincula el pago con el ciclo de Reval), y demás campos necesarios para crear el pedido. Esto es intencional por parte de MP para reducir el tamaño del payload y forzar una consulta autenticada.Detalle completo del pago (GET a MP)
Después de verificar la firma, el servidor hace el GET para obtener:external_reference contiene el ID del ciclo de Reval, que el servidor usó al ejecutar el cobro. Esto vincula unívocamente el pago con la suscripción y el ciclo correspondiente.
Garantía de idempotencia
MP puede enviar el mismo webhook más de una vez (reintentos por timeout, fallos de red). La idempotencia garantiza que, sin importar cuántas veces llegue el webhook de un pago aprobado, solo se crea un único pedido en Shopify.Mecanismo de deduplicación
reval.mp_payment_id actúa como clave de deduplicación durable. Al estar en Shopify (la fuente de verdad), persiste incluso si la base de datos de Reval se reconstruye.
Creación de pedido en Shopify
Cuando el pago es aprobado y el check de idempotencia confirma que no existe un pedido previo, el servidor crea un pedido estándar en Shopify via la Admin API.Estructura del pedido creado
Por qué cada cobro genera un pedido separado
Cada ciclo de suscripción genera su propio pedido en Shopify por las siguientes razones:- Fulfillment: cada envío mensual es una entrega distinta que necesita su propio tracking
- Inventario: Shopify descuenta el stock al crear el pedido; sin pedido separado, el inventario no se actualiza
- Analítica: los reportes de ventas de Shopify (y apps conectadas como Google Analytics) necesitan un evento de compra por cada cobro real
- Contabilidad: cada pedido genera su propia línea en los exports de ventas y en las integraciones con ERPs o facturación electrónica
- Soporte: el equipo de atención al cliente puede ver el historial completo de envíos del suscriptor en la timeline del cliente en Shopify
Job de reintentos
El job de reintentos es un proceso que se ejecuta diariamente y recupera los ciclos que fallaron por rechazo de la tarjeta o error temporal de MP.Frecuencia y criterios de ejecución
Flujo del job
Comportamiento tras múltiples fallos consecutivos
- Pausa automática
- Notificación al merchant
Cuando una suscripción supera el máximo de intentos fallidos consecutivos:
- La suscripción pasa a
status: pauseden la DB de Reval - No se programan nuevos ciclos hasta que el suscriptor reactive
- Se envía un email automático al suscriptor con un link firmado al portal
- Desde el portal, el suscriptor puede actualizar su método de pago y reactivar la suscripción
- Al reactivar, se programa el próximo ciclo desde la fecha actual (no se cobran los períodos pausados)
Códigos de rechazo comunes de MP y su tratamiento
Códigos de rechazo comunes de MP y su tratamiento
Los códigos de rechazo están disponibles en el detalle del pago bajo
status_detail en la respuesta de GET /v1/payments/{id}.