Saltar al contenido
Webhooks

Eventos

Cómo registrar un endpoint, verificar entregas y leer cada evento.

Hay 39 eventos en 6 categorías. El cuerpo JSON de cada entrega es el modelo del evento, sin sobre común.

Configurar el endpoint

Registra un endpoint con POST /v1/webhooks/endpoints. Al crearlo se envía un evento webhook.endpoint.test a la URL, y el endpoint se guarda solo si responde 2xx.

RequisitoValor
URLHTTPS, pública y de hasta 2048 caracteres. No puede resolver a una red privada o local.
UnicidadUna URL por tienda (y por vendedor, si el token es de un vendedor)
Respuesta correctaCualquier 2xx
Tiempo límite15 segundos

Cabeceras de entrega

CabeceraContenido
X-Ecomiq-EventTipo de evento, por ejemplo catalog.product.created
X-Ecomiq-DeliveryUUID de la entrega
X-Ecomiq-TimestampMomento del intento, en segundos Unix
X-Ecomiq-Signaturesha256=<hmac>, si el endpoint tiene secret

Verificar la firma

Con un secret configurado, cada entrega lleva el HMAC-SHA256 del cuerpo crudo en hexadecimal minúscula. Calcúlalo sobre el cuerpo tal como llega, antes de leer el JSON, y descarta el evento si no coincide.

import { createHmac, timingSafeEqual } from "node:crypto"

export function isValidSignature(rawBody: string, header: string, secret: string) {
  const expected = createHmac("sha256", secret).update(rawBody).digest("hex")
  const received = header.replace(/^sha256=/, "")

  const a = Buffer.from(expected, "hex")
  const b = Buffer.from(received, "hex")

  return a.length === b.length && timingSafeEqual(a, b)
}

Autenticación adicional

Con auth, cada entrega incluye credenciales en Authorization. Con headers, agrega cabeceras fijas.

auth.typeauth.config
basicUsername y Password
bearerToken
oAuth2TokenUrl HTTPS pública, ClientId y ClientSecret; opcionales Scope y TokenProperty (por defecto access_token)

Entrega y reintentos

Responde 2xx dentro de 15 segundos y procesa después. Otro estado o un timeout se reintenta con el mismo X-Ecomiq-Delivery, así que un evento puede llegar más de una vez: procésalo de forma idempotente.

Cada respuesta correcta reinicia el contador de fallos. Tras 10 fallos consecutivos el endpoint se pausa; corrige el receptor y llama a POST /v1/webhooks/endpoints/{id}/enable.

Para reenviar una entrega fallida, usa POST /v1/webhooks/deliveries/{id}/retry. El reenvío conserva el cuerpo y lleva un X-Ecomiq-Delivery nuevo.

Eventos disponibles

EventoModelo
catalog.product.createdProductChangedWebhookModel
catalog.product.updatedProductChangedWebhookModel
catalog.product.deletedProductDeletedWebhookModel
catalog.product.status_changedProductStatusChangedWebhookModel
catalog.stock.changedStockChangedWebhookModel
catalog.inventory.batch_processedInventoryBatchProcessedWebhookModel
catalog.price.changedPriceChangedWebhookModel
catalog.brand.createdBrandWebhookModel
catalog.brand.updatedBrandWebhookModel
catalog.brand.deletedBrandDeletedWebhookModel
catalog.category.createdCategoryWebhookModel
catalog.category.updatedCategoryWebhookModel
catalog.category.deletedCategoryDeletedWebhookModel
catalog.collection.createdCollectionWebhookModel
catalog.collection.updatedCollectionWebhookModel
catalog.collection.deletedCollectionDeletedWebhookModel

Canales

EventoModelo
channel.listing.publishedListingPublishedWebhookModel
channel.listing.price_changedListingPriceChangedWebhookModel
channel.createdChannelCreatedWebhookModel
channel.sales.enabledChannelStateWebhookModel
channel.deletedChannelDeletedWebhookModel

Operaciones

EventoModelo
operation.finishedOperationWebhookModel

Clientes

EventoModelo
customer.createdCustomerWebhookModel

Carritos

EventoModelo
cart.createdCartCreatedWebhookModel
cart.updatedCartUpdatedWebhookModel
cart.completedCartCompletedWebhookModel
cart.item_addedCartItemWebhookModel
cart.item_removedCartItemWebhookModel

Pedidos

EventoModelo
order.createdOrderWebhookModel
order.confirmedOrderWebhookModel
order.invoicedOrderWebhookModel
order.in_progressOrderWebhookModel
order.ready_to_pick_upOrderWebhookModel
order.in_transitOrderWebhookModel
order.deliveredOrderWebhookModel
order.cancelledOrderWebhookModel
order.returnedOrderWebhookModel
order.closedOrderWebhookModel
order.invalidatedOrderWebhookModel

Campos del cuerpo

Los campos usan camelCase. Los IDs son strings: guárdalos tal cual, sin convertirlos a número.

ProductChangedWebhookModel

Eventos: catalog.product.created · catalog.product.updated

CampoTipo JSONPuede ser nullDescripción
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
sellerIdstringSíIdentificador del vendedor propietario del producto.
productIdstringNoIdentificador del producto.
productobjectNoDatos del producto.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.
targetChannelIdsstring[]NoIdentificadores de los canales a los que se dirige el evento.
changeTypestringNoIndica si el producto se creó o actualizó.

ProductDeletedWebhookModel

Eventos: catalog.product.deleted

CampoTipo JSONPuede ser nullDescripción
productIdstringNoIdentificador del producto.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
sellerIdstringNoIdentificador del vendedor.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

ProductStatusChangedWebhookModel

Eventos: catalog.product.status_changed

CampoTipo JSONPuede ser nullDescripción
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
productIdstringNoIdentificador del producto.
sellerIdstringNoIdentificador del vendedor.
isActivebooleanNoIndica si el producto está activo.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

StockChangedWebhookModel

Eventos: catalog.stock.changed

CampoTipo JSONPuede ser nullDescripción
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
productIdstringNoIdentificador del producto.
variantIdstringNoIdentificador de la variante.
locationIdstringNoIdentificador de la ubicación.
availableQuantityintegerNoCantidad de stock disponible.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

InventoryBatchProcessedWebhookModel

Eventos: catalog.inventory.batch_processed

CampoTipo JSONPuede ser nullDescripción
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
modestringNoModo aplicado al lote de ajustes.
adjustmentsCountintegerNoCantidad de líneas de inventario ajustadas.
productsCountintegerNoCantidad de productos afectados.
variantsCountintegerNoCantidad de variantes afectadas.
locationsCountintegerNoCantidad de ubicaciones afectadas.
linesarrayNoLíneas de inventario ajustadas.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

PriceChangedWebhookModel

Eventos: catalog.price.changed

CampoTipo JSONPuede ser nullDescripción
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
productIdstringNoIdentificador del producto.
sellerIdstringNoIdentificador del vendedor.
pricenumber (decimal)NoPrecio actual del producto.
compareAtPricenumber (decimal)SíPrecio de comparación original.
currencystringNoCódigo de moneda.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

BrandWebhookModel

Eventos: catalog.brand.created · catalog.brand.updated

CampoTipo JSONPuede ser nullDescripción
brandIdstringNoIdentificador de la marca.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
namestringNoNombre de la marca.
slugstringNoSlug de la marca.
isActivebooleanSíIndica si la marca está activa.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

BrandDeletedWebhookModel

Eventos: catalog.brand.deleted

CampoTipo JSONPuede ser nullDescripción
brandIdstringNoIdentificador de la marca.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

CategoryWebhookModel

Eventos: catalog.category.created · catalog.category.updated

CampoTipo JSONPuede ser nullDescripción
categoryIdstringNoIdentificador de la categoría.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
namestringNoNombre de la categoría.
slugstringNoSlug de la categoría.
parentIdstringSíIdentificador de la categoría superior.
isActivebooleanSíIndica si la categoría está activa.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

CategoryDeletedWebhookModel

Eventos: catalog.category.deleted

CampoTipo JSONPuede ser nullDescripción
categoryIdstringNoIdentificador de la categoría.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

CollectionWebhookModel

Eventos: catalog.collection.created · catalog.collection.updated

CampoTipo JSONPuede ser nullDescripción
collectionIdstringNoIdentificador de la colección.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
namestringNoNombre de la colección.
slugstringNoSlug de la colección.
descriptionstringSíDescripción de la colección.
statusstringNoEstado de la colección.
typestringNoTipo de colección.
dynamicOperatorstringNoOperador de las reglas dinámicas.
validFromstring (date-time)SíFecha de inicio de la colección.
validTostring (date-time)SíFecha de finalización de la colección.
imageUrlstringSíURL de la imagen de la colección.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

CollectionDeletedWebhookModel

Eventos: catalog.collection.deleted

CampoTipo JSONPuede ser nullDescripción
collectionIdstringNoIdentificador de la colección.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

ListingPublishedWebhookModel

Eventos: channel.listing.published

CampoTipo JSONPuede ser nullDescripción
listingIdstringNoIdentificador de la publicación.
channelIdstringNoIdentificador del canal.
productIdstringNoIdentificador del producto.
externalIdstringNoIdentificador externo de la publicación.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
sellerIdstringNoIdentificador del vendedor.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

ListingPriceChangedWebhookModel

Eventos: channel.listing.price_changed

CampoTipo JSONPuede ser nullDescripción
listingIdstringNoIdentificador de la publicación.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
sellerIdstringNoIdentificador del vendedor.
channelIdstringNoIdentificador del canal.
productIdstringNoIdentificador del producto.
externalIdstringSíIdentificador externo de la publicación.
oldPricenumber (decimal)NoPrecio anterior de la publicación.
newPricenumber (decimal)NoNuevo precio de la publicación.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

ChannelCreatedWebhookModel

Eventos: channel.created

CampoTipo JSONPuede ser nullDescripción
channelIdstringNoIdentificador del canal.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
sellerIdstringSíIdentificador del vendedor.
namestringNoNombre del canal.
integrationIdstringNoIdentificador del proveedor.
channelTypestringNoTipo de canal.
isPrincipalbooleanNoIndica si es el canal principal.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

ChannelStateWebhookModel

Eventos: channel.sales.enabled

CampoTipo JSONPuede ser nullDescripción
channelIdstringNoIdentificador del canal.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
sellerIdstringSíIdentificador del vendedor.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

ChannelDeletedWebhookModel

Eventos: channel.deleted

CampoTipo JSONPuede ser nullDescripción
channelIdstringNoIdentificador del canal.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
sellerIdstringSíIdentificador del vendedor.
connectionIdstringNoIdentificador de la conexión.
providerIdstringNoIdentificador del proveedor.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

OperationWebhookModel

Eventos: operation.finished

CampoTipo JSONPuede ser nullDescripción
idstringNoIdentificador de la operación.
typestringNoTipo de operación.
resourcestringNoRecurso.
statusstringNoEstado final.
totalRowsintegerNoTotal de filas.
succeededRowsintegerNoFilas procesadas correctamente.
failedRowsintegerNoFilas rechazadas.
completedOnstring (date-time)NoFecha de finalización.

CustomerWebhookModel

Eventos: customer.created

CampoTipo JSONPuede ser nullDescripción
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
customerIdstringNoIdentificador del cliente.
emailstringSíCorreo electrónico del cliente.
firstNamestringSíNombre del cliente.
lastNamestringSíApellido del cliente.
customerTypestringNoTipo de cliente.
customerStatusstringNoEstado del cliente.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

CartCreatedWebhookModel

Eventos: cart.created

CampoTipo JSONPuede ser nullDescripción
cartIdstringNoIdentificador del carrito.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
currencyCodestringNoCódigo de moneda.
createdBystring (uuid)NoIdentificador UUID del actor que creó el carrito.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

CartUpdatedWebhookModel

Eventos: cart.updated

CampoTipo JSONPuede ser nullDescripción
cartIdstringNoIdentificador del carrito.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
updatedBystring (uuid)NoIdentificador UUID del actor que actualizó el carrito.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

CartCompletedWebhookModel

Eventos: cart.completed

CampoTipo JSONPuede ser nullDescripción
cartIdstringNoIdentificador del carrito.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
totalAmountnumber (decimal)NoImporte total del carrito.
currencyCodestringNoCódigo de moneda.
completedBystring (uuid)NoIdentificador UUID del actor que completó el carrito.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

CartItemWebhookModel — cart.item_added

Eventos: cart.item_added

CampoTipo JSONPuede ser nullDescripción
cartIdstringNoIdentificador del carrito.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
cartItemIdstringNoIdentificador del artículo del carrito.
productIdstringNoIdentificador del producto.
variantIdstringNoIdentificador de la variante.
quantityintegerNoCantidad agregada.
unitPricenumber (decimal)NoPrecio unitario.
actorIdstring (uuid)SíIdentificador UUID del actor que ejecutó la operación.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

CartItemWebhookModel — cart.item_removed

Eventos: cart.item_removed

CampoTipo JSONPuede ser nullDescripción
cartIdstringNoIdentificador del carrito.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
cartItemIdstringNoIdentificador del artículo del carrito.
productIdstringNoIdentificador del producto.
variantIdstringNoIdentificador de la variante.
quantityintegerSíSiempre es null cuando se retira un artículo.
unitPricenumber (decimal)SíSiempre es null cuando se retira un artículo.
actorIdstring (uuid)SíIdentificador UUID del actor que ejecutó la operación.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

OrderWebhookModel

Eventos: order.created · order.confirmed · order.invoiced · order.in_progress · order.ready_to_pick_up · order.in_transit · order.delivered · order.cancelled · order.returned · order.closed · order.invalidated

CampoTipo JSONPuede ser nullDescripción
orderIdstringNoIdentificador del pedido.
tenantIdstringNoIdentificador de la organización.
storeIdstringNoIdentificador de la tienda.
sellerIdstringSíIdentificador del vendedor al que pertenece el pedido.
customerIdstringSíIdentificador del cliente.
orderNumberstringNoNúmero del pedido.
orderGroupstringSíIdentificador del grupo de pedidos.
statestringNoEstado actual del ciclo de vida del pedido.
fulfillmentStatusstringNoEstado actual de preparación y entrega.
returnStatusstringNoEstado actual de la devolución.
currencyCodestringNoCódigo de moneda.
subTotalnumber (decimal)NoSubtotal del pedido.
shippingnumber (decimal)NoImporte del envío.
taxnumber (decimal)NoImporte de impuestos.
totalnumber (decimal)NoTotal del pedido.
emailstringSíCorreo electrónico del cliente.
firstNamestringSíNombre del cliente.
lastNamestringSíApellido del cliente.
cancelReasonstringSíMotivo de la cancelación.
trackingCodestringSíNúmero de seguimiento.
trackingUrlstringSíURL de seguimiento.
carrierNamestringSíNombre del transportista.
orderDatestring (date-time)NoFecha del pedido.
occurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

Última actualización:

En esta página