Tema
Eventos
Todos los cuerpos traen event, occurred_at, company_id y delivery_id. El esquema formal de cada uno está en la sección webhooks de la especificación.
| Evento | Scope | Cuándo |
|---|---|---|
order.created | orders:read | Pedido nuevo de tu florería, por cualquier canal |
order.status_changed | orders:read | Cada cambio de estado |
order.delivered | orders:read | El pedido pasó a delivered |
order.cancelled | orders:read | El pedido pasó a cancelled |
order.photo_uploaded | orders:read | Se subió o cambió la foto de entrega |
product.created | catalog:read | Producto nuevo |
product.updated | catalog:read | Datos, variantes, imágenes u opciones, o varios cambios juntos |
product.price_changed | catalog:read | Solo precio, oferta o fin de oferta |
product.status_changed | catalog:read | Solo activar o desactivar |
product.deleted | catalog:read | Borrado, o dejaste de revenderlo |
product.stock_changed | catalog:read | Stock. Hay que pedirlo explícito: los comodines no lo incluyen |
availability.changed | catalog:read | Bloqueo de día, alta demanda, comunas u horarios |
ping | — | Prueba manual (POST /webhooks/<id>/test) |
Pedidos
order.created, order.status_changed, order.delivered, order.cancelled y order.photo_uploaded. order es el mismo cuerpo que GET /orders/<id>. Los tres de estado traen además previous_status, el slug del estado anterior.
order.created se emite para cualquier pedido de tu florería (marketplace de Redfloral, tu tienda en Redfloral, ventas locales y pedidos de la API); distínguelos con is_internal y created_by_api. order.photo_uploaded llega unos segundos después de subirse la foto, cuando ya están sus tres tamaños.
json
{ "event": "order.status_changed", "occurred_at": "2026-11-02T15:04:05.123456+00:00",
"company_id": 15, "delivery_id": 9001, "previous_status": "processing",
"order": { "id": 70123, "external_id": "WC-10452",
"status": { "slug": "in_transit", "name": "En camino" },
"is_internal": true, "created_by_api": true,
"products": [ ... ], "history": [ ... ], "...": "..." } }Productos
product.created, product.updated, product.price_changed y product.status_changed. product es el cuerpo de GET /products/<id> y changes dice qué cambió: created, data, variants, images, personalization, price, status, stock.
json
{ "event": "product.price_changed", "occurred_at": "2026-11-02T15:04:50+00:00",
"company_id": 15, "delivery_id": 9002, "changes": ["price"],
"product": { "id": 8891, "shared": false, "name": "Ramo Primavera", "price": 25000,
"price_sale": null, "is_active": true, "variants": [],
"images": [ ... ], "...": "..." } }product.deleted es liviano:
json
{ "event": "product.deleted", "occurred_at": "2026-11-02T15:10:00+00:00",
"company_id": 15, "delivery_id": 9003, "product_id": 8891 }product.stock_changed también:
json
{ "event": "product.stock_changed", "occurred_at": "2026-11-02T15:12:00+00:00",
"company_id": 15, "delivery_id": 9004, "product_id": 8891,
"is_stock": true, "quantity": 7, "variants": [{ "id": 51, "stock": 3 }] }Disponibilidad
availability.changed es liviano y llega una sola vez por ventana aunque cambien muchas cosas. Al recibirlo, vuelve a consultar delivery-availability y products/prices para las fechas afectadas.
json
{ "event": "availability.changed", "occurred_at": "2026-11-02T15:15:00+00:00",
"company_id": 15, "delivery_id": 9005,
"changes": [
{ "type": "day_block", "action": "created", "date": "2026-11-14" },
{ "type": "high_demand", "action": "updated", "date": "2026-11-20", "percentage": 20, "is_active": true },
{ "type": "zone", "action": "updated", "zone_id": 12, "is_active": true },
{ "type": "schedule", "action": "updated", "schedule_id": 7, "day": 4, "is_active": true }
] }Prueba
json
{ "event": "ping", "occurred_at": "2026-11-02T15:20:00+00:00", "company_id": 15,
"webhook_id": 3, "message": "...", "delivery_id": 9006 }