Status do pedido do agregador
API
Status do pedido do agregador
Endpoint de entrada para o qual seu agregador de delivery (Rappi / Uber / Didi / iFood …) faz POST conforme move um pedido pelo seu ciclo de vida de entrega. O Fire espelha o status no pedido e registra o evento. O status é passthrough — os rótulos do próprio agregador, armazenados literalmente.
POST
Status do pedido do agregador
Este endpoint é de entrada — seu agregador de delivery (Rappi, Uber, Didi, iFood, PedidosYa, Glovo…) faz POST nele sempre que avança o pedido do seu lado: um entregador foi designado, o pedido foi retirado, está a caminho, foi entregue, e assim por diante. O Fire autentica a requisição, correlaciona o pedido, espelha o status mais recente em
Ambos são vendor-scoped: o pedido resolvido deve pertencer à conta + vendor vinculados à sua API key, e seu canal deve coincidir com
Um
O status cru é armazenado como está; qualquer rótulo amigável e traduzido é resolvido no momento da exibição a partir do catálogo de status do canal — o valor armazenado nunca muda.
orders.aggregator e registra o evento no seu log de eventos de agregador para observabilidade.
Este endpoint é assíncrono. O Fire autentica, correlaciona o pedido (guards de tenant + canal), deduplica e enfileira o evento — então responde
202 Accepted com um webhookEventId (tipicamente em menos de 100 ms). O espelho do pedido é atualizado um instante depois por um worker em segundo plano (normalmente em ~2 segundos). Para verificar o resultado, consulte GET /v1/webhooks/events/{webhookEventId}. Problemas corrigíveis pelo cliente (payload inválido, pedido não encontrado, tenant ou canal errado, ids conflitantes) são rejeitados sincronamente com 4xx antes do 202.O status é passthrough. Os agregadores não compartilham um vocabulário de status, então o Fire não impõe um enum:
status é armazenado literalmente como o tipo de evento (courier_assigned, on_route, entregue, o que quer que seu canal use). O status atual do pedido é o que tem o occurredAt mais recente — não uma ordem fixa de ciclo de vida. Não há guard anti-regressão: um timestamp mais recente vence, ponto. Rótulos amigáveis e traduzidos são uma questão de exibição resolvida a partir do catálogo do canal, nunca imposta aqui.Não há
eventId emitido pelo Fire para ecoar. Diferente do callback fiscal e dos status KDS — que ecoam um event.id que o Fire emitiu — um status de agregador é um evento externo espontâneo. O Fire não é a fonte da verdade aqui, então não há verificação de fonte da verdade sobre um eventId. Em vez disso, você diz ao Fire a qual pedido o status pertence, via resolução do pedido abaixo. A idempotência é chaveada no seu providerEventId (veja Idempotência e a jornada).Resolução do pedido
Você precisa dizer ao Fire a qual pedido este status pertence. Há dois caminhos, e você pode enviar um ou ambos — ao menos um é obrigatório:| Campo | Resolve por | Quando usar |
|---|---|---|
orderId | Nosso orders.id (UUID) | Você guardou o id do pedido do Fire (ex. ecoado de um evento outbound ou da resposta de injeção) |
externalOrderId | O id externo (XMART/agregador) do pedido, casado contra o metadata.order_id do pedido | Você só conhece a sua própria referência do pedido |
channelCode.
Autenticação
Este endpoint requer uma API key vendor-scoped com o escopowebhooks:aggregator (binding de conta + vendor). O Fire valida que o pedido resolvido pertença a esse vendor. Keys sem o escopo, ou sem binding de vendor, são rejeitadas com 403 Forbidden.
Sua API key vendor-scoped do Fire com escopo
webhooks:aggregator. Gere uma em Developers → Gestão de API para a conta/vendor cujos pedidos esta key pode reportar.Bearer <token> opcional — aceito como alternativa legada ao x-api-key. Envie um ou outro.Corpo da requisição
O código do agregador/canal — ele deve ser igual ao
metadata.channel.code do pedido (channels.code, ex. RAPPI, UBER, ou o id numérico do canal como 99). Se não coincidir com o canal do pedido resolvido, o Fire responde 403.O status de entrega cru, passthrough — armazenado literalmente como o tipo de evento. Qualquer string não vazia é aceita (
accepted, courier_assigned, picked_up, on_route, delivered, cancelled, ou os rótulos do seu próprio canal). Nenhum enum é imposto.O id próprio do seu agregador para esta entrega — a chave de idempotência (junto com
channelCode). O Fire mapeia (channelCode, providerEventId) para um id de evento interno estável, então reenviar o mesmo par com o mesmo status é um replay seguro. Use seu id de evento nativo se tiver; senão, um UUID.Timestamp ISO 8601 UTC de quando o status mudou do lado do agregador — não quando foi enviado. É isto que ordena a jornada: o status com o
occurredAt mais recente é o status atual do pedido.UUID do pedido no Fire. Obrigatório se
externalOrderId estiver ausente. Veja Resolução do pedido.O id externo (XMART/agregador) do pedido, casado contra o
metadata.order_id do pedido. Obrigatório se orderId estiver ausente. Veja Resolução do pedido.Saco livre opcional de campos extras (nome do entregador, url de rastreamento, etc.). Armazenado como está, sem validação.
Exemplos
Os reportes da mesma entrega compartilham umchannelCode e resolvem para o mesmo pedido; cada um carrega seu próprio status, providerEventId e occurredAt:
courier_assigned (pelo orderId do Fire)
on_route (pelo id externo do pedido)
delivered (ambos os ids — devem apontar para o mesmo pedido)
Resposta
Em caso de sucesso o endpoint responde202 Accepted — o evento foi autenticado, correlacionado, deduplicado e enfileirado. Um 202 não significa que o espelho do pedido já foi atualizado; isso acontece de forma assíncrona. Use o endpoint de status para confirmar.
O body traz dois ids distintos: eventId é o id interno estável do Fire para este par (channelCode, providerEventId), webhookEventId é o id do Fire para o registro enfileirado. Mesma forma que o callback fiscal.
Sempre
true quando a requisição foi aceita e enfileirada.true quando este reporte de status exato já foi ingerido (mesmo pedido, mesmo (channelCode, providerEventId), mesmo status) — o registro existente é retornado e nada é re-enfileirado. false para um reporte novo (incluindo um status diferente da mesma entrega — isso é um passo novo, não uma duplicata).O id interno estável do Fire derivado de
(channelCode, providerEventId).O id do Fire para o registro enfileirado. Passe-o para
GET /v1/webhooks/events/{webhookEventId} para consultar o resultado. Em uma duplicata é o mesmo id retornado na primeira vez.Status atual na fila —
queued → processing → processed (e retry / failed / dead / ignored).Timestamp ISO 8601 UTC de quando o Fire recebeu pela primeira vez este reporte. Estável entre retentativas.
Resumo legível.
Verificar o resultado
Como o processamento é assíncrono, o202 apenas confirma que o evento foi enfileirado. Para ver se o espelho do pedido foi atualizado, consulte o endpoint de status com o webhookEventId retornado pelo 202:
Ciclo de vida da fila:
queued → processing → processed (concluído) · failed / dead (desistiu após retentativas) · retry (aguardando a próxima tentativa) · ignored (tratado, sem ação — ex. um duplicado).Tentativas de processamento até agora.
Em caso de sucesso, o resultado do worker — ex.
{ "kind": "merged", "current": "delivered" }.{ "message": "…" } quando a última tentativa falhou; null caso contrário.404 é retornado para ids desconhecidos — ou ids de outro tenant — sem vazar existência. Autentique com a mesma key webhooks:aggregator que usou para o evento.
Idempotência e a jornada
O Fire deduplica pelo pedido mais(channelCode, providerEventId) e o status — não por um eventId emitido pelo Fire. É isso que faz a jornada funcionar mantendo as retentativas limpas:
| Cenário | Resultado |
|---|---|
courier_assigned, depois on_route, depois delivered — status diferente (e providerEventId), mesmo pedido | cada um é um passo novo → 202 duplicate:false |
O mesmo reporte reenviado — mesmo pedido, mesmo (channelCode, providerEventId), mesmo status | 202 duplicate:true — registro existente retornado, não reprocessado |
Nem orderId nem externalOrderId enviados | 400 |
| Pedido não encontrado para este vendor | 404 |
orderId e externalOrderId resolvem para pedidos diferentes | 409 |
channelCode ≠ o canal do pedido, ou key não é deste vendor | 403 |
| Auth store momentaneamente inacessível | 503 — transitório, retente |
Um
status diferente nunca é uma duplicata. Como os agregadores legitimamente reportam muitos status para uma entrega, dois reportes com o mesmo (channelCode, providerEventId) mas um status diferente são dois passos distintos — o Fire armazena ambos. Mantenha providerEventId único por reporte de status para evitar reproduzir um passo acidentalmente.O espelho do pedido
Uma vez processado, o status mais recente é espelhado no blocoaggregator do pedido, com a jornada completa mantida em history (ordenada por occurredAt). O status atual é a entrada com o occurredAt mais recente:
orders.aggregator
Relacionado
Injetar pedido
O endpoint de injeção que cria o pedido que este status referencia.
Status do pedido KDS
O webhook de entrada irmão para o estado da cozinha — mesmo modelo async + fila, mas com
eventId emitido pelo Fire e anti-regressão.Callback fiscal
O webhook fiscal de entrada — mesmo envelope async + idempotência.
Autenticação
Como funcionam as API keys, escopos e o binding de vendor.

