Saltar al contenido principal
Los webhooks salientes avisan a tus sistemas (ERP, Make, n8n, Zapier o tu propio servidor) de lo que pasa en Hurry sin que tengas que consultar nada. Das de alta una URL, eliges qué eventos quieres y Hurry le hace un POST con el JSON completo del pedido, el pago, el cliente, la tienda y la pasarela cada vez que ocurre algo. Se gestionan desde el CRM, en Cuenta → Webhooks. Solo la cuenta principal puede verlos y configurarlos: los colaboradores no tienen acceso a esta sección.

Cómo funciona

1

Crea un endpoint

Pulsa Nuevo endpoint, ponle un nombre, escribe la URL https de tu receptor y marca los eventos que quieres recibir. Si lo necesitas, acota el endpoint a unas tiendas concretas y añade cabeceras propias.
2

Guarda el secreto

Al crearlo, Hurry te muestra un secreto con el formato whsec_.... Guárdalo en tu receptor: es lo que usarás para verificar la firma de cada envío. Puedes volver a verlo o rotarlo desde la tarjeta del endpoint.
3

Verifica la firma y responde 2xx

En cada entrega, comprueba la cabecera X-Hurry-Signature sobre el cuerpo crudo y responde un código 2xx en menos de 10 segundos. Si no respondes 2xx, Hurry reintenta solo.
4

Pruébalo

Pulsa Probar en el endpoint. Hurry manda un evento ping firmado y te enseña el código HTTP y la respuesta de tu servidor.

Eventos

Cada endpoint se suscribe a los eventos que quieras. El código del evento viaja en el campo type del JSON y en la cabecera X-Hurry-Event.
Una venta de checkout dispara order.paid y payment.succeeded a la vez. Si solo quieres ventas, suscríbete a order.paid. Si además quieres los cobros recurrentes de las suscripciones, usa payment.succeeded.

Alcance por tienda

Un endpoint puede recibir los eventos de todas las tiendas (incluidos los cobros recurrentes, que no tienen tienda) o solo de algunas. Si eliges tiendas concretas, los cobros sin tienda no se envían a ese endpoint.

Cabeceras personalizadas

Puedes añadir hasta 5 cabeceras propias por endpoint, por ejemplo Authorization: Bearer ... si tu receptor exige un token. Los nombres admiten letras, números y guiones. No se pueden definir las cabeceras que fija Hurry: Host, Content-Type, Content-Length, Transfer-Encoding, User-Agent ni ninguna que empiece por X-Hurry-.

Formato del evento

Todos los eventos comparten el mismo sobre. Lo que cambia es el contenido de data.
string
Identificador del evento (evt_ + 24 caracteres). Es el mismo en todos los endpoints, en todos los reintentos y en los reenvíos manuales del mismo hecho. Úsalo para ignorar duplicados.
string
Código del evento: order.paid, payment.failed, refund.created…
string
Versión del formato del JSON. Actualmente 2026-11-01. Cada endpoint queda fijado a la versión con la que se creó.
string
Fecha de creación del evento en ISO 8601 con zona horaria.
string
Identificador de tu cuenta en Hurry.
object
id y name del endpoint que recibe el evento.
object
Todo lo que se sabe del hecho. Qué nodos vienen rellenos depende del evento; los que no aplican llegan como null.
Importes y fechas. Todos los importes son enteros en la unidad menor de la moneda (céntimos: 4980 son 49,80 EUR), con la moneda al lado y una versión legible en los campos *Formatted. Las fechas van en ISO 8601 con desplazamiento horario.

Qué lleva data en cada evento

string
Identificador del pedido en Hurry.
string
Referencia externa del carrito o de la plataforma de origen.
integer | null
Número de pedido secuencial, si ya se ha asignado.
string
Nombre legible del pedido, por ejemplo #1001.
string
Estado del pedido en el CRM: PENDING, IN_PROGRESS, REQUIRES_ACTION, PAID, PARTIALLY_REFUNDED, REFUNDED o CANCELED. Lee la nota de abajo antes de usarlo para saber si está cobrado.
boolean
true si el pedido está cobrado. Derivado del pago, vale para todas las pasarelas.
string | null
Momento del cobro.
string | null
Estado del pago asociado: CREATED, REQUIRES_ACTION, PROCESSING, SUCCEEDED, CANCELED o FAILED.
string
Moneda de cobro (ISO 4217).
object
Importes de cobro en unidad menor: currency, subtotal, tax, shipping, discount, upsells, total y totalFormatted.
object
Los mismos importes en la moneda que vio el comprador en el checkout, más fxRate cuando hubo conversión.
string | null
Código de descuento aplicado.
string | null
Nombre de la opción de envío elegida.
array
Líneas del pedido. Cada una con id, productId, sku, name, imageUrl, quantity, unitAmount, taxAmount y totalAmount.
object
Seguimiento: shipped, shippedAt, trackingNumber y trackingUrl.
string | null
URL del checkout de Hurry para este pedido.
string | null
Página de la tienda desde la que se inició la compra.
string
Enlace directo al pedido en el CRM de Hurry.
string
Fechas de creación y última modificación.
order.status es el estado del pedido en el CRM y solo las tiendas Shopify lo pasan a PAID; en el resto de pasarelas se queda en IN_PROGRESS aunque el cobro esté hecho. Para saber si un pedido está cobrado usa order.paid, order.paidAt y order.paymentStatus, que salen del pago.
string
Identificador del pago en Hurry.
string
CREATED, REQUIRES_ACTION, PROCESSING, SUCCEEDED, CANCELED o FAILED.
integer / string / string
Importe cobrado en unidad menor, su moneda y la versión legible.
integer | null
Importe convertido a USD en unidad menor, si está disponible.
string
Pasarela que procesó el cobro: STRIPE, STRIPE_EVERVAULT, WHOP, ONE, SUMUP, SQUARE, MAMO, AIRWALLEX, SHOPIFY, MOR, SLASH, NEXI, NEXI_ALIAS, REDSYS o REVOLUT.
string | null
Identificador del cobro en la pasarela (por ejemplo el pi_... de Stripe).
boolean
true si es un cobro recurrente sin pedido (rebill).
string | null
Lote de cobros recurrentes al que pertenece, si aplica.
string | null
Contacto del comprador. Se prefiere el del cliente al que dio la pasarela.
object
type, brand, last4, expMonth, expYear, country y funding. Nunca viaja el número completo de la tarjeta.
object | null
code y message del rechazo cuando el cobro falla.
array
Reembolsos del pago, con el mismo formato que data.refund.
integer
Suma de los reembolsos correctos o pendientes, en unidad menor.
string
Fechas de creación y última modificación.
id, email, name, phone, address (line1, line2, city, state, postalCode, country) y createdAt. No incluye ningún dato de tarjeta.
shop: id, name, url, slug, customDomain, type (EXTERNAL o NATIVE) y platform (SHOPIFY, WORDPRESS o API).gateway: id, name y psp de la credencial de pago con la que se cobró.
id, providerRefundId, amount, currency, amountFormatted, status (PENDING, SUCCEEDED, FAILED o CANCELED), reason, failureReason, createdAt y updatedAt.
string
Identificadores en Hurry y en la pasarela.
string
Pasarela donde se abrió.
string
CHARGEBACK, INQUIRY o EARLY_FRAUD_WARNING.
string
NEEDS_RESPONSE, UNDER_REVIEW, WON, LOST, CHARGE_REFUNDED o CLOSED.
string | null
Estado anterior, útil en dispute.closed para saber de dónde viene.
string | null
Estado y motivo tal como los reporta la pasarela y la red de tarjetas.
integer / string / string
Importe en disputa.
string | null
Email del comprador y cargo afectado en la pasarela.
string | null
Fechas de apertura, límite para aportar pruebas y cierre.
boolean
Si la pasarela ya ha retirado los fondos.
string
Enlace a la sección de riesgo del CRM.
message con un texto fijo y endpoint con id, name, url y la lista events a la que está suscrito. Sirve para comprobar que tu receptor está accesible y que verificas bien la firma.

Ejemplo completo: order.paid

Cabeceras HTTP

Cada entrega es un POST con Content-Type: application/json y User-Agent: Hurry-Webhooks/1.0. Además lleva estas cabeceras: A estas se suman las cabeceras personalizadas que hayas definido en el endpoint.

Verificar la firma

Cada envío va firmado con HMAC-SHA256 usando el secreto del endpoint. Verifica la firma antes de confiar en el contenido:
  1. Lee el cuerpo crudo de la petición, tal como llega, antes de parsear el JSON.
  2. Saca t y v1 de la cabecera X-Hurry-Signature.
  3. Rechaza la petición si t difiere más de 300 segundos de tu hora actual. Así una entrega capturada no se puede reproducir más tarde.
  4. Calcula HMAC-SHA256(secreto, t + "." + cuerpo) y pásalo a hexadecimal en minúsculas.
  5. Compara el resultado con v1 en tiempo constante.
Verifica siempre sobre el cuerpo crudo. Si tu framework parsea el JSON y lo vuelve a serializar, el orden de las claves o los espacios pueden cambiar y la firma dejará de coincidir.

Responder, reintentos y duplicados

Responde 2xx en menos de 10 segundos y procesa el evento después, en segundo plano. Cualquier otra respuesta, un timeout o un fallo de red cuentan como entrega fallida. Hurry no sigue redirecciones: una respuesta 3xx también cuenta como fallo. Si una entrega falla, Hurry la reintenta con esperas crecientes: el primer intento más 6 reintentos, repartidos a lo largo de unas 9 horas. Cuando se agotan los intentos, la entrega queda como Fallida y puedes reenviarla a mano desde Entregas. Las entregas de prueba (ping) y los reenvíos manuales se intentan una sola vez.
Un mismo evento puede llegar más de una vez. Si tu servidor procesa la petición pero la respuesta se pierde, Hurry la reintentará. Guarda el campo id (o la cabecera X-Hurry-Event-Id) de cada evento procesado e ignora los repetidos.

Apagado automático

Para no castigar a un receptor caído, Hurry apaga el endpoint en dos casos:
  • 10 fallos definitivos seguidos: el endpoint pasa a Apagado por fallos y te avisamos con una notificación en la campana del CRM. Un éxito en cualquier momento reinicia la racha.
  • Respuesta 410 Gone: tu servidor dice que la URL ya no existe y el endpoint se apaga al momento.
Al apagarse, las entregas que estaban pendientes se marcan como fallidas y no se encola nada nuevo. Cuando arregles el receptor, vuelve a activarlo con el interruptor de la tarjeta y reenvía desde Entregas lo que te interese recuperar.

Entregas

En Entregas ves el historial de todo lo que Hurry ha enviado o intentado enviar, lo último primero, con filtros por endpoint y por estado. Al pulsar Ver se abre el detalle con el JSON exacto que se envió, el código HTTP, los primeros bytes de la respuesta de tu servidor, la duración y el error si lo hubo. Reenviar vuelve a mandar el mismo JSON con el mismo id de evento como una entrega nueva. El historial se conserva 30 días.

Secreto y seguridad

  • Secreto por endpoint. Cada endpoint tiene su propio secreto whsec_..., cifrado en la base de datos. En la lista solo se enseña una pista con los últimos 4 caracteres. Puedes verlo o rotarlo cuando quieras.
  • Rotación inmediata. Al rotar, el secreto anterior deja de valer al momento: actualiza tu receptor con el nuevo antes de rotarlo si no quieres perder entregas.
  • Solo HTTPS y hosts públicos. La URL tiene que ser https://, apuntar a un dominio público de Internet y no llevar usuario ni contraseña. Hurry rechaza localhost, nombres internos, direcciones privadas o de loopback y la propia plataforma de Hurry, y vuelve a comprobarlo antes de cada envío.
  • Sin datos de tarjeta. El JSON nunca incluye el número completo de la tarjeta ni el CVC: solo marca, últimos 4 dígitos, caducidad, país y tipo.
  • Solo la cuenta principal. Los colaboradores no ven la sección, y no se puede modificar mientras se está suplantando a otro usuario.

Límites

Integración con Make, Zapier y n8n

Crea un módulo o nodo de tipo Webhook en la herramienta, copia la URL que te da y pégala como URL del endpoint en Hurry. Elige los eventos y pulsa Probar para que la herramienta reciba un ping con el que mapear los campos. Si la herramienta no te deja verificar la firma, añade al menos una cabecera personalizada con un token que solo conozcáis tú y la herramienta, y compruébala en el primer paso del flujo.

Gestión desde el MCP de Hurry

Si usas el conector MCP de Hurry con un asistente de IA, los webhooks también se pueden gestionar por conversación con estas herramientas. El secreto nunca se devuelve por el MCP; para verlo o rotarlo hay que usar la pantalla.

Preguntas frecuentes

Pulsa Probar en el endpoint: verás el código HTTP que devuelve tu servidor y su respuesta. Comprueba que la URL es https, pública y que respondes 2xx. Si Hurry lo apagó por fallos, vuelve a activarlo con el interruptor.
Hurry reintenta hasta 6 veces durante unas 9 horas. Si todos los intentos fallan, la entrega queda como fallida y puedes reenviarla desde Entregas. Diez fallos definitivos seguidos apagan el endpoint y te avisamos en la campana.
Sí: crea un webhook en esa herramienta, pega su URL en Hurry y elige los eventos. Si no puedes verificar la firma, usa al menos una cabecera personalizada con un token que solo conozcáis tú y la herramienta.
Pedido completo (estado, líneas, importes, descuentos, envío y seguimiento), pago (estado, importe, pasarela, método con marca y últimos 4), cliente (email, nombre, teléfono, dirección), tienda y pasarela. Nunca datos completos de tarjeta.
order.status es el estado del pedido en el CRM y solo las tiendas Shopify lo pasan a PAID. En el resto de pasarelas la verdad del cobro está en el pago. Usa order.paid, order.paidAt y order.paymentStatus, que valen para todas.
Una venta de checkout dispara order.paid y payment.succeeded a la vez, con el mismo contenido en data. Suscríbete solo a uno de los dos salvo que también quieras los cobros recurrentes, que solo llegan como payment.succeeded.
Pulsa Rotar secreto: el anterior deja de valer al momento. Actualiza tu receptor con el nuevo.
Sí, con el interruptor de la tarjeta. En pausa no se encola ningún evento nuevo; los reintentos que ya estaban en cola se siguen intentando con su calendario normal. Al reactivarlo, los eventos nuevos vuelven a enviarse.