Webhooks

Cuando la app está en modo HIOBuy warehouse fulfillment, HIOBuy envía eventos del ciclo de vida de fulfillment a tu endpoint HTTPS. Configúralos en Developer Portal → Webhooks . La entrega es asíncrona; las respuestas de la Public API no esperan a tu servidor webhook.

Requisito: Autorización de canal → modo de fulfillment = HIOBuy warehouse. En modo self solo ves la intro; no puedes crear/activar endpoints.

Resumen {#overview}

ElementoValor
TransportePOST JSON a tu endpoint
Tiempo de espera10 segundos
ÉxitoHTTP 2xx
Secreto de firmawhsec_… (se muestra una sola vez al crear / rotar)
Cabecera de firmaHioBuy-Signature
Cabecera de ID de eventoHioBuy-Event-Id
User-AgentHioBuy-Webhooks/1.0
Reintentoshasta 5 intentos: inmediato, luego 1m / 5m / 30m / 2h
Eventos de pruebaPortal Send testlivemode: false, prefijo id evt_test_

Registro, rotación de secreto, historial y retry manual son solo portal (auth de sesión). No hay API Public /v1/webhooks/* en v1.

Catálogo de eventos {#events}

Suscríbete por endpoint. Se requiere al menos un evento.

CategoríaTipo de eventoCuándo
Procurementprocurement.failedFalló el procurement de almacén
Procurementprocurement.out_of_stockSKU no disponible en procurement
Almacénpackage.receivedPaquete doméstico recibido en almacén
Almacénpackage.exceptionExcepción de entrada (data.exception_type)
Consolidaciónconsolidation.completedConsolidación completada
Envíoshipment.createdEnvío internacional creado
Envíoshipment.dispatchedEntregado al transportista
Envíoshipment.deliveredEntregado al destinatario
Envíoshipment.exceptionExcepción de salida (data.exception_type)
Cuentabalance.lowSaldo del almacén bajo el umbral

El push live warehouse→developer se activa de forma gradual; valida tu receptor con Send test hoy.

Envelope público {#envelope}

Cada cuerpo de entrega es JSON:

{
  "id": "evt_01HXYZ…",
  "type": "package.received",
  "created_at": "2026-08-16T04:00:00.000Z",
  "livemode": true,
  "app_id": "app_…",
  "data": {
    "package_id": "pkg_…",
    "order_id": "ord_…",
    "status": "received"
  }
}
CampoTipoDescripción
idstringID público del evento (evt_… live, evt_test_… test)
typestringTipo del catálogo
created_atstringMarca de tiempo ISO-8601
livemodebooleanfalse en pruebas del portal
app_idstringID de tu app
dataobjectPayload sin campos internos de almacén

Ejemplos de data {#data-shapes}

Igual que las muestras de prueba del portal; live usa las mismas claves.

procurement.failed

{
  "order_id": "ord_…",
  "status": "failed",
  "reason": "supplier_rejected"
}

package.exception

{
  "package_id": "pkg_…",
  "order_id": "ord_…",
  "status": "exception",
  "exception_type": "DAMAGED"
}

shipment.dispatched

{
  "shipment_id": "shp_…",
  "tracking_number": "…",
  "status": "dispatched"
}

balance.low

{
  "available_amount": 12.5,
  "currency": "USD",
  "threshold": 50
}

Entrega HTTP {#delivery}

POST /your/webhook-path HTTP/1.1
Host: your-server.example
Content-Type: application/json
User-Agent: HioBuy-Webhooks/1.0
HioBuy-Event-Id: evt_01HXYZ…
HioBuy-Signature: t=1723780800,v1=abcdef0123456789…
  • En producción la URL debe ser HTTPS. Fuera de producción se permiten http://localhost / túneles.
  • Responde 2xx en 10 s. Cualquier otro caso programa reintento.
  • Entrega at-least-once. Deduplica con id (y opcionalmente HioBuy-Event-Id).

Verificación de firma {#signature}

  1. Lee HioBuy-Signature (t=<unix_seconds>,v1=<hex_hmac>).
  2. Construye "{t}.{raw_body}" donde raw_body es el cuerpo exacto recibido (JSON UTF-8).
  3. Calcula HMAC-SHA256(secret, signed_payload) en hex.
  4. Compara con v1 en tiempo constante.
  5. Rechaza si |now - t| es demasiado grande (tolerancia recomendada: 5 minutos).

Node.js ejemplo

import crypto from "node:crypto";
 
function verifyHioBuySignature(rawBody, signatureHeader, secret, toleranceSec = 300) {
  const match = /^t=(\d+),v1=([0-9a-f]+)$/i.exec(signatureHeader || "");
  if (!match) return false;
 
  const t = Number(match[1]);
  const expected = match[2].toLowerCase();
  if (!Number.isFinite(t)) return false;
  if (Math.abs(Math.floor(Date.now() / 1000) - t) > toleranceSec) return false;
 
  const signed = `${t}.${rawBody}`;
  const digest = crypto
    .createHmac("sha256", secret)
    .update(signed, "utf8")
    .digest("hex");
 
  const a = Buffer.from(digest, "utf8");
  const b = Buffer.from(expected, "utf8");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Guarda whsec_… solo en el servidor. El portal muestra máscara (últimos 6). Tras rotar, actualiza el servidor antes de la siguiente entrega.

Reintentos y estado {#retries}

IntentoRetraso tras el fallo anterior
1Inmediato (cola)
21 minuto
35 minutos
430 minutos
52 horas

Tras el último fallo: failed. Puedes Retry now en el detalle del portal.

Estados: pending · success · retrying · failed.

Flujo en el portal {#portal}

  1. Pon la app en warehouse fulfillment en Channel Auth / setup.
  2. Abre Webhooks Add endpoint.
  3. Introduce URL HTTPS, descripción opcional y eventos.
  4. Copia el secreto al mostrarlo (una sola vez).
  5. Usa Send test event e inspecciona deliveries / attempts.
  6. Rota el secreto, desactiva o elimina cuando haga falta.

Límites y retención {#limits}

LímiteValor
Payload≤ 64 KB
cuerpo de respuesta guardado en attempt≤ 4 KB
retención de events / deliveries~30 días
Attempt~14 días

Relacionado

Get Support

Need integration help? Contact Developer Support at support@hiobuy.com · Response within 1–2 business days

Email support