Skip to main content
product.price_updated é um evento restrito — diferente de product.updated, transmite apenas preços. Os demais atributos do produto (nome, descrição, imagens, modificadores etc.) permanecem sem alteração. Suporta múltiplos produtos em um único evento. Quando a alteração afeta várias lojas, o Fire emite um único evento com todas as lojas afetadas listadas em targets. O preço de uma opção de modificador é contextual: pertence à combinação (produto pai × grupo × opção), não à opção como produto avulso — a mesma opção pode valer diferente sob dois pais. Por isso ele viaja onde já vive em menu.updated: em products[].productModifiers[].overrides[], aninhado sob o pai e delimitado pelo modifierId do grupo. Não existe um array separado.

Payload

Campos

data

data.targets[n]

Mesma estrutura que em product.updated — inclui vendorId e timezone.

data.targets[n].channels[n]

⚠️ listName neste evento é o nome do menu (ex.: Menu App), enquanto list.listName em menu.updated é um rótulo autogerado (IFOOD - Store 1350). Não são o mesmo valor e não servem para correlacionar — use listId, que é idêntico em ambos os eventos.

data.products[n]

Os quatro valores vêm do item do produto na lista de preços da combinação destino (a mesma identificada por listId), não de nenhuma lista padrão. products[] inclui o produto pai de cada opção com preço contextual, mesmo que o preço dele não tenha mudado: assim você sempre tem o contexto do produto de onde vem a alteração. Esse priceInfo é o preço vigente do pai, então aplicá-lo é um replace idempotente (você escreve o valor que ele já tem). Se duas opções editadas compartilham o mesmo pai, o pai aparece uma única vez. Um produto sem preço na lista destino é omitido. ⚠️ O preço base de uma opção NÃO viaja neste evento. Esta tela edita a camada contextual (o preço da opção sob um pai), nunca o preço próprio do produto-opção, então transmitir o base afirmaria um preço que não mudou — e como priceInfo é replace total, poderia sobrescrever o que você já tem. O base você tem do último menu.updated, onde a opção viaja como produto do tipo MODIFIER, e continua válido. Se o que foi editado é o preço próprio de um produto que também é opção em outro lugar, esse produto chega como entrada normal de products[]: é uma edição de produto, não de opção. ⚠️ Este priceInfo não tem os mesmos campos que o priceInfo de products[n] em menu.updated / product.updated ({pointPrice, price, referencePrice, suggestedPrice}). São deliberadamente diferentes: este evento transmite o preço de venda recém-salvo com seu desconto, não os preços de catálogo do produto.

data.products[n].productModifiers[n]

Mesmo vocabulário que products[n].productModifiers[n] de menu.updated. Quais grupos chegam e com quê:
  • Somente os grupos que têm algum preço contextual sob esse pai. Um grupo ausente significa “suas opções usam o preço base”, não “sem alteração”: os preços contextuais só são adicionados ou atualizados, nunca removidos, então a ausência sempre reflete o estado real.
  • Dos grupos que chegam, vem a totalidade de seus preços contextuais vigentes, não só os recém-editados. Assim você pode fazer merge por modifierId sem perder os que já tinha.
  • Diferente de menu.updated, o grupo não traz position: a ordem é estrutura e este evento só transmite preços. Mantenha a ordem que você já tem do menu.
A chave de um preço contextual é a tripla pai × modifierId × productId da opção. O aninhamento já a expressa: aplicar o preço buscando apenas pelo productId da opção é incorreto, porque a mesma opção pode aparecer sob vários pais, ou sob o mesmo grupo atribuído duas vezes ao mesmo pai (dois modifierId distintos), com preços diferentes em cada caso. Um override traz apenas price: um preço contextual de opção não tem preço com desconto nem sugerido próprios — esses conceitos existem apenas no nível do produto, em products[n].priceInfo.

Combos: chegam reconstruídos

Um COMBO não tem preço próprio: seu valor é derivado das opções de seus grupos obrigatórios. Por isso ele é emitido igual a menu.updatedprice: 0 e o valor real em referencePrice:
referencePrice = para cada grupo com minOptions ≥ 1, minOptions × (menor preço efetivo entre suas opções), somado entre todos esses grupos. Grupos opcionais (minOptions = 0) não contribuem.
minOptions não viaja neste evento — é um campo de data.menu.modifierGroups[n] em menu.updated, correlacionado por modifierId. Para recalcular referencePrice você precisa dos dois eventos: este te dá os preços contextuais vigentes, menu.updated te dá quais grupos são obrigatórios. Como alterar uma única opção move esse valor, quando o preço de uma opção de um combo é editado, o evento traz, de todos os grupos com preço contextual vigente sob este pai — não só o grupo editado —, a totalidade de seus overrides, para que você possa recalcular a referência por conta própria e validá-la contra a que enviamos. Assim como em qualquer produto, um grupo obrigatório sem nenhum override vigente não aparece neste evento (ver “Quais grupos chegam e com quê”); para seu mínimo use o preço base dessas opções em menu.updated. Opções sem preço resolúvel não participam do cálculo do mínimo.

Exemplo

Nenhum grupo traz position. Cruzando modifierId com minOptions de menu.updated: ⚠️ Se este combo tivesse também um grupo obrigatório cujas opções mantivessem todas o preço base (sem nenhum override), esse grupo não apareceria em productModifiers[] — não significa que foi removido, apenas que não há preço contextual a informar. Seu mínimo vem das opções desse modifierId em menu.updated. ⚠️ Um grupo ter overrides não implica que seja obrigatório: 7c2f9d4e83a1b650 traz preços contextuais para suas opções (são add-ons reais, com preço próprio) mas, por ser opcional (minOptions = 0), não participa da soma. Em um produto normal, as opções são add-ons e não alteram o preço do pai: o pai mantém seu price de lista e não traz referencePrice.

Comportamento

Este evento só altera preços. Nome, descrição, imagens, modificadores, impostos e demais atributos permanecem sem alteração.
  • Para products[n], o objeto priceInfo recebido substitui totalmente o existente para aquele productId — não é um merge campo a campo.
  • Para productModifiers[n].overrides[n], price substitui o preço contextual dessa opção somente sob este pai e este modifierId. As demais ocorrências da mesma opção não são tocadas.
  • Um array vazio ou ausente significa “nada a mudar aqui”, não “apagar tudo”.
  • Um produto aparecer em products[] não implica que seu preço mudou: ele pode estar ali como pai de uma opção (ver data.products[n]). O replace é idempotente nesse caso.
Uma alteração de preço não altera a data de atribuição ao menu do produto (additionalInfo.assignedAt): esse valor é de pertencimento, não de edição. Por isso este evento não o transmite — o assignedAt que você já tem registrado para esse produto continua válido. Ele chega em product.updated e em menu.updated.

Uso

Consulte o guia Publicação de produto para o fluxo completo de processamento.