Skip to main content

Modelo geral

Setup inicial

Primeiro pull: sem updated_since. Retorna todos os pedidos em status ativo.

Loop periódico (a cada 5 min)

Roteador por status

Processar pedido aprovado

Registrar rastreio (evento separado)

Quando o pacote for postado, dispare o POST /rastreio — não faz sentido embutir no loop de pull (só saberá que postou no evento local, não pelo pull).

Cancelamento (integrador reagindo)

Se você recebe pedido.status === "cancelado" e o pedido estava na sua base (você já processou):

Idempotência: casos de replay

Como o updated_since > cursor é filtro rígido, você nunca deveria receber o mesmo pedido duas vezes num pull normal. Mas atenção a:
  • Race condition: se o pedido é atualizado exatamente no momento do pull, ele pode ficar de fora (será pego no próximo tick). Não é bug, é natureza do cursor.
  • Reset de cursor: se você perder o cursor local e reprocessar tudo, use hunter_processado_em pra pular pedidos já processados. Chamar POST /processado num pedido já processado retorna 409 CONFLICT — trate como sinal “OK, já foi”.

Erros e retentativas

  • 5xx no GET /pedidos — backoff, retente. Cursor não avançou, você não perde nada.
  • 429 — aguarde Retry-After.
  • 5xx no POST /processado — investigue via GET /pedidos?updated_since=<cursor_anterior> se o pedido apareceu com hunter_processado_em preenchido. Se sim, foi um retry silencioso — siga.
  • 409 no POST /processado — já processou; loga como aviso e segue.
  • 409 no POST /rastreio — pedido saiu de em_separacao/enviado (foi entregue ou cancelado); loga e siga (rastreio já não faz sentido).

Frequência sugerida

  • Loop de pull: a cada 5 minutos
  • POST /rastreio: evento disparado pelo WMS (não é loop)
  • POST /processado: dentro do loop de pull, imediato após emitir NF
Se seu volume é baixo (< 100 pedidos/dia), pode espaçar pra 15 min. Se é alto (> 10k pedidos/dia), reduza pra 1 min mas cuide do rate limit.