Integração com TMS Externo

Esta documentação orienta fornecedores de software TMS (Transportation Management System) sobre como integrar seus sistemas ao Vendelo, permitindo cotação automática de frete e gestão completa do processo de despacho por meio de APIs REST padronizadas.

Introdução à Integração TMS

A integração entre o Vendelo e sistemas TMS externos permite que transportadoras e fornecedores de software logístico ofereçam cotações automáticas de frete e gerenciem todo o ciclo de despacho diretamente na plataforma Vendelo. O processo começa quando um operador solicita opções de frete para um pedido e pode evoluir até a geração de etiquetas e rastreamento.

Público-alvo: este guia é destinado especificamente a integradores e fornecedores de software TMS que desejam conectar seus sistemas ao Vendelo para ofertar serviços de frete integrados.

A integração opera em dois níveis:

  • Nível 1: cotação de frete.
  • Nível 2: cotação + despacho completo (registro, geração de etiqueta, acompanhamento e cancelamento).

Exemplo – Mock de Referência

Para facilitar o desenvolvimento e os testes, disponibilizamos um projeto de referência que simula um fornecedor TMS externo. Este exemplo implementa os endpoints necessários e demonstra boas práticas de integração.

Repositório GitHub: https://github.com/alcgithub/Vendelo.FakeShippingProvider

O projeto de referência (C#/.NET 6) inclui:

  • Endpoints: cotação, cart, geração de etiqueta, cancelamento e consulta.
  • Autenticação flexível: token estático e OAuth 2.0.
  • Validação de payload: CEPs, produtos e campos obrigatórios.
  • Rotas de debug: apoio para testes locais.
  • Collection Postman: cenários completos com scripts de validação.
Tela de configuração de variáveis de ambiente no Postman mostrando baseUrl, token, clientId e outros parâmetros
Configuração das variáveis de ambiente no Postman para facilitar os testes com o mock de referência.

Serviços fake simulados

O mock retorna quatro serviços de frete no endpoint de cotação:

ID Nome do Serviço Transportadora Características
1 SEDEX (Correios) Correios Serviço expresso com prazo reduzido
2 PAC (Correios) Correios Serviço econômico com prazo estendido
3 Jadlog Package Jadlog Serviço de transportadora privada
4 ChinaLog ChinaLog Serviço internacional simulado

Mecânica de Seleção do Vendelo

O Vendelo utiliza regras de frete para determinar quando e como chamar fornecedores TMS externos.

Processo de seleção automática

  1. Identifica a filial do pedido e busca regras ativas do tipo PER_WEIGHT_FROM_EXTERNAL_SHIPPING_PROVIDER.
  2. Aplica filtros de CEP, peso e valor conforme configurado na regra.
  3. Resolve a conta de integração (filial específica tem prioridade sobre filial padrão).
  4. Monta o request com dados de origem, destino, transportadora e produtos.
  5. Executa a chamada para POST /api/v1/shipment/calculate.
  6. Processa as opções retornadas e apresenta para seleção.
Tela de configuração de regra de despesa adicional mostrando tipo PER_WEIGHT_FROM_EXTERNAL_SHIPPING_PROVIDER
Configuração de regra para despesa adicional de frete com integração TMS externa.

Seleção automática vs manual

  • Seleção automática: aplica a melhor opção conforme configuração da regra.
  • Seleção manual: operador escolhe entre as opções disponíveis.
Interface mostrando opções de frete com seleção automática habilitada
Tela de seleção de despesas de frete no documento.

Aplicação da despesa selecionada

Após a seleção, o Vendelo registra a opção escolhida como despesa adicional do documento e distribui o valor entre os itens conforme as regras internas.

Despesa de frete já selecionada com ícone de lápis para reconfiguração
Despesa de frete já aplicada ao documento, com possibilidade de reseleção.

Configuração da Conta de Integração

Para habilitar a integração com seu TMS, configure uma conta de integração no Vendelo com as credenciais e parâmetros de conexão.

Campo Obrigatório Descrição
Host Sim URL base da API, sem barra final. Ex: https://api.seutms.com.br
Token Condicional Token Bearer fixo (quando não usar OAuth).
UserName Condicional client_id para OAuth 2.0.
Password Condicional client_secret para OAuth 2.0.
Tipo Sim Selecionar EXTERNAL_SHIPPING_PROVIDER.
Integration Tag Opcional Identificador para múltiplas contas do mesmo tipo.
Formulário de configuração de conta de integração TMS externo
Tela de configuração da conta de integração TMS externo.

Resolução de conta por filial

  • Filial específica: prioridade máxima.
  • Filial padrão: fallback para filiais sem conta própria.
  • Integration Tag: separa integrações distintas.

Ordem de resolução: filial do pedido → filial padrão. Se nenhuma conta válida for encontrada, a integração TMS não é executada.

Fluxo Operacional Completo

Cotação de frete (Nível 1 e 2)

  1. Operador abre as opções de frete do documento.
  2. Vendelo encontra regras ativas e conta de integração.
  3. Sistema monta request com origem, destino e itens.
  4. Executa POST /api/v1/shipment/calculate.
  5. Exibe opções de serviço para seleção.
  6. Aplica a opção escolhida como despesa no documento.

Registro do envio (Nível 2)

Botão de gerar etiqueta pendente na interface do usuário
Fluxo de despacho com indicação de etiqueta pendente.
  1. Usuário acessa a tela de volumes.
  2. Vendelo envia POST /api/v1/cart.
  3. TMS retorna o ID do pedido externo.
  4. Vendelo salva o ID e marca o volume como registrado.
Aviso na interface sobre etiquetas pendentes de geração
Aviso de etiquetas pendentes para acompanhamento operacional.

Geração de etiqueta

Botão salvar para gerar etiquetas
Ação de geração de etiquetas após registro no TMS.
  1. Usuário confirma os volumes.
  2. Vendelo envia POST /api/v1/shipment/generate.
  3. TMS gera etiqueta e rastreio.
  4. Vendelo exibe links de etiqueta e rastreamento no documento.
Opção de frete escolhida exibida como selecionada por padrão ao gerar etiqueta
Opção de frete previamente escolhida reaproveitada no momento da geração.

Acompanhamento e rastreamento

Detalhes do volume registrado com etiqueta de envio gerada
Detalhes do volume com dados de envio e rastreamento.
Status do envio mostrando etiqueta gerada com código de rastreamento
Status atualizado do envio após geração da etiqueta.

Endpoints

Todos os endpoints devem seguir padrão REST com JSON.

Nível 1 – Cotação apenas

Endpoint Método Obrigatório Descrição
/api/v1/shipment/calculate POST Sim Retorna opções de frete (preço e prazo).

Nível 2 – Cotação + despacho completo

Endpoint Método Obrigatório Descrição
/api/v1/shipment/calculatePOSTSimCotação
/api/v1/cartPOSTSimRegistro do envio
/api/v1/shipment/generatePOSTSimGeração de etiqueta
/api/v1/cart/cancelPOSTSimCancelamento
/api/v1/orders/{id}GETSimStatus e rastreamento

Regra de consistência: se implementar /api/v1/cart, implemente também os demais endpoints do Nível 2.

Autenticação OAuth 2.0

Para credenciais com expiração, recomendamos OAuth 2.0 com refresh token.

Endpoint de renovação

EndpointMétodoQuando usado
/oauth/tokenPOSTRenovação automática antes do vencimento.

Request de renovação

{
  "grant_type": "refresh_token",
  "refresh_token": "dGhpcyBpcyBhIHJlZnJlc2...",
  "client_id": "vendelo-client",
  "client_secret": "vendelo-secret"
}

Response esperado

{
  "token_type": "Bearer",
  "access_token": "eyJhbGciOiJSUzI1NiJ9...",
  "refresh_token": "dGhpcyBpcyBhIHJlZnJlc2...",
  "expires_in": 2592000
}

Renovação automática: o Vendelo renova tokens próximos do vencimento antes das operações.

Estrutura de Dados

Tabela de Incoterms (PT-BR)

O campo incoterms deve ser enviado conforme os valores esperados pela integração. Abaixo estão os itens e a descrição em português:

Valor em incoterms Descrição (PT-BR) Responsabilidade principal pelo frete
BY_SENDER Por conta do remetente Remetente
BY_RECIPIENT Por conta do destinatário Destinatário
THIRD_PARTY Por conta de terceiros Terceiro pagador
NO_FREIGHT Sem frete / retirada Não se aplica

Importante: valide o valor recebido em incoterms como enum/string controlada. Quando o valor não for reconhecido, retorne erro de validação em JSON (HTTP 422).

Cotação de Frete – Request

Exemplo JSON válido de request enviado pelo Vendelo:

{
  "from": {
    "postal_code": "01310100",
    "erp_id": "F001",
    "company_document": "12345678000199",
    "state_register": "123456789"
  },
  "to": {
    "postal_code": "30130010",
    "erp_id": "C00042",
    "document": "98765432100",
    "company_document": "98765432000188",
    "state_register": "987654321"
  },
  "incoterms": "BY_SENDER",
  "carrier": {
    "id": "vendelo-carrier-id",
    "erp_id": "TMS_CAR_001"
  },
  "products": [
    {
      "id": "item-uuid-vendelo",
      "erp_id": "A00001",
      "name": "Produto Exemplo",
      "width": 15,
      "height": 10,
      "length": 20,
      "weight": 0.5,
      "quantity": 2,
      "unit_price": 149.9,
      "discount_total": 15.0,
      "insurance_value": 284.8,
      "available_stock": 25,
      "user_fields": [
        { "name": "U_VDO_CODIGO_EXTRA", "value": "7101" },
        { "name": "U_VDO_ORIGEM", "value": "Importado" }
      ]
    }
  ],
  "user_fields": [
    { "name": "U_XXX_REDESPACHO", "value": "Y" },
    { "name": "U_XXX_FONTE", "value": "Indicacao" }
  ]
}

Diferença entre request e response: no request, o Vendelo pode enviar carrier.id e carrier.erp_id. No response, o TMS deve retornar somente carrier.erp_id; o id interno será preenchido pelo backend do Vendelo.

Cotação de Frete – Response

[
  {
    "id": "1",
    "name": "Expresso",
    "custom_price": 28.9,
    "custom_delivery_time": 2,
    "carrier": {
        "erp_id": "V10000" 
    },
    "company": {
      "id": "1",
      "name": "Nome da Transportadora",
      "picture": "https://cdn.seusite.com.br/logo.png"
    },
    "packages": [
      {
        "format": "box",
        "weight": 1.0,
        "price": 28.9,
        "insurance_value": 284.8,
        "dimensions": {
          "width": 15,
          "height": 10,
          "length": 20
        },
        "products": [
          {
            "id": "item-uuid-vendelo",
            "quantity": 2
          }
        ]
      }
    ],
    "error": null
  }
]

Carrier no response: quando o TMS retornar carrier.erp_id, o Vendelo localizará automaticamente a transportadora correspondente e substituirá a transportadora da cotação/pedido pela transportadora informada no retorno. O campo carrier.id não deve ser enviado no response, pois o ID interno será resolvido pelo Vendelo a partir do erp_id.

Quando não houver transportadora: omita completamente o bloco carrier. Não envie "carrier": null nem "erp_id": null.

Tratamento de Erros

Implemente tratamento consistente de erros com códigos HTTP apropriados:

Código HTTP Significado Comportamento do Vendelo
200SucessoProcessa resposta normalmente
400Payload inválidoExibe mensagem ao operador
401Não autorizadoTenta renovar token e repetir
422Falha de validaçãoExibe erros por campo
429Rate limitRetenta com backoff
5xxErro internoRegistra log e exibe mensagem genérica

Estrutura de erro padrão

{
  "error": "CEP de destino invalido.",
  "errors": {
    "to.postal_code": ["O CEP informado nao foi encontrado."]
  }
}

Importante: não retorne HTML em erros. O Vendelo espera JSON em todos os cenários.

Perguntas Frequentes

Posso implementar apenas cotação sem despacho?

Sim. No Nível 1, apenas /api/v1/shipment/calculate é obrigatório.

Como funciona a resolução de conta por filial?

O Vendelo busca primeiro a conta da filial do documento. Se não existir, usa a conta da filial padrão.

Os campos carrier são enviados na cotação?

No request, o Vendelo pode enviar carrier.id e carrier.erp_id. No response de cotação, o TMS deve retornar apenas carrier.erp_id, quando houver transportadora correspondente. O carrier.id é resolvido pelo Vendelo a partir do erp_id.

O que é available_stock no produto?

É o estoque disponível por item no momento da cotação, carregado do ERP e enviado em products[].available_stock.

Como funciona a renovação automática de OAuth?

O Vendelo renova o token via refresh token quando necessário, sem intervenção manual.

Posso usar credenciais diferentes por filial?

Sim. Configure contas separadas por filial e, se necessário, diferencie por Integration Tag.

Como testar durante o desenvolvimento?

Use o mock de referência e a collection Postman para validar cotação e despacho de ponta a ponta.