Um cliente 3PL em Fontana fechou novembro e descobriu que seu gasto de frete de outubro estava quase $4,000 acima do plano. Levou duas semanas para encontrar a causa: 45 dias antes, a transportadora havia mudado silenciosamente suas regras de sobretaxa de área remota. Ninguém atualizou o TMS, o motor de tarifação do WMS continuava cotando com as regras antigas, e a fatura chegou 45 dias atrasada. O frete se moveu bem. O dinheiro vazou em silêncio.

Esse incidente mudou a forma como examino cada projeto WMS-TMS. Primeiro verifico o caminho dos callbacks, não o push para fora. Qualquer um pode empurrar um embarque para um TMS. Tudo quebra no caminho de volta.

A cadeia em si é simples: o WMS envia os dados do embarque para o TMS ou a transportadora, a transportadora coleta, transporta e entrega, e as atualizações de status e as faturas sobem pela cadeia. Os três pontos de falha moram nessas viagens de retorno.

O callback morreu, e o pedido fica "em trânsito" para sempre

A cena clássica: o pacote foi entregue há dois dias, o cliente liga pedindo o comprovante de entrega, e o atendente olha no WMS — ainda "em trânsito". O webhook do TMS nunca disparou, ou o POD da transportadora nunca voltou. O pedido fica travado, o estoque continua alocado, e no fim do mês há uma pilha de registros "enviados" flutuando no limbo enquanto o financeiro os concilia à mão, um número de rastreio de cada vez.

A causa raiz quase sempre é uma máquina de estados desenhada de forma muito grosseira. A maioria das integrações modela dois estados — enviado e concluído — e mapeia cada status do TMS (em trânsito, em entrega, entregue) para "concluído". As exceções (devolvido, cancelado, danificado) nem sequer têm seu próprio canal de callback. O que uso agora: o estado do embarque no WMS é dividido em pelo menos cinco — enviado, coletado, em trânsito, entregue e exceção. Cada código de status do TMS tem um mapeamento explícito, e tudo que não se encaixa vai para um pool de exceções para revisão humana.

Minha tabela de mapeamento é assim: TMS picked_up e departed mapeiam para coletado; in_transit, arrived_at_hub e out_for_delivery mapeiam para em trânsito; delivered mapeia para entregue; exception, returned_to_sender, voided, damaged e lost vão todos para o pool de exceções — nunca podem fluir automaticamente para entregue. Essa última linha é a linha vermelha. Uma vez que uma exceção é etiquetada erroneamente como entregue, atendimento ao cliente, financeiro e estoque estão todos errados ao mesmo tempo, e desembaraçar isso custa três vezes mais trabalho.

Depois adicione cinto e suspensórios: webhooks para tempo real, mais um pull programado como backup. O job de backup roda a cada hora e consulta ativamente o TMS por qualquer coisa travada "em trânsito" há mais de 24 horas. É um pequeno pedaço de código e o patch de maior ROI que conheço neste espaço. Mais um monitor: alerta se o receptor de webhooks passar 30 minutos com zero callbacks. Cadeias de callback morrem em silêncio. Ninguém olhando significa três dias de silêncio.

A fatura chega atrasada com campos que não batem, e o fim do mês desvia por milhares

As faturas das transportadoras chegam rotineiramente de 30 a 45 dias depois dos fatos, e as tabelas de sobretaxa de combustível e as regras de área remota mudam sem cerimônia. Quando a estimativa do WMS não bate com a fatura, o financeiro sempre assume primeiro que o WMS está errado. Na maioria das vezes, uma versão de regra nunca foi sincronizada.

Primeiro crave a checklist de mapeamento de campos. Esta é a base contra a qual todo o resto se concilia:

Campo WMS Campo da fatura TMS / transportadora Notas
Shipment ID tracking number / PRO number A chave única em toda a cadeia, a chave primária da conciliação
Billed weight billed weight Cuidado com a regra do maior entre peso real e dimensional
Destination zone zone Guarde versões quando as tabelas de zona mudarem
Service level service level ground / 2-day / overnight, etc.
Fuel surcharge fuel surcharge Iguale a versão da tarifa com a data da fatura
Accessorial detail accessorial charges Área remota, excesso de tamanho, residencial — linha por linha
Quoted at ship time quoted amount A estimativa no momento da cotação
Invoiced invoiced amount O que a transportadora realmente fatura
Invoice date invoice date Determina qual versão de tarifa se aplica

Eu nunca codifico tarifas específicas — as tabelas de tarifas das transportadoras e as políticas de sobretaxa mudam ano a ano, então trate a política publicada mais recente da transportadora como a fonte da verdade. O que o sistema precisa é de uma tabela de versões de regras: cada regra de tarifação carrega uma data de vigência, e a conciliação iguala a versão da regra com a data da fatura. Os $4,000 do cliente de Fontana morreram por causa da tabela de versões de regras que faltava.

Depois rode duas janelas de conciliação em vez de uma só correria de fim de mês. Sete dias após a data do embarque, rode a conciliação da estimativa: estimativa do WMS contra o custo retornado pelo TMS, e sinalize qualquer desvio acima de 5%. Depois rode a conciliação final dentro de três dias após a chegada da fatura. Dividir as janelas significa que os embarques problemáticos aparecem na semana um em vez do dia 45.

Auditoria de frete de saída em um armazém

A janela de estimativa tem um benefício colateral: detecta a deriva sistêmica no motor de tarifação. Se um nível de serviço — digamos overnight — sai 8% ou mais abaixo do custo retornado por duas semanas seguidas, quase certamente está faltando um acessório nas regras de tarifação. Corrija cedo e a economia se compõe. A conciliação final tem outro trabalho: fatura contra custo retornado, linha por linha, e tudo que não bater vai direto para o processo de disputa com a transportadora. As janelas de correção de fatura das transportadoras são limitadas — uma vez fechada a janela, o dinheiro pago a mais se perde para sempre, então verifique a política vigente de cada transportadora.

Retentativas sem idempotência: o mesmo embarque empurrado três vezes

A rede falha, o WMS não recebe o acknowledgment do TMS, e a lógica antiga retenta o push. Exceto que o TMS realmente recebeu a primeira solicitação — só a resposta se perdeu. Agora o mesmo embarque existe três vezes no TMS, e algumas transportadoras geram alegremente três etiquetas. Pior, a retentativa às vezes sobrescreve a primeira cotação, então a fatura não bate com nada.

Duas correções, e ambas são inegociáveis. Envie um ID de solicitação globalmente único com cada push; o TMS e a transportadora deduplicam por esse ID, e um ID repetido retorna o primeiro resultado sem reexecutar a ação de negócio. Use retentativas de intervalo fixo mais backoff exponencial — digamos 5 minutos, 30 minutos, 2 horas — e o que passar do limite vai para uma fila manual. Nunca retente para sempre. E verifique o "registro de enviados" local antes de cada envio: uma solicitação com entrada no registro nunca é reenviada. Idempotência custa meio dia de design e economiza três dias de contabilidade forense.

Um detalhe que as pessoas perdem: nunca regenere o ID de solicitação na retentativa. Cada retentativa do mesmo embarque deve carregar o mesmo ID de solicitação, ou a deduplicação do TMS é decorativa. O ajuste de timeouts também importa. As APIs das transportadoras ficam lentas na alta temporada; um timeout de 5 segundos dispara retentativas constantemente, enquanto 30 segundos mais backoff cortam drasticamente as retentativas falsas.

Meu veredicto sobre qual escala merece integração profunda

Aqui vai a versão curta. Menos de 300 pedidos por dia com uma ou duas transportadoras: a conciliação via CSV basta. Exporte o detalhe de custos do TMS toda semana, junte com os registros de embarque do WMS, e meio dia de trabalho manual fecha o mês. Construir integração em tempo real para esse volume — o custo de desenvolvimento e manutenção quase certamente excede o que ela economiza. Não vale a pena.

Mais de 500 pedidos por dia, ou três ou mais transportadoras com níveis de serviço mistos: a integração profunda com conciliação automatizada é obrigatória. Nesse volume, a mão de obra de conciliação manual e o risco de pagar a mais/a menos já excedem o custo de construção. A faixa do meio — 300 a 500 — pode ir semi-automatizada: push e callbacks de status por API, conciliação de faturas via importação CSV semi-automatizada, e complete o resto quando o volume crescer.

Uma regra dura independentemente da escala: na primeira semana após o go-live, verifique à mão 20 embarques por dia de ponta a ponta — push do WMS, status do TMS, fatura da transportadora, os três lados. Essa semana de trabalho manual é o que compra um ano tranquilo.

O que você pode fazer amanhã: rode hoje à noite um relatório listando cada pedido do WMS travado "em trânsito" há mais de 48 horas, e verifique o status real de cada um no TMS. Até que essa lacuna seja fechada, cada conciliação, cada análise, cada projeto de economia é uma casa construída sobre areia. Tape primeiro os buracos dos callbacks, e depois fale de otimização.

Traduzido do inglês. Em caso de divergência, prevalece a versão em inglês.