Um contrato de frete por perfil de cliente
Uma loja B2B tinha dois contratos com a transportadora e só conseguia usar um, e o token ficava em texto aberto na tela e no log. Projetei e implementei a escolha do token pelo perfil do cliente a cada cotação, com o token mascarado em todo lugar e 83 testes.
- Papel
- Desenvolvedor responsável, da análise à entrega
- Contexto
- Plataforma de e-commerce B2B e marketplace
- Stack
- PHP, Symfony, Doctrine, MySQL, JavaScript, PHPUnit
- Time
- Solo, a partir de uma história de produto
- Período
- 2026
Case anonimizado: nomes de empresa, cliente e pessoas foram omitidos ou trocados.
01. Situação
Dois contratos de frete e só um token
A integração com uma transportadora aceitava um único token de acesso por configuração. Uma loja B2B tinha dois contratos com essa transportadora, um para revenda e outro para consumidor, e só conseguia usar um. O revendedor era cotado na tabela do consumidor, e o frete cobrado divergia do frete faturado. No marketplace, cada lojista tinha o mesmo limite.
Recebi a história de produto com as regras de negócio e fiquei responsável por tudo o que vinha depois: análise técnica, plano, implementação e testes. Havia ainda um problema de segurança: o token aparecia em texto aberto no HTML da tela de configuração e no log de cada cotação. Tratei os dois na mesma entrega.
02. Investigação
Duas premissas da história não se confirmaram no código
A história descrevia bem o comportamento esperado, mas partia de premissas técnicas. Antes de escrever qualquer código, verifiquei cada uma. Duas eram falsas, e implementar em cima delas teria gerado trabalho inútil e um defeito.
Procurei cache de frete em memória, sessão, Redis, Doctrine e HTTP. O único cache vive dentro da requisição; toda cotação chama a transportadora de novo. Não foi preciso mudar chave de cache. Descartada.
03. Solução
Resolver o token a cada cotação e nunca mostrá-lo
Desenhei a solução em torno de um modo de configuração: token geral ou token por perfil. No modo por perfil, cada perfil de cliente pode ter um token; visitantes e perfis sem token usam o geral.
Resolvi o token a cada cotação e por pacote, não por carrinho. Essa escolha cobre o marketplace: num carrinho com produtos de dois lojistas, cada um cota com o seu contrato.
- Cotação de um pacote
- Configuração do lojista dono do pacote
- Modo por perfil e perfil com token: usa o token do perfil
- Header montado e log com o token mascarado
- visitante, perfil sem token ou modo geral: usa o token geral
Fechei também o vazamento do token. O token não sai em texto aberto em lugar nenhum: a tela mostra só os quatro últimos caracteres, os logs e as exceções são mascarados, e o botão de testar credencial, que adicionei, busca o token salvo no servidor sem enviá-lo ao navegador.
Escolha
Tabela própria para os tokens
Guardar como atributos da configuração não garantiria um token por perfil. A tabela garante a unicidade e apaga tudo junto com a configuração.
Escolha
Lojas existentes não mudam
O modo nasce vazio, e vazio significa geral. Nenhuma loja muda de comportamento sem escolher o modo novo.
Cuidado
Token geral obrigatório com a integração ativa
O servidor recusa o salvamento antes de gravar qualquer coisa, inclusive as faixas de frete, para não deixar a configuração pela metade.
Desenvolvi com TDD: 83 testes em 9 arquivos. Testei as migrações em um schema temporário e montei roteiros ponta a ponta com requisições reais, cobrindo admin, lojista, cotação e o JavaScript da tela, incluindo cotações com três perfis seguidos e login e logout no meio da sessão.
04. Resultado
Cada perfil cota no seu contrato
- testes automatizados
- 83
- verificações end-to-end
- 69/69
- premissas falsas descartadas antes de codar
- 2
Revendedor e consumidor são cotados cada um no seu contrato, inclusive em carrinhos com mais de um lojista, e o token não aparece mais na tela, nos logs nem nas exceções.
Além da funcionalidade, entreguei a recomendação de rotacionar os tokens e expurgar os logs antigos, e o registro de um problema antigo na seleção da opção de frete no checkout, que encontrei durante os testes.