Skip to main content
Cada entrega de webhook lleva un cuerpo JSON con la misma estructura de envoltura, sin importar el tipo de evento. Esta página explica cada campo y los dos más importantes de manejar correctamente en tu integración: sequence y applicationId.

La envoltura

El cuerpo es idéntico byte por byte a través de cada entrega y reenvío del mismo evento. Todo lo que varía por intento de entrega — el ID de entrega, el contador de intentos, la marca de tiempo, la firma — vive en su lugar en los encabezados HTTP.

Eventos, entregas e intentos

Tres registros distintos están detrás de cada webhook que te llega, y cada uno lleva su propio identificador y sus propias marcas de tiempo. Mantenerlos claros es la clave para reconciliar las distintas marcas de tiempo y la lógica de sequence que se explica a continuación. La división sigue una sola regla: todo lo intrínseco al eventoid, type, sequence, originalCreateDate, data — vive en el cuerpo y nunca cambia; todo lo que describe esta solicitud HTTP en particular — ID de entrega, número de intento, tipo de intento, marca de tiempo, firma — vive en los encabezados y se regenera en cada intento.
Al ordenar el estado de negocio, confía en el evento, nunca en el intento. Un reenvío de un evento antiguo llega con un Sphere-Timestamp nuevo (por lo que pasa las verificaciones de tolerancia de firma), pero su sequence y originalCreateDate siguen reflejando cuándo ocurrió realmente el cambio de estado. Ordenar por Sphere-Timestamp haría que un evento antiguo reenviado pareciera más nuevo que los eventos que lo superaron — ordenar por sequence mantiene los reenvíos inofensivos.

Los payloads llevan el cambio de estado, no el recurso completo

Los payloads de webhook contienen deliberadamente lo mínimo que necesitas para reaccionar: el ID del recurso y la transición de previousStatus a status. No contienen el objeto del recurso completo. La mayoría de las reacciones — enrutar según el nuevo estado, actualizar la fila en tu propia base de datos, notificar a tu equipo de operaciones — funcionan solo con el payload. Cuando necesites el recurso completo (criterios de verificación completos, detalles de cuenta bancaria, montos de transferencia), recupéralo del endpoint GET del recurso:
Debido a que el payload es mínimo e inmutable, un evento reenviado nunca lleva datos obsoletos que pretendan ser recientes — describe una transición que ocurrió en originalCreateDate. Si siempre haces un GET del recurso para obtener su estado actual antes de actuar sobre los efectos secundarios, los reenvíos son inofensivos.

El campo sequence

sequence es un entero monotónicamente creciente delimitado a una única instancia de recurso — un contador por cliente, uno por transferencia, y así sucesivamente, identificado por data.id. Se asigna cuando se crea el evento y nunca cambia, por lo que refleja el orden real en que ocurrieron los cambios de estado incluso cuando las entregas llegan fuera de orden. Debido a que el orden de entrega no está garantizado, usa sequence para protegerte contra actualizaciones obsoletas:
  1. Almacena el sequence más alto que hayas procesado por instancia de recurso — por ejemplo, una columna lastSphereSequence en la fila del cliente en tu propia base de datos.
  2. Cuando llegue un evento, compara su sequence con el valor almacenado para ese data.id.
  3. Si incoming.sequence <= stored.sequence, el evento es obsoleto o un duplicado — confirma con un 2xx y omite la actualización.
  4. De lo contrario, aplica la actualización y almacena el nuevo sequence.
No necesitas un contador global en toda tu cuenta — solo seguimiento por entidad, ubicado junto al estado del recurso que ya mantienes.
No asumas que los valores de sequence que recibes son contiguos. Si tu endpoint se suscribe a un subconjunto de los eventos de un recurso, observarás brechas — usa la comparación de obsolescencia <= de arriba, nunca detección de brechas.

¿Por qué tanto sequence como originalCreateDate?

Responden preguntas diferentes. originalCreateDate te dice cuándo ocurrió un cambio de estado — tiempo de reloj, útil para visualización, registros de auditoría y consultas por ventana de tiempo. Pero el tiempo de reloj es una clave de ordenamiento poco confiable: dos transiciones rápidas en el mismo recurso pueden caer tan cerca una de otra que sus marcas de tiempo colisionan, y una comparación de marcas de tiempo no tiene forma de romper el empate. sequence existe para hacer que el ordenamiento sea inequívoco — un entero estrictamente creciente por instancia de recurso, de modo que dos eventos cualesquiera del mismo recurso siempre tienen un orden definido, sin importar qué tan cerca ocurrieron. Regla general: ordena y deduplica por sequence; visualiza y audita por originalCreateDate.

El campo applicationId

Cada payload incluye data.applicationId — la aplicación de SpherePay a la que pertenece el evento. Los endpoints de webhook se registran por aplicación, y los eventos solo se entregan para recursos que pertenecen a la aplicación del endpoint. Esto importa sobre todo cuando operas múltiples aplicaciones de SpherePay que comparten una misma URL receptora de webhooks. Registrar la misma URL bajo dos aplicaciones es perfectamente válido — pero tu handler entonces recibe eventos de ambas, y el endpoint de cada aplicación tiene su propio secreto de firma. Usa applicationId para enrutar cada evento al contexto de aplicación correcto en tu sistema (y para seleccionar el secreto correcto al verificar firmas).
Puedes encontrar el ID de cada aplicación en la página de Settings del dashboard de integradores de SpherePay.
Última modificación el 11 de agosto de 2026