Modelo geral
Setup inicial
Primeiro pull: semupdated_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 oPOST /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ê recebepedido.status === "cancelado" e o pedido estava na sua base (você já processou):
Idempotência: casos de replay
Como oupdated_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_empra pular pedidos já processados. ChamarPOST /processadonum pedido já processado retorna409 CONFLICT— trate como sinal “OK, já foi”.
Erros e retentativas
5xxnoGET /pedidos— backoff, retente. Cursor não avançou, você não perde nada.429— aguardeRetry-After.5xxnoPOST /processado— investigue viaGET /pedidos?updated_since=<cursor_anterior>se o pedido apareceu comhunter_processado_empreenchido. Se sim, foi um retry silencioso — siga.409noPOST /processado— já processou; loga como aviso e segue.409noPOST /rastreio— pedido saiu deem_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