Buenas prácticas y deduplicación
Cómo hacer tu endpoint de webhooks seguro, idempotente y rápido, más las respuestas a las preguntas más frecuentes de los comercios.
Estas son las prácticas esenciales de seguridad e implementación para construir integraciones de webhooks seguras y confiables.
Seguridad
- Usa siempre una URL segura (HTTPS). Las conexiones HTTP no están cifradas y son vulnerables a ataques de intermediario.
- Verifica la firma de cada webhook y rechaza los que no la pasen —ver
Verifica la firma. Un header de autenticación es una capa
adicional, no un reemplazo. Sin Webhooks 2.0, los webhooks no vienen firmados: usa un método de
autenticación (
BEARER,API_TOKENoBASIC_AUTH). - Compara el evento con tus registros antes de entregar. El monto, la moneda y la referencia deben coincidir con el pedido. Una firma válida prueba que el webhook viene de Tonder, no que el pago cubra el pedido.
- Valida la estructura y el contenido del evento antes de procesarlo: revisa que los campos obligatorios estén presentes y tengan el tipo esperado.
- Guarda los secretos en tu servidor. El secreto de firma y tu llave de API van en variables de entorno o en un gestor de secretos —nunca en código del frontend o de una app móvil, en tu repositorio ni en tus logs. Tu llave de API también administra endpoints con la API de webhooks: quien la tenga puede agregar un endpoint y recibir tus eventos. Rota cualquier secreto que sospeches expuesto.
- Pon las credenciales en un header, no en la URL. La URL del endpoint se muestra en la lista de endpoints; envía los tokens con un método de autenticación, no como parámetro de la URL.
- Responde con un estado breve. Los primeros 2 KB de la respuesta de tu servidor aparecen en el registro de eventos; no devuelvas stack traces, tokens ni detalles internos.
- Si tu firewall filtra por IP, pide a tu contacto de Tonder la IP de salida de los webhooks. Una lista de IPs permitidas complementa la firma; no la reemplaza.
Implementación
- Responde
2xxrápido y procesa después, en una cola propia. Tienes 10 segundos (30 sin Webhooks 2.0). - Deduplica con
webhook-id. Un mismo evento puede llegar más de una vez —un reintento o un reenvío manual trae el mismowebhook-id. Sin Webhooks 2.0, deduplica conid+event_type. Correlaciona conmetadata.external_id, que se repite en cada evento de la misma transacción. Guarda loswebhook-idprocesados durante al menos 60 días, el tiempo en que un evento todavía se puede reenviar —una restricción de unicidad en tu base de datos lo resuelve. - No dependas del orden de llegada. Un
payment_Pendingpuede llegar después de unpayment_Successsi se reintentó. Usa elstatusy la fechacreateddel payload. - Suscribe cada endpoint solo a los eventos que usa, y separa sistemas distintos en endpoints distintos.
- Responde
2xxa los eventos que no manejas, comoendpoint.test, y no hagas nada más con ellos. - Registra lo necesario para rastrear un evento —
webhook-id,event_type,status, tu referencia del pedido, el resultado y cualquier error, con marcas de tiempo— y enmascara lo demás. Los payloads pueden traer datos personales y bancarios (un pago SPEI incluye el nombre y la CLABE de quien envía). Nunca registres tu header de autenticación ni el secreto de firma. - Maneja los errores con cuidado. Envuelve el procesamiento en bloques try-catch para que un webhook fallido no tumbe toda tu aplicación.
Checklist de deduplicación
- Con Webhooks 2.0, deduplica con el header
webhook-id— un reintento o un reenvío trae el mismo. Sin Webhooks 2.0, deduplica conid+event_type. Correlaciona conmetadata.external_id, que se repite en cada evento de una transacción y funciona en los formatos Short + Long. - Guarda los
webhook-idprocesados durante al menos 60 días —un evento se puede reenviar mientras se conserva. - Mantén un índice
idempotency_keyen tu base de datos. - En modo Híbrido, trata el par Pending + Success como intencional.
- Verifica siempre el estado final con
GET /api/v1/transactions/{id}/. - Maneja los cinco estados terminales de retiros —
Success,Declined,Cancelled,FailedyReturned;Returnedllega después deSuccess.
Preguntas frecuentes
No veo la pestaña Eventos. Webhooks 2.0 se habilita por cuenta: pídelo a tu contacto de Tonder. Mientras tanto tu endpoint recibe todos los eventos, sin selección por tipo.
Mi servidor estuvo caído unas horas, ¿perdí eventos? No, si volvió antes de que terminaran los 6 intentos (unas 8,5 horas). Si alguno quedó Fallido, búscalo en el registro de eventos y usa Reenviar evento o Reintentar todos.
Desmarqué un evento y me sigue llegando. El cambio aplica a los eventos nuevos; los que ya estaban en reintento continúan.
¿Por qué recibí endpoint.test si no lo marqué? Llega solo cuando alguien usa Enviar
prueba, sin importar la suscripción del endpoint.
El contador dice 7/6. Los reenvíos manuales se suman al total de intentos, pero no a los 6
automáticos.
¿Cuánto tiempo se guardan los eventos? 60 días.
¿Puedo elegir el formato (Short o Long) por endpoint? No: lo define tu integración con Tonder.
Siguientes pasos
API de webhooks
Administra endpoints y entregas por código —las mismas operaciones de Desarrolladores › Webhooks y Eventos, con tu llave de API.
Validación de cuentas
Sabe de quién es una CLABE — nombre y RFC, directo del banco — antes de que se mueva el dinero. Una llamada para iniciar, otra para leer la respuesta.
