SPEI Frictionless
SPEI sin salir de tu checkout: el cliente paga con una CLABE dedicada y tú lo concilias solo.
Frictionless SPEI procesa automáticamente transferencias bancarias incluso cuando no coinciden con una transacción pendiente existente. Habilita dos escenarios clave:
- Montos no coincidentes: el cliente deposita un monto distinto al esperado.
- Transferencias directas: el cliente transfiere sin iniciar un checkout.
Esta función se basa en los pagos SPEI estándar. Si aún no integras SPEI, empieza por SPEI. Es la opción recomendada para comercios nuevos de SPEI (MX) y está disponible con API Direct o Híbrido.
CLABE + identificador
Cada depósito SPEI usa dos capas de identificación:
- CLABE (gestionada por Tonder): una cuenta única de 18 dígitos asignada por Tonder para cada comercio + cliente. Es el identificador principal del depósito, usado para búsquedas y matching.
- Campos de identificador (que tú provees):
external_id(tu referencia interna) yadditional_external_id(segundo identificador opcional). Habilitan tu lógica de conciliación.
Caso 1: depósitos con monto no coincidente
El cliente inicia checkout pero deposita un monto distinto. Ejemplo: crea un checkout por 100 MXN pero deposita 600 MXN. El sistema empareja por CLABE y procesa automáticamente.
{
"data": {
"amount": 600.0,
"metadata": {
"external_id": "ORD-001",
"mismatched_deposit": "True",
"original_expected_amount": "100"
}
}
}Caso 2: transferencias directas (sin checkout)
El cliente transfiere directamente a su CLABE sin iniciar un checkout. Ejemplo: usa la CLABE guardada de un depósito previo y transfiere 700 MXN desde su app bancaria. El sistema encuentra la última transacción exitosa de esa CLABE, extrae el identificador y crea un nuevo depósito.
{
"data": {
"amount": 700.0,
"metadata": {
"external_id": "CUSTOMER-12345",
"concept": "Frictionless deposit - auto-created"
}
}
}Estrategia recomendada: identificador único
Usa el mismo identificador para ambos casos —el enfoque más simple. Por ejemplo, una plataforma de
gaming que usa player_id:
{
"metadata": {
"external_id": "PLAYER-12345"
}
}Procesa el webhook acreditando siempre la misma cuenta del cliente, y maneja los montos no
coincidentes cuando metadata.mismatched_deposit sea "True":
const playerId = webhook.data.metadata.external_id;
await creditPlayer(playerId, webhook.data.amount);
if (webhook.data.metadata.mismatched_deposit === "True") {
await notifyPlayer(playerId, "amount_mismatch");
}Configuración avanzada (identificadores duales)
Para comercios que necesitan identificadores distintos por caso de uso —por ejemplo, tracking a nivel de orden para checkouts (Caso 1) y tracking a nivel de cliente para transferencias directas (Caso 2):
{
"amount": 500,
"currency": "MXN",
"payment_method": "spei",
"metadata": {
"external_id": "ORDER-12345",
"additional_external_id": "PLAYER-98765"
}
}Webhook Caso 1 (existe transacción pendiente):
{
"metadata": {
"external_id": "ORDER-12345",
"additional_external_id": "PLAYER-98765",
"mismatched_deposit": "True"
}
}const orderId = webhook.data.metadata.external_id;
await completeOrder(orderId, webhook.data.amount);Webhook Caso 2 (no existe transacción pendiente; external_id no se incluye porque no hay orden):
{
"metadata": {
"additional_external_id": "PLAYER-98765"
}
}const playerId = webhook.data.metadata.additional_external_id;
await manualTopUp(playerId, webhook.data.amount);| Estrategia | Caso 1 regresa | Caso 2 regresa | Complejidad | Ideal para |
|---|---|---|---|---|
| Identificador único | player_id | player_id (histórico) | Simple | Plataformas centradas en cliente |
| Identificadores duales | order_id | player_id (histórico) | Avanzada | Tracking de orden + cliente |
Alias de campos personalizados
En lugar de usar siempre external_id / additional_external_id, puedes pedir a Tonder que use
nombres de campo específicos de tu dominio (por ejemplo order_id / player_id):
{
"field_aliases": {
"order_id": "external_id",
"player_id": "additional_external_id"
}
}Con esa configuración, tu petición y el webhook usan tus propios nombres de campo:
{
"metadata": {
"order_id": "ORDER-12345",
"player_id": "PLAYER-98765"
}
}Los identificadores duales y los alias de campos personalizados se acuerdan y configuran junto con tu gerente de integración de Tonder. Empieza con identificador único; agrega identificadores duales solo si necesitas tracking distinto por caso de uso, y alias solo si quieres nombres de campo específicos de tu dominio.
Consultar el status de un depósito (Polling)
Los webhooks son la forma recomendada de recibir actualizaciones de depósitos SPEI Frictionless, pero también puedes consultar el status directamente con los endpoints específicos de depósitos. Es útil para conciliación o cuando la entrega de un webhook se retrasa.
GET https://02ljs5zoif.execute-api.us-east-1.amazonaws.com/stage/api/v1/deposits/{id}/transactionGET https://38dictnz7c.execute-api.us-east-1.amazonaws.com/pdn/api/v1/deposits/{transaction_id}/transactionEstos endpoints son específicos de depósitos SPEI Frictionless y son distintos del
Get Transaction Status general. Usa
{transaction_id} / {id} como el identificador de transacción del depósito.
Simulador (Sandbox)
En sandbox puedes simular un depósito SPEI Frictionless —incluyendo montos no coincidentes y transferencias directas— desde el simulador:
https://tonder.live/simulatedeposits/
El simulador solo está disponible en Sandbox. Úsalo para probar el matching por CLABE y tu lógica de conciliación antes de pasar a producción.
