Saltar al contenido
Guías

Webhooks

Configuración, entrega y campos de los eventos de webhook.

Puedes suscribirte a 37 eventos en 5 categorías. El cuerpo JSON corresponde al modelo indicado para cada evento; no existe un sobre común.

Configurar el endpoint

Registra un endpoint para la tienda con POST /v1/webhooks/endpoints. La URL debe usar HTTPS, ser pública y no resolver a una red privada o local.

Al crearlo, Ecomiq envía webhook.endpoint.test. El endpoint se guarda solo si esa prueba responde con 2xx antes del límite de 15 segundos.

RequisitoValor
Esquemahttps
Longitud máxima2048 caracteres
UnicidadLa misma URL no puede repetirse en el contexto actual de tienda y vendedor
Respuesta correctaCualquier 2xx
Tiempo límite15 segundos

Cabeceras de entrega

CabeceraContenido
X-Ecomiq-EventTipo de evento, por ejemplo catalog.product.created
X-Ecomiq-DeliveryIdentificador UUID de la entrega
X-Ecomiq-TimestampMomento del intento, en segundos Unix
X-Ecomiq-Signaturesha256=<hmac>, solo cuando configuras un secreto

Verificar la firma

Ecomiqemisor del eventoTu endpointel receptorPOST con el eventoX-Ecomiq-Signature, X-Ecomiq-TimestampRecalcula el HMACcompara en tiempo constante200responde antes de procesarSi la firma no cuadra, descarta: no proceses el evento

Si configuras un secret, Ecomiq firma el cuerpo crudo con HMAC-SHA256 y codifica el resultado en hexadecimal minúscula. Verifica la firma antes de leer el JSON.

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

Puedes configurar credenciales para que Ecomiq las incluya en cada envío. También puedes agregar cabeceras fijas con headers.

TipoConfiguración requerida
BasicUsername y Password
BearerToken
OAuth2TokenUrl HTTPS pública, ClientId y ClientSecret

Entrega y reintentos

Algo cambiaun pedido, un productoEcomiq envíaPOST firmadoTu endpointresponde en 15 s2xxentrega cerradaOtro estado o timeoutse reintentaResponde 2xx primero y procesa después: el reloj corre

La entrega es al menos una vez. Un fallo puede repetir el mismo evento con el mismo X-Ecomiq-Delivery; procesa el evento de forma idempotente y guarda ese identificador después de completar el trabajo.

Una respuesta correcta reinicia el contador de fallos. Tras 10 intentos fallidos consecutivos, Ecomiq pausa el endpoint. Corrige el receptor y llama a POST /v1/webhooks/endpoints/{id}/enable.

Puedes reenviar una entrega fallida con POST /v1/webhooks/deliveries/{id}/retry. El reintento manual conserva el cuerpo y crea un nuevo X-Ecomiq-Delivery.

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

Clientes

EventoModelo
customer.createdCustomerWebhookModel

Carritos

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

Pedidos

EventoModelo
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

El runtime actual usa nombres PascalCase y serializa los IDs snowflake como números JSON int64. En JavaScript, usa un parser que conserve enteros de 64 bits: Number puede perder precisión.

ProductChangedWebhookModel

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

CampoTipo JSONPuede ser nullDescripción
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
SellerIdinteger (int64)Identificador del vendedor propietario del producto.
ProductIdinteger (int64)NoIdentificador del producto.
ProductobjectNoDatos del producto.
OccurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.
TargetChannelIdsinteger[] (int64)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
ProductIdinteger (int64)NoIdentificador del producto.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
SellerIdinteger (int64)NoIdentificador del vendedor.
OccurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

ProductStatusChangedWebhookModel

Eventos: catalog.product.status_changed

CampoTipo JSONPuede ser nullDescripción
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
ProductIdinteger (int64)NoIdentificador del producto.
SellerIdinteger (int64)NoIdentificador 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
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
ProductIdinteger (int64)NoIdentificador del producto.
VariantIdinteger (int64)NoIdentificador de la variante.
LocationIdinteger (int64)NoIdentificador 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
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador 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
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
ProductIdinteger (int64)NoIdentificador del producto.
SellerIdinteger (int64)NoIdentificador del vendedor.
Pricenumber (decimal)NoPrecio actual del producto.
CompareAtPricenumber (decimal)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
BrandIdinteger (int64)NoIdentificador de la marca.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
NamestringNoNombre de la marca.
SlugstringNoSlug de la marca.
IsActivebooleanIndica 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
BrandIdinteger (int64)NoIdentificador de la marca.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador 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
CategoryIdinteger (int64)NoIdentificador de la categoría.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
NamestringNoNombre de la categoría.
SlugstringNoSlug de la categoría.
ParentIdinteger (int64)Identificador de la categoría superior.
IsActivebooleanIndica 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
CategoryIdinteger (int64)NoIdentificador de la categoría.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador 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
CollectionIdinteger (int64)NoIdentificador de la colección.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
NamestringNoNombre de la colección.
SlugstringNoSlug de la colección.
DescriptionstringDescripción de la colección.
StatusstringNoEstado de la colección.
TypestringNoTipo de colección.
DynamicOperatorstringNoOperador de las reglas dinámicas.
ValidFromstring (date-time)Fecha de inicio de la colección.
ValidTostring (date-time)Fecha de finalización de la colección.
ImageUrlstringURL 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
CollectionIdinteger (int64)NoIdentificador de la colección.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
OccurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

ListingPublishedWebhookModel

Eventos: channel.listing.published

CampoTipo JSONPuede ser nullDescripción
ListingIdinteger (int64)NoIdentificador de la publicación.
ChannelIdinteger (int64)NoIdentificador del canal.
ProductIdinteger (int64)NoIdentificador del producto.
ExternalIdstringNoIdentificador externo de la publicación.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
SellerIdinteger (int64)NoIdentificador del vendedor.
OccurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

ListingPriceChangedWebhookModel

Eventos: channel.listing.price_changed

CampoTipo JSONPuede ser nullDescripción
ListingIdinteger (int64)NoIdentificador de la publicación.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
SellerIdinteger (int64)NoIdentificador del vendedor.
ChannelIdinteger (int64)NoIdentificador del canal.
ProductIdinteger (int64)NoIdentificador del producto.
ExternalIdstringIdentificador 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
ChannelIdinteger (int64)NoIdentificador del canal.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
SellerIdinteger (int64)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
ChannelIdinteger (int64)NoIdentificador del canal.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
SellerIdinteger (int64)Identificador del vendedor.
OccurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

ChannelDeletedWebhookModel

Eventos: channel.deleted

CampoTipo JSONPuede ser nullDescripción
ChannelIdinteger (int64)NoIdentificador del canal.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
SellerIdinteger (int64)Identificador del vendedor.
ConnectionIdinteger (int64)NoIdentificador de la conexión.
ProviderIdstringNoIdentificador del proveedor.
OccurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

CustomerWebhookModel

Eventos: customer.created

CampoTipo JSONPuede ser nullDescripción
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
CustomerIdinteger (int64)NoIdentificador del cliente.
EmailstringCorreo electrónico del cliente.
FirstNamestringNombre del cliente.
LastNamestringApellido 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
CartIdinteger (int64)NoIdentificador del carrito.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador 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
CartIdinteger (int64)NoIdentificador del carrito.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador 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
CartIdinteger (int64)NoIdentificador del carrito.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador 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
CartIdinteger (int64)NoIdentificador del carrito.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
CartItemIdinteger (int64)NoIdentificador del artículo del carrito.
ProductIdinteger (int64)NoIdentificador del producto.
VariantIdinteger (int64)NoIdentificador de la variante.
QuantityintegerNoCantidad agregada.
UnitPricenumber (decimal)NoPrecio unitario.
ActorIdstring (uuid)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
CartIdinteger (int64)NoIdentificador del carrito.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
CartItemIdinteger (int64)NoIdentificador del artículo del carrito.
ProductIdinteger (int64)NoIdentificador del producto.
VariantIdinteger (int64)NoIdentificador de la variante.
QuantityintegerSiempre es null cuando se retira un artículo.
UnitPricenumber (decimal)Siempre es null cuando se retira un artículo.
ActorIdstring (uuid)Identificador UUID del actor que ejecutó la operación.
OccurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

OrderWebhookModel

Eventos: 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
OrderIdinteger (int64)NoIdentificador del pedido.
TenantIdinteger (int64)NoIdentificador de la organización.
StoreIdinteger (int64)NoIdentificador de la tienda.
SellerIdinteger (int64)Identificador del vendedor al que pertenece el pedido.
CustomerIdinteger (int64)Identificador del cliente.
OrderNumberstringNoNúmero del pedido.
OrderGroupstringIdentificador del grupo de pedidos.
StatusstringNoEstado anterior conservado por compatibilidad.
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.
EmailstringCorreo electrónico del cliente.
FirstNamestringNombre del cliente.
LastNamestringApellido del cliente.
CancelReasonstringMotivo de la cancelación.
TrackingCodestringNúmero de seguimiento.
TrackingUrlstringURL de seguimiento.
CarrierNamestringNombre del transportista.
OrderDatestring (date-time)NoFecha del pedido.
OccurredOnstring (date-time)NoFecha y hora en que ocurrió el evento.

En esta página