Hosted Checkout

Escuchar webhooks

Registra tu endpoint y procesa los eventos de sesión de forma idempotente, con un handler de ejemplo.

Los webhooks son la forma más fiable de recibir actualizaciones en tiempo real del estado de tus sesiones y transacciones de pago. En lugar de consultar la API manualmente, Tonder envía una petición HTTP POST a tu servidor cuando ocurre un evento.

Prerrequisitos

Necesitas una URL pública en tu servidor —por ejemplo https://tu-tienda.com/webhooks/tonder— que pueda recibir peticiones POST. No puede ser una URL de localhost.

Para pruebas locales, servicios como ngrok pueden crear una URL pública que reenvía las peticiones a tu máquina.

Configurar y escuchar webhooks

  1. Inicia sesión en el Dashboard: dashboard-stage.tonder.io (Sandbox) o dashboard.tonder.io (Producción).
  2. Ve a Developers → Webhooks.
  3. Haz clic en Add Endpoint.
  4. Pega la URL pública de tu endpoint en el campo Endpoint URL.
  5. Haz clic en Save.

Tu endpoint debe aceptar peticiones POST con cuerpo JSON. Cuando ocurre un evento, Tonder envía una petición como esta:

{
  "action": "session.completed",
  "type": "checkout.hosted",
  "data": {
    "id": "cs_97_41521_d11ba771527b4056c7f85786cfbb980bc105efaf42af113d",
    "amount_total": 150.00,
    "currency": "MXN",
    "status": "completed",
    "payment_id": 41521,
    "transaction_status": "Success",
    "metadata": { "external_id": "ORD-001" }
  }
}

Tu external_id no viaja como campo propio del payload. Para recibirlo aquí, envíalo también dentro de metadata al crear la sesión; llega en data.metadata.external_id. Ver Referencia.

Para avisarle a Tonder que recibiste el webhook, tu servidor debe responder con un código 200 OK. Si Tonder no recibe un 200 OK, asume que la entrega falló y reintenta. Responde de inmediato, antes de ejecutar cualquier lógica de negocio compleja, para evitar timeouts.

const express = require('express');
const app = express();

app.post('/webhooks/tonder', express.json(), (req, res) => {
  const event = req.body;

  // 1. Confirma la recepción de inmediato
  res.status(200).send();

  // 2. Procesa el evento
  switch (event.action) {
    case 'session.completed':
      const session = event.data;
      console.log(`Pago exitoso para la sesión: ${session.id}`);
      // TODO: actualiza tu base de datos, cumple el pedido, etc.
      break;
    case 'session.expired':
      const expiredSession = event.data;
      console.log(`Sesión expirada: ${expiredSession.id}`);
      // TODO: marca el pedido como cancelado.
      break;
    default:
      console.log(`Evento no manejado: ${event.action}`);
  }
});

app.listen(3000, () => console.log('Escuchando webhooks en el puerto 3000'));

No confíes únicamente en el payload recibido. Antes de cumplir el pedido, vuelve a consultar el estado de la sesión o transacción con la API (por payment_id o metadata.external_id) y responde 200 para confirmar la recepción.

Confirma siempre el resultado del lado del servidor (volviendo a consultar el estado) y procesa los webhooks de forma idempotente para evitar acciones duplicadas ante reintentos.

Siguientes pasos

¿Te resultó útil esta página?

En esta página