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_type | hosted (por defecto) | embedded |
| Dónde paga el cliente | En la página de Tonder | Dentro de tu página |
| Cómo lo sigues | URLs de redirección + webhooks | Eventos 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
| Evento | Cuándo | transaction_status | session_status |
|---|---|---|---|
checkout.initiated | El checkout terminó de cargar | — | pending |
checkout.redirected | El cliente va a un voucher o a una página de pago externa | Pending | pending |
checkout.returned | El cliente regresa de esa página | varía | varía |
checkout.failed | Un intento falló; el cliente puede reintentar (puede repetirse) | Failed, Declined | pending |
checkout.completed | El pago o el guardado de la tarjeta fue exitoso (se envía una sola vez) | Success | completed |
Campos del evento
| Campo | Descripción |
|---|---|
event | Nombre del evento. |
session_type | payment o enrollment. |
payment_id | El pago (no está presente en sesiones de registro de tarjeta). |
direct_transaction_id | Solo en cuentas de API Direct: el intento más reciente (no está presente antes del primer intento). |
external_id | Tu referencia del pedido. |
transaction_status, session_status | Estados actuales. |
payment_method | Mé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
Personalizar el checkout
Plantillas, colores, fuentes, texto del botón e idioma: guardados una vez para tu negocio o definidos por sesión.
Guardar una tarjeta sin cobrar
Crea una sesión de registro de tarjeta para que el cliente guarde primero una tarjeta: para suscripciones o para agregar un método de pago.
