WebHook


Canal de comunicación servidor a servidor para integraciones con terceros. Un mismo registro puede funcionar en dos sentidos según su name:

  • Salientes: cuando ocurre un evento, la plataforma llama a un endpoint externo usando method + url + headers + body + auth. Nombres en WebHook::OUTBOUND_HOOKS (goods_import, order_status_report, payments_validation_zelle, payments_report_stripe, fleet_prices_partner, order_creation_partner, shipment_creation_partner, promos_sync, discounts_refresh, ...).
  • Entrantes: un tercero llama a web-hooks/{handler}/{hookName} (ruta con nombre web-hooks.inbound.handler, autenticada con auth.api) y un intérprete registrado procesa el payload: validación de pagos de pasarelas (Zelle, Payco, Sypago, Stripe, Bancamiga), creación/validación/cancelación de delivery de Deliverect, manejo de órdenes y de estados de entrega de SIMs, etc.

El formato detallado de cada tipo está en la página web_hook_format.

Plantillas de cuerpo (hooks salientes)

Los valores de body admiten tokens comando:accesor que se resuelven contra el objeto relacionado en el momento del disparo: v: valor directo, e2: divide entre 100, e6: divide entre 1.000.000, datef2:/datef3: formatean una fecha, if: incluye el bloque sólo si el accesor tiene valor, c: valor constante. Un sufijo ::tipo (s, i, f, d) castea el resultado; con ; se indica un valor por defecto.

config

Objeto JSON de opciones. El trait HasConfig lo expone además explotado en propiedades config_* y good_import_*. Claves relevantes:

Clave Descripción
ext Formato de la respuesta esperada (json, csv, ...).
auto_sync / auto_sync_delay / auto_sync_offset Ejecución programada del hook de importación: activación, minutos entre corridas y desfase horario.
check_in_service Sólo ejecuta si el comercio está en servicio.
order_status_mask Máscara de estados de orden que disparan el hook saliente.
conditions Condiciones extra que deben cumplirse para disparar el hook.
use_body Envía body como cuerpo de la petición saliente.
ttl Segundos de vida de la respuesta cacheada.
tries / backoff Reintentos ante fallo y espera entre ellos.
response_processor.handler / response_processor.hook_name Hook encargado de procesar la respuesta recibida.
config.data_accessor Ruta dentro de la respuesta donde están los ítems a importar.
config.refresh_data / config.refresh_category Actualiza datos / categoría de los productos ya existentes.
config.clear_missing Elimina los productos que no vienen en la importación.
config.quantity_threshold / config.quantity_reservation Umbral de stock y cantidad reservada al importar.
config.starting_cell Celda inicial en importaciones desde hoja de cálculo.
config.separated_sku El SKU viene en una columna separada.
config.debug Modo depuración de la importación.
config.currency Moneda de los precios importados.
appends.branch_id Comercio destino de los productos importados.
identifier.headers / identifier.latest Cabeceras y clave para identificar la última importación.

Notas y gotchas

  • Crear, actualizar o eliminar un hook limpia la caché hook-{name}.
  • Al actualizar, company_id o branch_id con valor 0 se normalizan a null (hook global).
  • El endpoint trigger tiene un lock de 60 s por hook (ER423 si ya hay uno en curso).

Estructura de Datos

Atributo Tipo Descripción
id int
name string Tipo de hook; valores admitidos en WebHook::NAME_OPTIONS.
enabled bool true si el hook está activo.
method string Verbo HTTP para los hooks salientes (GET, POST, PATCH, UPDATE).
url string Endpoint externo al que se llama en los hooks salientes.
headers array Plantilla de cabeceras de la petición saliente.
body array Plantilla del cuerpo de la petición saliente; admite tokens comando:accesor (ver arriba).
auth array Configuración de autenticación: {type: none|basic|jwt, ...}.
created_at datetime\|null Fecha de creación.
updated_at datetime\|null Fecha de última modificación.
company_id int\|null Compañía a la que aplica el hook; null si es global.
branch_id int\|null Comercio al que aplica el hook; null si es global o de compañía/grupo.
config array Objeto JSON de opciones del hook (ver tabla de claves arriba).
branch_group_id int\|null Grupo de comercios al que aplica el hook; null si no aplica a un grupo.
display_name string\|null Nombre visible del hook en el panel.
config_auto_sync bool\|null Atajo de config.auto_sync: ejecución programada del hook de importación.
config_auto_sync_delay int\|null Atajo de config.auto_sync_delay: minutos entre ejecuciones automáticas.
config_auto_sync_offset int Atajo de config.auto_sync_offset: desfase en minutos del horario de sincronización.
config_backoff array\|null Atajo de config.backoff: espera entre reintentos.
config_check_in_service bool\|null Atajo de config.check_in_service: sólo ejecuta si el comercio está en servicio.
config_conditions array\|null Atajo de config.conditions: condiciones extra para disparar el hook.
config_ext string Atajo de config.ext: formato de la respuesta esperada (por defecto json).
config_order_status_mask int\|null Atajo de config.order_status_mask: máscara de estados de orden que disparan el hook saliente.
config_response_processor_handler string\|null Atajo de config.response_processor.handler: hook que procesa la respuesta.
config_response_processor_hook string\|null Atajo de config.response_processor.hook_name: nombre del hook que procesa la respuesta.
config_tries int\|null Atajo de config.tries: número de reintentos ante fallo.
config_ttl int\|null Atajo de config.ttl: segundos de vida de la respuesta cacheada.
config_use_body bool\|null Atajo de config.use_body: envía body como cuerpo de la petición saliente.
good_import_branch_id int\|null Atajo de config.appends.branch_id: comercio destino de los productos importados.
good_import_clear_missing bool\|null Atajo de config.config.clear_missing: elimina los productos ausentes en la importación.
good_import_currency string\|null Atajo de config.config.currency: moneda de los precios importados.
good_import_data_accessor string\|null Atajo de config.config.data_accessor: ruta de la respuesta con los ítems a importar.
good_import_debug bool\|null Atajo de config.config.debug: modo depuración de la importación.
good_import_header_identifiers array\|null Atajo de config.identifier.headers: cabeceras para identificar la importación.
good_import_latest_unique_key string\|null Atajo de config.identifier.latest: clave para identificar la última importación.
good_import_quantity_reservation int\|null Atajo de config.config.quantity_reservation: cantidad reservada al importar stock.
good_import_quantity_threshold int\|null Atajo de config.config.quantity_threshold: umbral de stock al importar.
good_import_refresh_category bool\|null Atajo de config.config.refresh_category: actualiza la categoría de los productos existentes.
good_import_refresh_data bool\|null Atajo de config.config.refresh_data: actualiza los datos de los productos existentes.
good_import_separated_sku bool\|null Atajo de config.config.separated_sku: el SKU viene en una columna separada.
good_import_starting_cell string\|null Atajo de config.config.starting_cell: celda inicial en importaciones desde hoja de cálculo.
import_config GoodImportOptions Vista tipada de config para los hooks de importación de productos.
allLogs ApiLog> Registros de auditoría de la API, incluidos los internos.
logs ApiLog> Registros de auditoría de la API visibles.
{
    "id": 1,
    "name": "payments_validation_zelle",
    "enabled": false,
    "method": "POST",
    "url": "https://bspaycoapi-qa.payco.net.ve/api/v1/transaccion/zelle.registrar",
    "headers": [],
    "body": {
        "Monto": "e2:total_e2",
        "CodigoAutorizacion": "v:metadata.payload.identifier",
        "Email": "v:metadata.payload.email",
        "NombrePagador": "v:client.name",
        "Fecha": "datef2:updated_at"
    },
    "auth": {
        "type": "basic",
        "username": "liveri_vz_admin",
        "password": "12345678"
    },
    "created_at": "2020-07-21 22:21:39",
    "updated_at": "2025-10-08 13:59:47",
    "company_id": null,
    "branch_id": null,
    "config": {
        "response_processor": {
            "handler": "payco",
            "hook_name": "zelle-validate"
        }
    },
    "branch_group_id": null,
    "display_name": "Pagos Payco Zelle"
}

Endpoints

Insertar WebHook

Crear un webhook

Crea un WebHook. Si no se envían, enabled es false, method es POST, headers vacío y auth.type es none.

Método URI Cabeceras
POST /web-hooks Authorization
{
    "name": "required|string|in:goods_import,order_status_report,payments_validation_zelle,payments_report_stripe,fleet_prices_ridery,fleet_prices_partner,shipment_creation_ridery,shipment_creation_partner,order_creation_ridery,order_creation_partner,promos_sync,discounts_refresh",
    "display_name": "required|string|max:64",
    "enabled": "boolean",
    "method": "string|in:GET,POST,PATCH,UPDATE",
    "url": "required|string|url",
    "headers": [
        "string"
    ],
    "body": "array",
    "config": "array",
    "auth": {
        "type": "string|in:none,basic,jwt"
    },
    "company_id": "integer",
    "branch_id": "integer",
    "branch_group_id": "integer"
}

Listar WebHook

{info} Soporta: Paginación Filters Carga dinámica

Listar webhooks

Devuelve los WebHook configurados, paginados.

Método URI Cabeceras
GET /web-hooks Authorization

Mostrar WebHook

{info} Soporta: Carga dinámica

Ver un webhook

Devuelve el WebHook indicado.

Método URI Cabeceras
GET /web-hooks/{webHookId} Authorization

Actualizar WebHook

Actualizar un webhook

Modifica el WebHook. company_id o branch_id con valor 0 se guardan como null (hook global).

Método URI Cabeceras
PATCH /web-hooks/{webHookId} Authorization
{
    "name": "string|in:goods_import,order_status_report,payments_validation_zelle,payments_report_stripe,fleet_prices_ridery,fleet_prices_partner,shipment_creation_ridery,shipment_creation_partner,order_creation_ridery,order_creation_partner,promos_sync,discounts_refresh",
    "display_name": "required|string|max:64",
    "enabled": "boolean",
    "method": "string|in:GET,POST,PATCH,UPDATE",
    "url": "string|url",
    "headers": [
        "string"
    ],
    "body": "array",
    "config": "array",
    "auth": {
        "type": "string|in:none,basic,jwt"
    },
    "company_id": "integer",
    "branch_id": "integer",
    "branch_group_id": "integer"
}

Eliminar WebHook

Eliminar un webhook

Borra el WebHook indicado.

Método URI Cabeceras
DELETE /web-hooks/{webHookId} Authorization

Acciones de WebHook

Opciones de webhooks

{info} Soporta: Paginación Filters Carga dinámica

Devuelve los catálogos para construir un WebHook: names (tipos de hook admitidos), outbound_hooks (tipos que operan como salientes) y response_processors (handlers y hooks disponibles para procesar la respuesta).

Método URI Cabeceras
GET /web-hooks/options Authorization

Disparar un webhook manualmente

Ejecuta el WebHook saliente con el payload recibido y devuelve su import_config.

{warning} Hay un lock de 60 segundos por hook: dos disparos seguidos del mismo webhook devuelven error.

Método URI Cabeceras
POST /web-hooks/{webHookId}/trigger Authorization

Errores de negocio

Código HTTP Cuándo ocurre
ER423 423 Ya hay un disparo de este webhook en curso (lock de 60 s).

Reprocesar la respuesta de un webhook

Vuelve a pasar el payload recibido por el procesador de respuesta del WebHook, acotado al grupo de comercios del hook, y devuelve el resultado combinado con su import_config.

Método URI Cabeceras
POST /web-hooks/{webHookId}/handle Authorization

Check

{info} Soporta: Carga dinámica

Método URI Cabeceras
POST /orders/authorize N/A
{
    "code": {
        "required": true,
        "string": true,
        "min": "8",
        "regex": "/docs/3/web_hook#^\d+\|[0-9a-f]+$#"
    },
    "is_allowed": "nullable|boolean"
}

Check

{info} Soporta: Carga dinámica

Método URI Cabeceras
GET /orders/authorize N/A
{
    "code": {
        "required": true,
        "string": true,
        "min": "8",
        "regex": "/docs/3/web_hook#^\d+\|[0-9a-f]+$#"
    },
    "is_allowed": "nullable|boolean"
}

Relaciones