Evento `ORDER_DELAY`

Webhook disparado quando um pedido atrasa — ou quando entra em risco de atrasar. Vale para qualquer pedido com prazo de cliente, e o payload diz qual dos dois casos disparou.

Evento enviado ao seller quando um pedido fura o prazo prometido ao cliente — ou quando entra em risco de furar, se você configurou marcadores de risco. Vale para qualquer pedido que tenha prazo de cliente, com ou sem marcador.

O disparo é agendado no momento em que o pedido nasce, a partir do prazo informado na criação, e acontece no instante exato desse prazo (ou da antecedência da regra de risco). Nesse instante a Abbiamo revalida o pedido: se ele já foi entregue, cancelado, baixado manualmente ou devolvido, nada é enviado.

Para assinar, crie um webhook em Configurações → Webhooks apontando para o seu endpoint e selecione o evento ORDER_DELAY.

Os dois gatilhos

O campo trigger diz por que o evento chegou. Ele é a primeira coisa que o seu consumidor deve olhar.

triggerQuando disparaO que vem no payload
DELAYEDO prazo prometido ao cliente estourou e o pedido não foi concluídooverdue: true, risk_marker: null, rule_id: null
RISK_MARKERUma regra de risco que você configurou acendeu um marcador antes do prazorisk_marker preenchido, rule_id preenchido, overdue normalmente false

DELAYED é automático e vale para todo pedido com prazo de cliente — não precisa configurar nada. RISK_MARKER só existe se você criou regras em Configuração → Marcadores de risco de entrega.

Um mesmo pedido pode gerar os dois: primeiro o RISK_MARKER (faltando 30 min), depois o DELAYED (quando o prazo estourou de fato).

Este evento não é uma mudança de status. O pedido continua no status em que estava — o campo status vem só como contexto do momento do disparo. Se você já trata ORDER_STATUS_CHANGE, trate este num caminho separado.

Duas datas diferentes, não confunda. Este evento usa o promised_delivery_date — o prazo que você prometeu ao cliente final e nos enviou em POST /v2/order. Não é o expected_delivery_date do ORDER_STATUS_CHANGE, que é o prazo combinado com a transportadora. O ORDER_DELAY mede o compromisso com o cliente, não com o parceiro logístico.

Estrutura base

A cada disparo, a Abbiamo faz um POST no seu endpoint com este corpo:

{
  "event_type": "ORDER_DELAY",
  "trigger": "DELAYED",
  "order_id": "3f9a1c22-0000-0000-0000-000000000000",
  "order_number": "1042",
  "invoice_number": "000123456",
  "external_order_id": "PED-98213",
  "tracking": "AB12CD34EF",
  "seller_id": "8c1e4b70-0000-0000-0000-000000000000",
  "seller_group_id": "b7d2f011-0000-0000-0000-000000000000",
  "seller_identifier": "loja-centro",
  "order_type": "DELIVERY",
  "status": "START_DELIVERY",
  "sub_status": null,
  "delivery_type": "BEE",
  "promised_delivery_date": "2026-07-27T21:00:00.000Z",
  "threshold_minutes": 0,
  "minutes_to_deadline": 0,
  "overdue": true,
  "risk_marker": null,
  "rule_id": null,
  "event_at": "2026-07-27T21:00:03.482Z",
  "timestamp": 1785186003482
}

Glossário de campos

CampoTipoNotas
event_typestringsempre "ORDER_DELAY"
trigger"DELAYED" | "RISK_MARKER"por que o evento chegou — veja a tabela acima
order_idstring (uuid)identificador do pedido na Abbiamo
order_numberstringnúmero do pedido no painel
invoice_numberstring | nullnúmero da nota fiscal
external_order_idstring | nullseu identificador, enviado na criação
trackingstringcódigo de rastreio público
seller_idstring (uuid)filial dona do pedido
seller_group_idstring (uuid)marca (seller group)
seller_identifierstring | nullidentificador externo da filial
order_typestringDELIVERY, TAKEOUT, RETURN
statusstringstatus do pedido no momento do disparo (contexto, não mudança)
sub_statusstring | nullsub-status correspondente
delivery_typestring | nulltransportadora atribuída, ou null se ainda não despachado. Mesmo vocabulário do delivery_type do ORDER_STATUS_CHANGE
promised_delivery_dateISO datetimeprazo prometido ao cliente que serviu de âncora — o mesmo valor que você enviou em POST /v2/order
threshold_minutesnumberantecedência da regra; sempre 0 quando trigger = "DELAYED"
minutes_to_deadlinenumberminutos restantes até o prazo; negativo se já estourou
overduebooleantrue quando o prazo já passou no momento do disparo
risk_markerobjeto | nullnull quando trigger = "DELAYED"
risk_marker.idstring (uuid)marcador de risco aplicado
risk_marker.namestringnome que você deu ao marcador (ex.: "Risco de Entrega Grave")
risk_marker.colorstringcor em hexadecimal, a mesma exibida no painel
rule_idstring (uuid) | nullregra de risco que originou o disparo; null quando trigger = "DELAYED"
event_atISO datetimedata/hora do disparo
timestampnumbermesmo instante em epoch (ms)

Garantias de entrega

Leia esta seção antes de escrever o consumidor — as garantias aqui são diferentes das do ORDER_STATUS_CHANGE.

  • Entrega é at-least-once: deduplique do seu lado. O normal é chegar um evento por gatilho, mas uma repetição é possível. Trate order_id + trigger (+ risk_marker.id, quando houver) como chave e ignore o que já processou — é a única garantia da qual vale depender.
  • Um RISK_MARKER por par (pedido, marcador). Se duas regras acendem o mesmo marcador no mesmo pedido, chega um evento — o da primeira que vencer. Regras que acendem marcadores diferentes geram eventos distintos.
  • Nada é enviado para pedido já concluído. No instante do disparo o pedido é revalidado: SUCCESSFUL, CANCELED, MANUAL_HANDLE (baixa manual) e RETURNED cancelam o envio silenciosamente.
  • Prazo em branco não dispara. Pedido sem promised_delivery_date nunca gera ORDER_DELAY. O prazo é lido na criação do pedido — é ali que o disparo é agendado.
  • Retirada em loja fica de fora. Pedidos TAKEOUT não têm prazo de entrega ao cliente — é o mesmo recorte da coluna Situação de entrega, que mostra "Sem info" para eles.
  • Não há evento de "saiu do atraso". O disparo é de mão única; a conclusão você recebe pelo ORDER_STATUS_CHANGE com status: "SUCCESSFUL".
  • Retentativas: até 3 tentativas com timeout de 20s por chamada, igual aos demais webhooks. Todos os disparos ficam auditáveis em Configurações → Logs → Webhooks.

Exemplos

AtrasadoO prazo do cliente estourou e o pedido segue em rotaver detalhes →
{
  "event_type": "ORDER_DELAY",
  "trigger": "DELAYED",
  "status": "START_DELIVERY",
  "promised_delivery_date": "2026-07-27T21:00:00.000Z",
  "threshold_minutes": 0,
  "minutes_to_deadline": 0,
  "overdue": true,
  "risk_marker": null,
  "rule_id": null
}
Em riscoRegra de risco: faltam 30 min pro prazover detalhes →
{
  "event_type": "ORDER_DELAY",
  "trigger": "RISK_MARKER",
  "status": "START_DELIVERY",
  "promised_delivery_date": "2026-07-27T21:00:00.000Z",
  "threshold_minutes": 30,
  "minutes_to_deadline": 30,
  "overdue": false,
  "risk_marker": {
    "id": "d81f9a3c-0000-0000-0000-000000000000",
    "name": "Risco de Entrega Grave",
    "color": "#D92D20"
  },
  "rule_id": "0a55c7e2-0000-0000-0000-000000000000"
}
Nasceu atrasadoPedido criado com prazo já no passado — dispara na horaver detalhes →
{
  "event_type": "ORDER_DELAY",
  "trigger": "DELAYED",
  "status": "PENDING",
  "promised_delivery_date": "2026-07-27T18:00:00.000Z",
  "threshold_minutes": 0,
  "minutes_to_deadline": -45,
  "overdue": true,
  "risk_marker": null,
  "rule_id": null
}

Como consumir

O caso de uso mais direto é abrir um alerta interno (ticket, mensagem no canal do time, linha num painel) sem depender de alguém olhando a lista de Pedidos.

app.post('/abbiamo/webhook', (req, res) => {
  const e = req.body
  if (e.event_type !== 'ORDER_DELAY') return res.sendStatus(200)

  if (e.trigger === 'DELAYED') {
    abrirOcorrencia(e.order_id, `Pedido ${e.order_number} atrasou`)
  } else {
    avisarTime(e.order_id, `${e.order_number}: ${e.risk_marker.name}`)
  }

  res.sendStatus(200)
})

Sugestões práticas:

  • Ramifique sempre pelo trigger. Um RISK_MARKER é um aviso preventivo; um DELAYED é um fato consumado. Tratar os dois igual gera ruído no time.
  • Deduplique por order_id + trigger (+ risk_marker.id, quando houver). O mesmo pedido gera um RISK_MARKER e depois um DELAYED — são eventos distintos —, e a entrega é at-least-once.
  • minutes_to_deadline já vem calculado a partir do promised_delivery_date — não recalcule se o seu servidor estiver em outro fuso.
  • Combine com o ORDER_STATUS_CHANGE: ao receber SUCCESSFUL para um pedido que atrasou, feche o alerta.

Nesta página