> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fire.rest/llms.txt
> Use this file to discover all available pages before exploring further.

# store.updated

> La configuración de una tienda se publicó a sus canales — la tienda completa, sus canales con horarios resueltos y la publicación que produjo el evento.

> [!NOTE]
>
> **Disponibilidad limitada.** Este evento está en despliegue y se habilita por cuenta. Consulta con tu contacto en Fire si ya aplica a la tuya.

> [!WARNING]
>
> Este es el evento `store.updated` de **Integration Flows**, documentado en esta página. **No** es el webhook de integraciones de agregadores con el mismo nombre que se describe en [Referencia de webhooks → `store.updated`](https://docs.fire.rest/es/webhook-reference/store-updated): ese pertenece a otro sistema, tiene otra forma y no cambia.

`store.updated` se dispara cada vez que la configuración de una tienda se **publica** a sus canales: primera publicación, publicar un borrador, re-sincronizar, prender o apagar un canal, aplicar un override, archivar. Siempre trae la **tienda completa** — nunca un diff. Trátalo como un reemplazo total de lo que sabes de esa tienda.

Igual que `store.business_day_closed`, es un evento **a nivel de tienda**: uno por publicación, no uno por orden ni por canal. Una publicación que toca varios canales produce un solo evento con todos los canales adentro, y cada flow que la recibe recibe ese evento una sola vez, con la tienda completa.

## Condición de disparo

Cada publicación de una tienda emite **un** `store.updated`. `data.publication.reason` te dice qué lo produjo:

| `reason` | Qué pasó |
| - | - |
| `publish` | La tienda se publicó por primera vez (también cuando se crea una tienda ya publicada). |
| `draft` | Se aplicaron los cambios pendientes de una tienda publicada. Los canales que se apagan viajan con `enabled: false`. |
| `resync` | Alguien re-sincronizó la tienda; viaja exactamente como está. |
| `channel_toggle` | Se prendió o apagó un canal de la tienda, a mano o por su horario. |
| `override_apply` / `override_revert` | Se aplicó un override a la tienda, o se revirtió. |
| `archive` | La tienda se archivó — ver [Archivar](#archivar). |

Pueden aparecer valores nuevos de `reason` (el contrato ya admite `retry`) y de `mode`. Trata un valor que no conozcas como una publicación normal: el evento igual trae la tienda completa.

Una publicación también puede **programarse**: al programarla no se emite nada; el evento se dispara cuando llega la hora programada, con `publication.mode: "scheduled"` y `publication.scheduledAt`. Cancelar una publicación programada no emite nada.

**No se emite nada** cuando se guardan cambios sin publicarlos a los canales, ni cuando abre o cierra el día de negocio.

| | |
| - | - |
| Cobertura | Todos los países, en las cuentas donde el evento está habilitado |
| Id de la publicación | `data.publication.id` — el mismo en cada entrega y en cada flow que recibe esa publicación |
| Id de la entrega | `event.id`, como en todos los eventos (la ejecución del flow) |
| Orden | `data.publication.sequence`, por tienda — ver [La publicación más reciente gana](#la-publicación-más-reciente-gana) |
| Entidad | `_meta.triggerEntityId` es el UUID de la tienda (`data.store.uid`) |

> [!NOTE]
>
> Un flow limitado a ciertos canales recibe una publicación cuando toca **al menos uno** de ellos — y recibe el evento **completo**, con todos los canales. Elige los que son tuyos desde `data.channels`.

## Ejemplo — payload real (sanitizado y abreviado)

```json theme={null}
{
  "event": {
    "id": "5b0f3c9e-2d71-4a8e-9f14-6c3e2a7d8b10",
    "type": "store.updated",
    "emittedAt": "2026-10-27T02:40:46.985Z",
    "createdAt": "2026-10-27T02:40:47.402Z"
  },
  "data": {
    "store": {
      "uid": "a4019cad-bbac-4269-9f8d-f29654e92c45",
      "code": "BR-SP-001",
      "name": "Loja Centro - SP",
      "number": 2,
      "status": "PUBLISHED",
      "active": true,
      "phone": "+5511999990000",
      "email": "loja.centro@example.com",
      "address": "Av. Exemplo 1000, Centro, São Paulo - SP",
      "externalId": "200400500",
      "vendor": { "uid": "100.2.1", "name": "Sandbox Brand", "description": null, "loyaltyPlan": false },
      "account": { "uid": "100", "name": "Sandbox", "description": null },
      "locationInfo": {
        "city":     { "uid": "1", "code": "SAO", "name": "São Paulo" },
        "country":  { "uid": "6", "code": "BR",  "name": "Brasil", "phoneCode": "+55" },
        "location": { "lat": "-23.5632", "lon": "-46.6543" },
        "timezone": "America/Sao_Paulo",
        "currencyCode": "BRL"
      },
      "storeFiscalConfig": {
        "enabled": true,
        "company": { "govIdType": "CNPJ", "govIdNumber": "00000000000000", "legalName": "Sandbox LTDA", "tradeName": "Sandbox" },
        "govIdType": "CNPJ",
        "govIdNumber": "00000000000000",
        "secondaryGovIdType": "INSCRICAO_ESTADUAL",
        "secondaryGovIdNumber": "000000000000",
        "metadata": { "neverstop": { "url": "", "enabled": false }, "storeCode3S": "50000001", "serialNumber": 1 }
      },
      "metadata": {
        "taxesInfo": { "taxRate": 4, "vatRatePercentage": 4 },
        "deliveryInfo": { "cookTime": 15, "minimumOrder": 1, "shippingCost": 1 }
      }
    },
    "channels": [
      {
        "code": "KIOSK",
        "enabled": true,
        "published": true,
        "fulfillmentTypes": [
          {
            "code": "DINE_IN",
            "enabled": true,
            "schedules": [
              { "day": "MONDAY",    "startTime": "09:00", "endTime": "22:30" },
              { "day": "TUESDAY",   "startTime": "09:00", "endTime": "22:30" },
              { "day": "WEDNESDAY", "startTime": "09:00", "endTime": "22:30" },
              { "day": "THURSDAY",  "startTime": "09:00", "endTime": "22:30" },
              { "day": "FRIDAY",    "startTime": "09:00", "endTime": "22:30" },
              { "day": "SATURDAY",  "startTime": "09:00", "endTime": "22:30" },
              { "day": "SUNDAY",    "startTime": "09:00", "endTime": "22:30" }
            ]
          },
          {
            "code": "TAKEAWAY",
            "enabled": true,
            "schedules": [ /* los mismos 7 días */ ]
          }
        ]
      },
      {
        "code": "POS",
        "enabled": true,
        "published": true,
        "fulfillmentTypes": [
          { "code": "DINE_IN",  "enabled": true, "schedules": [ /* los mismos 7 días */ ] },
          { "code": "TAKEAWAY", "enabled": true, "schedules": [ /* los mismos 7 días */ ] }
        ]
      },
      {
        "code": "IFOOD",
        "enabled": false,
        "published": false,
        "fulfillmentTypes": [
          { "code": "DELIVERY", "enabled": false, "schedules": [ /* los mismos 7 días */ ] }
        ]
      }
    ],
    "operationSchedule": [
      { "day": "MONDAY",    "startTime": "07:00", "endTime": "23:00" },
      { "day": "TUESDAY",   "startTime": "07:00", "endTime": "23:00" },
      { "day": "WEDNESDAY", "startTime": "07:00", "endTime": "23:00" },
      { "day": "THURSDAY",  "startTime": "07:00", "endTime": "23:00" },
      { "day": "FRIDAY",    "startTime": "07:00", "endTime": "23:00" },
      { "day": "SATURDAY",  "startTime": "07:00", "endTime": "23:00" },
      { "day": "SUNDAY",    "startTime": "07:00", "endTime": "23:00" }
    ],
    "salesSchedule": [
      { "day": "MONDAY",    "startTime": "09:00", "endTime": "22:30" },
      { "day": "TUESDAY",   "startTime": "09:00", "endTime": "22:30" },
      { "day": "WEDNESDAY", "startTime": "09:00", "endTime": "22:30" },
      { "day": "THURSDAY",  "startTime": "09:00", "endTime": "22:30" },
      { "day": "FRIDAY",    "startTime": "09:00", "endTime": "22:30" },
      { "day": "SATURDAY",  "startTime": "09:00", "endTime": "22:30" },
      { "day": "SUNDAY",    "startTime": "09:00", "endTime": "22:30" }
    ],
    "publication": {
      "id": "0fc14118-15e2-4964-8ae6-970dd801b836",
      "sequence": 2,
      "mode": "now",
      "reason": "resync",
      "channels": ["KIOSK", "POS"],
      "scheduledAt": null,
      "requestedBy": { "id": "7b1e4c2a-0d3f-4a5b-8c6d-9e0f1a2b3c4d", "name": "Ana Souza" }
    }
  },
  "_meta": {
    "executionId": "5b0f3c9e-2d71-4a8e-9f14-6c3e2a7d8b10",
    "flowId": "9a2b3c4d-7e8f-4a1b-9c2d-3e4f5a6b7c8d",
    "flowName": "Store sync",
    "attempt": "1",
    "triggerEntityId": "a4019cad-bbac-4269-9f8d-f29654e92c45"
  }
}
```

## Referencia de `data.*`

### `data.store`

**store** `object`

El **mismo bloque de tienda V4** que viaja en los eventos de orden — `uid`, `code`, `name`, `phone`, `email`, `address`, `externalId`, `vendor`, `account`, `locationInfo` (con `country.phoneCode`), `metadata` y `storeFiscalConfig` (puede ser `null`). Referencia de campos en [`order.completed` → `data.store`](https://docs.fire.rest/es/events/order-completed#data-store). `phone` viene en formato internacional (`+` y dígitos, p. ej. `+5511999990000`). Puede traer un número que no es real (por ejemplo, solo ceros) si la tienda no tiene teléfono cargado, o el valor tal como se guardó si el país no tiene código telefónico. `metadata` es la configuración **llave-valor libre** de la tienda: Fire no impone sus llaves, algunas integraciones leen llaves conocidas (en el ejemplo, `taxesInfo` y `deliveryInfo`), y es `{}` cuando la tienda no tiene ninguna. Sobre ese bloque, este evento agrega:

**campos que agrega store.updated**

**number** `integer | null`

El número correlativo de la tienda en Fire. `null` cuando no se conoce.

**status** `string`

Estado de publicación de la tienda: `DRAFT`, `PUBLISHED`, `PARTIALLY_PUBLISHED` o `ARCHIVED`.

**active** `boolean`

Si la tienda está activa. Siempre `false` cuando está archivada.

### `data.channels`

**channels** `array`

**Todos** los canales configurados en la tienda — no solo los de esta publicación (esos están en `publication.channels`). Un canal o tipo de servicio apagado viaja igual, con `enabled: false`: así te enteras de que se dio de baja.

**channels\[]**

**code** `string`

Código del canal, escrito como está configurado en Fire (`KIOSK`, `POS`, `iFood`, `99`, …). Compara sin asumir mayúsculas o minúsculas.

**enabled** `boolean`

Si el canal está habilitado en la tienda.

**published** `boolean`

Si el canal está entre los canales publicados de la tienda.

**fulfillmentTypes** `array`

Los tipos de servicio del canal.

**fulfillmentTypes\[]**

**code** `string`

Código del tipo de servicio (`DELIVERY`, `TAKEAWAY`, `DINE_IN`, …).

**enabled** `boolean`

Si el tipo de servicio está habilitado en este canal.

**schedules** `array`

El horario **efectivo**, ya resuelto: el horario propio del tipo de servicio; si no tiene, el del canal; si el canal tampoco tiene, el `salesSchedule` de la tienda. Cada entrada es `{ day, startTime, endTime }`, con la misma forma que abajo. No necesitas aplicar la herencia tú.

### `data.operationSchedule` y `data.salesSchedule`

**operationSchedule** `array`

El horario de operación de la tienda. Cada entrada: `day` (`MONDAY` … `SUNDAY`), `startTime` y `endTime` (`HH:mm`).

**salesSchedule** `array`

El horario de venta de la tienda, con la misma forma. Es el respaldo de los canales y tipos de servicio sin horario propio — ya aplicado en `channels[].fulfillmentTypes[].schedules`.

### `data.publication`

**publication** `object`

La publicación que produjo este evento.

**publication**

**id** `string`

UUID de la publicación. El mismo en cada entrega y en cada flow que la recibe — úsalo para reconocer una publicación que ya aplicaste.

**sequence** `integer`

Contador por tienda: sube en uno con cada publicación emitida de esa tienda. La mayor es la más nueva. Ver [La publicación más reciente gana](#la-publicación-más-reciente-gana).

**mode** `string`

`now` (publicada en el momento) o `scheduled` (disparada por una programación). Pueden aparecer valores nuevos; trátalos como una publicación normal.

**reason** `string`

Qué produjo la publicación: `publish`, `draft`, `resync`, `channel_toggle`, `override_apply`, `override_revert` o `archive`. Pueden aparecer valores nuevos (p. ej. `retry`); trátalos como una publicación normal. Ver [Condición de disparo](#condición-de-disparo).

**channels** `string[]`

Los códigos de canal de los que trata esta publicación: los elegidos al publicar, todos los canales habilitados en una re-sincronización, el canal que se prendió o apagó en un `channel_toggle`, el canal puntual en una re-sincronización de un solo canal, todos los canales habilitados en un `override_apply` u `override_revert`, y al archivar, los canales publicados más los habilitados.

**scheduledAt** `string | null`

Hora ISO 8601 UTC para la que se programó la publicación. `null` cuando `mode` es `now`.

**requestedBy** `object`

`{ id, name }` — quién la pidió. Cualquiera de los dos puede ser `null`; las ejecuciones automáticas pueden llegar con `id: null` y `name: "CRON"`.

## La publicación más reciente gana

Cada evento trae la tienda **completa**, así que la publicación más reciente reemplaza todo lo anterior. Fire ya se ocupa del orden por ti:

* Dentro de un flow, las publicaciones de **una misma tienda** se entregan de a una, en el orden en que se emitieron. Las tiendas distintas avanzan en paralelo.
* Cuando una tienda tiene una publicación nueva que cubre los mismos canales, las entregas anteriores que todavía esperaban se cancelan; las demás salen igual, en orden.

`publication.sequence` sigue siendo un dato útil: puedes guardar la última que aplicaste por tienda y reconocer un payload viejo si alguna vez te llega — por ejemplo, una reejecución manual de una entrega vieja, que conserva su `sequence` original.

## Archivar

Archivar una tienda emite un `store.updated` con `publication.reason: "archive"`. Trae la tienda archivada: `store.status: "ARCHIVED"`, `store.active: false`, y **todos** los canales y tipos de servicio con `enabled: false` (y los canales con `published: false`). Si quieres tratar el archivado aparte, ramifica por `reason` o por `status`.

> [!NOTE]
>
> Integration Flows no emite un evento `store.deleted` aparte: archivar es un `store.updated`.

## Handler de ejemplo

```js theme={null}
async function onStoreUpdated(data) {
  const { store, channels, publication } = data;

  // 1. ¿Ya aplicamos esta publicación? (mismo id en cada entrega)
  if (await db.storePublications.exists(publication.id)) return;

  // 2. Opcional: guardar la sequence para reconocer un payload viejo
  const last = await db.stores.lastSequence(store.uid);
  if (last != null && publication.sequence < last) return;

  // 3. Reemplazo total — el evento trae la tienda completa
  const mine = channels.filter((c) => MY_CHANNELS.includes(c.code.toUpperCase()));
  await db.stores.replace(store.uid, {
    code: store.code,
    name: store.name,
    active: store.active,
    archived: store.status === "ARCHIVED",
    metadata: store.metadata,
    channels: mine,
    sequence: publication.sequence,
  });
  await db.storePublications.add(publication.id);
}
```

## Errores comunes

* **No es un diff.** Un canal que falta en tu copia no está "sin cambios" — el evento lista todos los canales. Reemplaza, no combines.
* **Un canal apagado viaja igual.** Lee `enabled`; no asumas que un canal presente en el evento está abierto.
* **`publication.channels` no es la lista de canales.** Dice de qué trató esta publicación; los canales de la tienda están en `data.channels`.
* **No deduplices por `event.id`.** Identifica la entrega; la publicación es `data.publication.id`.
* **Los códigos de canal conservan las mayúsculas con que se configuraron** (`iFood`, `KIOSK`). Normaliza antes de comparar.

## Eventos relacionados

> **[store.business\_day\_closed](https://docs.fire.rest/es/events/store-day-closed.md)**
>
> El otro evento a nivel de tienda: una tienda cerró su día de negocio.

> **[order.completed](https://docs.fire.rest/es/events/order-completed.md)**
>
> Referencia de campos del bloque `store` V4 que comparte este evento.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.