Hosted Checkout

Embeber el checkout

Carga el checkout en un iframe en tu página y sigue el pago con eventos postMessage.

Cada sesión tiene una url de checkout. Puedes redirigir al cliente a ella, o embeberla en un iframe en tu propia página y recibir eventos conforme el cliente avanza en el pago.

Alojado (redirección)Embebido (iframe)
checkout_typehosted (por defecto)embedded
Dónde paga el clienteEn la página de TonderDentro de tu página
Cómo lo siguesURLs de redirección + webhooksEventos postMessage + webhooks

El dominio de tu sitio debe estar habilitado para embeber en cada entorno. Pide a soporte de Tonder que lo agregue antes de probar.

Paso a paso

Crea la sesión con checkout_type: "embedded" y post_message_enabled: true. Agrega redirect_on_completion: "never" si quieres que tu página, y no el checkout, decida a dónde va el cliente al final.

{
  "customer": { "first_name": "Ana", "last_name": "Garcia", "email": "ana@example.com" },
  "amount_total": 100.00,
  "currency": "MXN",
  "line_items": [{ "name": "Deposit", "quantity": 1, "unit_price": 100.00 }],
  "payment_method_types": ["card", "spei"],
  "external_id": "ORD-001",
  "return_url": "https://your-store.com/checkout/complete",
  "checkout_type": "embedded",
  "post_message_enabled": true,
  "redirect_on_completion": "never"
}

Acepta mensajes únicamente del origen del checkout de tu entorno: https://stage-payflow.tonder.io (Sandbox) o https://payflow.tonder.io (Producción).

Usa la url de la respuesta de la sesión como el src del iframe.

Los eventos le dicen a tu página qué mostrar. Confirma el pago en sí desde tu backend, con webhooks o Consultar una sesión.

Eventos

EventoCuándotransaction_statussession_status
checkout.initiatedEl checkout terminó de cargar—pending
checkout.redirectedEl cliente va a un voucher o a una página de pago externaPendingpending
checkout.returnedEl cliente regresa de esa páginavaríavaría
checkout.failedUn intento falló; el cliente puede reintentar (puede repetirse)Failed, Declinedpending
checkout.completedEl pago o el guardado de la tarjeta fue exitoso (se envía una sola vez)Successcompleted

Campos del evento

CampoDescripción
eventNombre del evento.
session_typepayment o enrollment.
payment_idEl pago (no está presente en sesiones de registro de tarjeta).
direct_transaction_idSolo en cuentas de API Direct: el intento más reciente (no está presente antes del primer intento).
external_idTu referencia del pedido.
transaction_status, session_statusEstados actuales.
payment_methodMétodo usado, p. ej. card, oxxopay.
{
  "event": "checkout.completed",
  "session_type": "payment",
  "payment_id": 41528,
  "external_id": "ORD-001",
  "transaction_status": "Success",
  "session_status": "completed",
  "payment_method": "card"
}

Página de ejemplo

<!DOCTYPE html>
<html>
<body>
  <div id="status"></div>
  <script>
    window.addEventListener('message', function (event) {
      const allowedOrigins = ['https://payflow.tonder.io', 'https://stage-payflow.tonder.io'];
      if (!allowedOrigins.includes(event.origin)) return;
      const data = event.data;
      switch (data.event) {
        case 'checkout.initiated':
          document.getElementById('status').textContent = 'Listo para pagar';
          break;
        case 'checkout.completed':
          window.location.href = data.session_type === 'enrollment'
            ? '/card-saved'
            : '/success?payment=' + data.payment_id;
          break;
        case 'checkout.failed':
          document.getElementById('status').textContent =
            'El pago falló: ' + data.transaction_status + '. Inténtalo de nuevo.';
          break;
        case 'checkout.redirected':
          document.getElementById('status').textContent =
            'Redirigiendo a ' + data.payment_method + '...';
          break;
        case 'checkout.returned':
          if (data.transaction_status === 'Success') {
            window.location.href = '/success?payment=' + data.payment_id;
          }
          break;
      }
    });
  </script>
  <iframe id="checkout-iframe" src="SESSION_URL" style="width: 100%; height: 600px; border: none;"></iframe>
</body>
</html>

Nunca entregues un pedido basándote solo en un evento del navegador. Un mensaje en la página puede falsificarse; el webhook o una consulta de la sesión desde tu servidor es la fuente de verdad.

Siguientes pasos

¿Te resultó útil esta página?

En esta página