Integração de Cotação de Frete - Plataforma Seller
Sumário
Este documento descreve a integração de cotação de frete entre sellers parceiros e a Plataforma Seller do Magalu. A integração permite que sellers exponham suas próprias APIs de frete para serem consumidas pela plataforma durante o processo de checkout.
Pré-requisitos
- Endpoint HTTP/HTTPS disponível publicamente
- Capacidade de responder em até 1.0 segundos
- Suporte a formato JSON
- Sistema de cotação de frete funcional
Objetivo
Integrar seu sistema de cotação de frete com a Plataforma Seller para:
- Fornecer cotações em tempo real durante o fluxo de compra e checkout
- Manter controle sobre regras de precificação e prazos
Visão Geral
A Plataforma Seller é o sistema de frete do Magalu, responsável por gerenciar e orquestrar cotações de múltiplos provedores de transporte. A plataforma não expõe endpoints externos, ao invés disso, os sellers expõem APIs que a plataforma consome para obter cotações de frete.
Características
| Característica | Especificação |
|---|---|
| Método HTTP | POST |
| Formato | JSON |
| Autenticação | Nenhuma (usar allowlist de IPs) |
| Timeout | 1.0 segundos |
| Tipo de Entrega | Método de Entrega |
Arquitetura de Integração
Fluxo de Integração:
- 👤 Cliente solicita cotação no site Magalu
- 🌐 Magalu Site encaminha o pedido para a Plataforma Seller
- ⚙️ Plataforma Seller chama sua API (timeout de 1.0s)
- 🔌 Seller APIs retorna opções de frete disponíveis
- ⚙️ Plataforma Seller processa as cotações
- 🌐 Magalu Site exibe as opções ao cliente
Diagrama de Sequência
Métodos de Cotação de Frete
Quais os métodos de cotação de frete no Magalu Marketplace?
Atualmente o Magalu Marketplace aceita quatro tipos de cotação de frete, sendo elas:
- Planilhas Internas - Configuração manual de tabelas de frete
- Magalu Entregas - Serviço de logística próprio do Magalu
- Cotação Via API - Integração com API do seller (foco desta documentação)
- Gateways de Frete - Integração com provedores terceiros de frete
O que você precisa saber
- Sua API será chamada em tempo real durante o checkout para obter cotações de frete
- O Magalu exibe apenas a opção de frete mais barata entre todas as cotações retornadas
- Você pode retornar múltiplas opções de frete, mas apenas a mais econômica será mostrada ao cliente
- Se sua API não responder no prazo, o frete será exibido como indisponível para aquele produto
Como Funciona
Endpoint Que Você Precisa Implementar
Você deve criar um endpoint que a plataforma irá chamar para obter cotações:
POST https://sua-api.com/...
Content-Type: application/json
Exemplos com autenticação (opcional):
POST https://sua-api.com/...?token=SEU_TOKEN_AQUI
Content-Type: application/json
💡 Nota: Se optar por autenticação na URL, configure exatamente a URL (incluindo parâmetros) no portal do Magalu. A plataforma chamará o endpoint exatamente como configurado.
Requisitos Técnicos
| Requisito | Especificação | Obrigatório |
|---|---|---|
| Protocolo | HTTPS | ✅ Sim |
| Método | POST | ✅ Sim |
| Content-Type | application/json | ✅ Sim |
| Encoding | UTF-8 | ✅ Sim |
| Timeout Máximo | 1.0 segundo | ✅ Sim |
| Rate Limiting | Sem limite (alta frequência) | ⚠️ Considerar |
O que acontece em caso de Timeout?
Quando a API do seller não responde dentro do prazo de 1.0 segundos, o sistema executa o seguinte fluxo:
- Cancelamento Imediato: A requisição HTTPS é cancelada automaticamente
- Sem Retentativas: Não há nova tentativa para a mesma requisição
- Cotação Ignorada: A resposta da sua API é descartada e registrada como erro de timeout
- Resultado Final: O cliente recebe mensagem de "frete indisponível" para aquele produto
Segurança e Autenticação
⚠️ Sem autenticação via token: a Plataforma Seller não envia tokens automaticamente nas requisições.
Recomendações de Segurança:
- Allowlist de IPs: Implemente no seu gateway/API para restringir acesso apenas aos IPs do Magalu
- Autenticação na URL (se necessário): Você pode configurar o endpoint com parâmetros de autenticação na URL (ex.:
https://api.exemplo.com/frete?token=SEU_TOKEN). A plataforma chamará o endpoint exatamente como você configurou
Formato de Requisição
Headers
| Name | Valor |
|---|---|
| Content-Type | application/json |
Body - Parâmetros
| Atributo | Descrição | Tipo | Obrigatório | Observações |
|---|---|---|---|---|
| session_id | Identificador da requisição | string | Sim | UUID v4 |
| zipcode | CEP de destino para cotação | string | Sim | 8 dígitos, só números |
| items | Itens solicitados para cotação | array | Sim | Pelo menos 1 item |
| items[].sku | SKU do produto solicitado | string | Sim | Máx. 50 caracteres |
| items[].quantity | Quantidade do item solicitado | int | Sim | Inteiro > 0 |
| items[].price | Preço do item solicitado | float | Sim | Maior que 0, 2 casas decimais |
| items[].currency | Tipo da moeda | string | Sim | Sempre "BRL" |
| items[].dimensions | Objeto com as dimensões do item solicitado | object | Sim | Medidas em metros e quilos |
| items[].dimensions.depth | Profundidade do item solicitado | float | Sim | > 0 em metros |
| items[].dimensions.height | Altura do item solicitado | float | Sim | > 0 em metros |
| items[].dimensions.width | Largura do item solicitado | float | Sim | > 0 em metros |
| items[].dimensions.weight | Peso do item solicitado | float | Sim | > 0 em kg |
Observações Importantes sobre Unidades
⚠️ ATENÇÃO: Unidades de medida são críticas para cálculo correto!
Dimensões (dimensions)
| Campo | Unidade | Observação |
|---|---|---|
width | metros | Largura expressa em metros (ex.: 0.570 = 57cm) |
depth | metros | Profundidade/Comprimento expresso em metros (ex.: 0.400 = 40cm) |
height | metros | Altura expressa em metros (ex.: 0.280 = 28cm) |
weight | quilos | Peso expresso em quilos (ex.: 11.59 = 11,59kg) |
💡 Conversão rápida: Para converter centímetros em metros, divida por 100. Para gramas em quilos, divida por 1000.
Price e Quantity
| Campo | Tipo | Observação |
|---|---|---|
price | float | Preço unitário com até 2 casas decimais (ex.: 571.98) |
quantity | int | Quantidade inteira, sempre maior que zero |
Validações
💡 Dica: Sempre valide os dados de entrada antes de processar a cotação para evitar erros de cálculo.
Exemplos de Requisição
Exemplo 1: Cotação com um único SKU
POST https://sua-api.com/...
Content-Type: application/json
{
"session_id": "c1a03cd1-bb63-456d-82a1-7818000e33e4",
"zipcode": "04038001",
"items": [
{
"sku": "601612",
"quantity": 1,
"price": 571.98,
"currency": "BRL",
"dimensions": {
"depth": 0.08,
"height": 1.0,
"width": 1.0,
"weight": 11.59
}
}
]
}
Exemplo 2: Cotação com múltiplos SKUs
POST https://sua-api.com/...
Content-Type: application/json
{
"session_id": "f8b2e4d3-9a1c-4f7e-b5d6-8e9f0a1b2c3d",
"zipcode": "01310100",
"items": [
{
"sku": "601612",
"quantity": 2,
"price": 571.98,
"currency": "BRL",
"dimensions": {
"depth": 0.08,
"height": 1.0,
"width": 1.0,
"weight": 11.59
}
},
{
"sku": "401622",
"quantity": 2,
"price": 102.55,
"currency": "BRL",
"dimensions": {
"depth": 0.5,
"height": 1.5,
"width": 1.1,
"weight": 12.0
}
}
]
}
Formato de Resposta
Sucesso - Status Code 200
Exemplo 1: Resposta com um único SKU
{
"packages": [
{
"delivery_options": [
{
"delivery_days": 12,
"id": "ID da Minha Transportadora SP",
"name": "Minha Transportadora SP",
"price": 5.33,
"type": "conventional"
},
{
"delivery_days": 5,
"id": "EXPRESS_CD_SP",
"name": "Express Transportadora SP",
"price": 12.5,
"type": "conventional"
}
],
"items": [
{
"sku": "601612",
"quantity": 1
}
]
}
]
}
Exemplo 2: Resposta com múltiplos SKUs
{
"packages": [
{
"delivery_options": [
{
"delivery_days": 8,
"id": "TRANSP_PADRAO",
"name": "Transportadora Padrão",
"price": 45.8,
"type": "conventional"
},
{
"delivery_days": 3,
"id": "TRANSP_EXPRESS",
"name": "Transportadora Express",
"price": 89.9,
"type": "conventional"
}
],
"items": [
{
"sku": "601612",
"quantity": 2
},
{
"sku": "401622",
"quantity": 2
}
]
}
]
}
Body (HTTP 200) - Parâmetros de Resposta
| Atributo | Descrição | Tipo | Obrigatório | Observações |
|---|---|---|---|---|
| packages | Pacotes com as opções de entregas | array | Sim | Pelo menos 1 pacote |
| packages[].delivery_options | Opções de entrega para o pacote | array | Sim | Pelo menos 1 opção |
| packages[].delivery_options[].delivery_days | Prazo para entrega | int | Sim | Inteiro > 0 (ex.: 5 dias) |
| packages[].delivery_options[].id | Id da opção de entrega (será exibido dentro da tela de gestão de pedidos) | string | Sim | Máx. 32 caracteres |
| packages[].delivery_options[].name | Nome da opção de entrega | string | Sim | Será exibido ao cliente |
| packages[].delivery_options[].price | Valor da opção de entrega | float | Sim | Maior que 0, 2 casas decimais |
| packages[].delivery_options[].type | Tipo da opção de entrega | string | Sim | Define o tipo de entrega |
| packages[].items | Itens presentes no pacote | array | Sim | Deve corresponder exatamente à requisição |
| packages[].items[].sku | SKU do item presente no pacote (deve condizer com a requisição) | string | Sim | Mesmo SKU da requisição |
| packages[].items[].quantity | Quantidade do item presente no pacote (deve condizer com a requisição) | int | Sim | Mesma quantidade da requisição |
Erros - Status Code 400
Todos os erros retornam status HTTP 400 com a seguinte estrutura:
Body (HTTP 400) - Parâmetros de Erro
| Atributo | Descrição | Tipo | Obrigatório |
|---|---|---|---|
| message | Mensagem do erro | string | Sim |
| code | Código do erro | string | Sim |
| items[] | Itens relacionados ao erro | array | Não |
| items[].sku | SKU relacionado ao erro | string | Não |
| items[].available_quantity | Estoque do SKU relacionado ao erro | string | Não |
CEP Inválido
{
"message": "Invalid zipcode",
"code": "invalid_zipcode"
}
Não Entrega na Região
{
"message": "Delivery Not Available",
"code": "delivery_not_available",
"items": [
{
"sku": "601612",
"available_quantity": "2"
}
]
}
Item sem Estoque
{
"message": "Itens sem Estoque",
"code": "out_of_stock",
"items": [
{
"sku": "601612",
"available_quantity": "0"
}
]
}
Códigos de Erro: Todos os erros retornam status
400. Use os códigos específicos para diferentes situações.
Códigos de Erro Disponíveis
| Código | Descrição | Quando Usar | Requer items[] |
|---|---|---|---|
invalid_zipcode | CEP inválido ou mal formatado | CEP não existe ou formato incorreto | ❌ Não |
delivery_not_available | Não atende a região | Área fora de cobertura | ✅ Sim |
out_of_stock | Produto sem estoque | SKU sem estoque disponível | ✅ Sim (com available_quantity) |
📌 Importante: Sempre retorne o código mais específico possível para facilitar o debugging.
Considerações Importantes
Comportamento do Site Magalu
Exibição de Opções de Frete
- O Magalu sempre exibirá apenas a opção de frete mais barata no site, mesmo que você retorne múltiplas opções
- Caso duas opções tenham o mesmo preço, a opção com menor prazo de entrega será exibida
- Se não houver opções válidas (timeout ou erro), o produto aparecerá como "Frete Indisponível" no checkout
Múltiplas Opções de Frete
Ainda assim, é recomendado retornar múltiplas opções quando disponível:
{
"packages": [
{
"delivery_options": [
{
"id": "gateway",
"type": "conventional",
"name": "Jadlog Normal",
"price": 229.14,
"delivery_days": 6
},
{
"id": "gateway",
"type": "conventional",
"name": "Jadlog Expresso",
"price": 178.9,
"delivery_days": 5
},
{
"id": "extra",
"type": "conventional",
"name": "TRANSPORTADORA",
"price": 70.2,
"delivery_days": 20
}
],
"items": [
{
"sku": "12",
"quantity": 1
}
]
}
]
}
Checkout no Magalu Marketplace
Duas Cotações por Pedido
No checkout do carrinho do Magalu Marketplace, são realizadas duas cotações de frete:
- Cotação Inicial - Na tela inicial, quando o cliente consulta prazo e valor de frete
- Cotação Automática - Na finalização do carrinho, de forma automática
Validação de Resposta
Campos Obrigatórios
- Certifique-se que o retorno da sua API está retornando exatamente todos os campos obrigatórios
- Parenteses, chaves e vírgulas devem estar corretos no JSON
- A ordem de exibição dos itens deve seguir o modelo estabelecido
FAQ - Perguntas Frequentes
Em relação ao cálculo de frete, como é feito o checkout do carrinho no Magalu Marketplace?
RESPOSTA: No checkout são realizadas duas cotações de frete, uma na página do produto cliente e outra automática na finalização do carrinho. Veja detalhes completos na seção Checkout no Magalu Marketplace.
Qual deve ser o padrão na estrutura do endpoint de frete?
RESPOSTA: Não existe um padrão no endpoint de frete, o mesmo pode ser livre. A única exigência é que:
⚠️ Não sejam enviadas informações como a porta do servidor diretamente no endpoint de frete
Exemplo INCORRETO:
https://api.exemplo.com:8080/cotacao/frete
Exemplo CORRETO:
https://api.exemplo.com/cotacao/frete
https://api.exemplo.com/v1/shipping/calculate
https://frete.seudominio.com.br/api/quotation
Como faço para realizar a autenticação de um determinado seller que utiliza o meu endpoint de cotação?
RESPOSTA: A autenticação pode ser feita via parâmetros na URL (ex.: ?token=SEU_TOKEN) ou por identificação no payload (session_id, SKUs). Veja todas as opções e recomendações na seção Segurança e Autenticação.