API de Frete v2
A nova versão da API foi desenvolvida para facilitar o cálculo de frete com o intuito de padronizar os retornos das cotações e possibilitar ao lojista a realização de diversas regras de frete, onde nós (Grupo Casas Bahia) encaminhamos uma requisição com método POST diretamente para a URL do seller/integrador de frete, com o objetivo de recuperar informações referentes a entrega de um produto para uma determinada região.
O grande ganho dessa API é que com as mensagens bem tratadas, vamos conseguir acatar os retornos de insucessos das cotações para que o lojista não tenha vendas indevidas, por exemplo, regiões não atendidas, produto sem estoque, etc, evitando assim que caiam na contingência.
Regras para desenvolvimento da URL de frete
Para o desenvolvimento da URL nesta versão da API é preciso que sigam o exemplo abaixo para que possamos também identificar o nome do parceiro responsável pela integração de frete do lojista. A URL deve conter o parâmetro "dominio_parceiro" com o valor correspondente ao nome do parceiro. Isso facilita o rastreamento e a resolução de problemas relacionados ao frete.
Modelo da URL de frete:
https://<dominio_parceiro>/<uri_opcional>/v2/freight
<Paint color='warn'>
### Importante!
Caso seja necessário colocar um autenticador, esse parâmetro deve ser adicionado na própria URL, desta forma caso optem por coloca-lo, cada lojista terá uma URL específica para ser cadastrada dentro do portal do lojista (PAS).
</Paint>
Exemplo:
https://<dominio_parceiro>/<uri_opcional>/v2/freight/{{2315ds215d29478613ds}}
Atenção
O tempo máximo esperado para o retorno da cotação, por padrão será de até 1 segundo 1000ms, caso não seja retornado nesse tempo a cotação dará time-out e será encaminhada à tabela de contingência cadastrada pelo lojista.
Request
Iremos enviar uma requisição contendo informações do produto cotado para que retornem o cálculo de frete. Com o envio das informações do item, o intuito é que a loja consiga realizar várias regras e com isso oferecer um frete mais competitivo.
Abaixo mostraremos os campos enviados na requisição detalhando cada um deles:
Campo | Tipo | Descrição |
---|---|---|
departament | string | Enviaremos o departamento (id) |
category | string | Enviaremos a categoria (id) |
sku | string | Enviaremos o SKU Lojista |
quantity | integer | Quantidade de vezes do item cotado |
price | double | Preço do produto no Marketplace |
dimensions: width, depth and height | double | Valores serão enviados em metros (m) |
dimensions: weight | double | Valor será enviado sempre em quilos (kg) |
seller_id | integer | ID único para cada seller no Marketplace |
origin_zip_code | string | CEP origem do lojista cadastrado no PAS (centro de distribuição) |
destination_zip_code | string | CEP destino (cliente) |
business_unit | string | Unidade de negócio Grupo Casas Bahia |
Headers
Observação
A requisição ocorrerá dentro da URL de frete e para isso, o lojista deve cadastrar a URL desenvolvida no portal do lojista, seguindo o caminho a seguir: Configurações > Integradora de frete.
Cotação com um SKU
Neste cenário simularemos um cliente cotando apenas um SKU do lojista em nosso site para obter a informação de preço e prazo em uma determinada região. Abaixo mostraremos o bodyrequest enviado:
Método: :POST
Request:
{
"items": [
{
"departament": "",
"category": "",
"sku": "RO7",
"quantity": 1,
"price": 39.99,
"dimensions": {
"width": 0.40,
"depth": 0.50,
"height": 0.60,
"weight": 12
}
}
],
"seller_id": 123456,
"origin_zip_code": "35590000",
"destination_zip_code": "09791225",
"business_unit": "5"
}
Observação
Nesta simulação de cotação com um SKU, o cliente pode adicionar o item várias vezes no carrinho. Nesse caso, o campo "quantity" indica o número total de itens adicionados.
Cotação com SKUs diferentes
Neste cenário simularemos um cliente cotando dois ou mais SKUs diferentes do lojista em nossos sites, para obter a informação de preço e prazo em uma determinada região. Abaixo mostraremos o bodyrequest enviado:
Método: :POST
Request:
{
"items": [
{
"sku": "RO7",
"quantity": 1,
"category": "723",
"price": 169.90,
"dimensions": {
"width": 0.31,
"depth": 0.83,
"height": 0.08,
"weight": 10.0
}
},
{
"sku": "RO8",
"quantity": 1,
"category": "723",
"price": 539.90,
"dimensions": {
"width": 0.49,
"depth": 1.23,
"height": 0.12,
"weight": 37.0
}
}
],
"seller_id": 123456,
"origin_zip_code": "35590000",
"destination_zip_code": "09791225",
"business_unit": "5"
}
Response
Após enviarmos os dados do produto a ser cotado, o response da chamada deve ser devolvido contendo todos os campos obrigatórios referente ao frete do lojista, segue abaixo todos os campos disponíveis a serem preenchidos na devolução do cálculo do frete, onde será possível saber quais são :obrigatórios e quais são opcionais
Campo | Tipo | Descrição | Obrigatório |
---|---|---|---|
seller_mp_token | string | Identificador do lojista, campo deve ser preenchido com o ID do lojista ou access_token até 100 caracteres | Sim |
sku | string | Devolução do SKU lojista cotado | Sim |
quantity | integer | Quantidade do item que enviamos para ser cotado | Sim |
price | double | Preço do frete | Sim |
method_type | string | Nome da transportadora responsável pela entrega | Sim |
method_name | string | Nome da modalidade do frete "Normal" ou Expressa" | Sim |
method_id | integer | Número da modalidade de frete (1 = Normal ou 2 = Expressa) | Sim |
delivery_estimate_date_min * | string | Data mínima de entrega | Não |
delivery_estimate_date_max* | String | Data máxima de entrega | Não |
lead_time_business_days * | integer | Adiciona mais dias dentro do prazo estimado na cotação | Não |
delivery_estimate_business_days* | integer | Prazo total de entrega em dias úteis | Não |
delivery_estimate_transit_time_business_days* | integer | Tempo de entrega da transportadora em dias úteis | Sim |
delivery_processing_time_business_days* | integer | Tempo de preparo em dias úteis | Sim |
warehouse_handling_time* | integer | Prazo de expedição em dias úteis | Sim |
delivery_additional_transit_time_business_days* | integer | Tempo de entrega adicional da transportadora em dias úteis | Não |
business_or_calendar_days* | string | "B" = business e "C" = calendar_days | Não |
Novidades: os campos com * são novos, abaixo colocamos alguns alertas sobre eles e quando estarão disponíveis em produção.
Importante!
Os campos que compõe o prazo de entrega para o cliente, na cotação do frete, não podem receber valores negativos. Caso isto ocorra, automaticamente a cotação de frete será direcionada para a tabela de contingência.
Os campos que compõe este cálculo são:
- delivery_estimate_business_days*
- delivery_estimate_transit_time_business_days*
- delivery_processing_time_business_days*
- warehouse_handling_time*
- delivery_additional_transit_time_business_days*
Importante
Os seguintes campos : obrigatórios
- "delivery_estimate_transit_time_business_days"
- "delivery_processing_time_business_days"
- "warehouse_handling_time"
Não será mais utilizado o campo "delivery_time" conforme glossário dos campos que farão parte do body_response.
Serão utilizados para compor o prazo final para o cliente em nossos sites e serão somados automaticamente pelo Marketplace. Com o prazo somado, iremos disponibilizar o prazo nos sites estimando em dias úteis mostrando a data prometida para a entrega.
Composição do preço do frete
A integradora calcula o frete total para todos os itens que enviamos. Para mostrar o frete individual de cada item no carrinho, precisam dividir o valor total pelo número de SKUs que enviamos no calculo do frete:
Exemplo
Enviamos 2 SKUs para a API do lojista, onde nos retornaram R$ 50,00 reais.
Internamente vamos pegar os R$ 50,00 e dividir por 2 (quantidade de itens no carrinho) que ficará R$ 25,00 reais para cada SKU e essa será a visão do cliente dentro do carrinho para cada produto.
Cotação com um SKU
Neste cenário mostraremos o retorno do cálculo do frete onde o cliente cotou apenas um SKU do lojista em nosso site para obter a informação do frete. Abaixo o bodyresponse retornado, considerando o cenário onde o cliente colocou no carrinho dois itens do mesmo SKU e a loja oferece duas opções de entrega, sendo (Normal ou Expressa):
Status_code de retorno: 200 Retornando todos os campos, tanto obrigatório quanto opcional.
{
"seller_mp_token": "12345",
"items": [
{
"sku": "123",
"quantity": 2
}
],
"delivery_options": [
{
"price": 47.23,
"method_type": "PAC",
"method_name": "Normal",
"method_id": 1,
"delivery_estimate_date_min": "03/04/2023",
"delivery_estimate_date_max": "10/04/2023",
"lead_time_business_days": 2,
"delivery_estimate_business_days": 5,
"delivery_estimate_transit_time_business_days": 1,
"delivery_processing_time_business_days": 1,
"warehouse_handling_time": 2,
"delivery_additional_transit_time_business_days": 1,
"business_or_calendar_days": "B"
},
{
"price": 50.00,
"method_type": "SEDEX",
"method_name": "Expressa",
"method_id": 2,
"delivery_estimate_date_min": "03/04/2023",
"delivery_estimate_date_max": "05/04/2023",
"lead_time_business_days": 2,
"delivery_estimate_business_days": 2,
"delivery_estimate_transit_time_business_days": 0,
"delivery_processing_time_business_days": 0,
"warehouse_handling_time": 0,
"delivery_additional_transit_time_business_days": 0,
"business_or_calendar_days": "B"
}
]
}
Retornando apenas os campos obrigatórios
{
"seller_mp_token": "12345",
"items": [
{
"sku": "123",
"quantity": 2
}
],
"delivery_options": [
{
"price": 47.23,
"method_type": "PAC",
"method_name": "Normal",
"method_id": 1,
"delivery_estimate_transit_time_business_days": 1,
"delivery_processing_time_business_days": 1,
"warehouse_handling_time": 2
},
{
"price": 50.00,
"method_type": "SEDEX",
"method_name": "Expressa",
"method_id": 2,
"delivery_estimate_transit_time_business_days": 1,
"delivery_processing_time_business_days": 1,
"warehouse_handling_time": 2
}
]
}
Observação
Não é obrigatório enviar duas opções de entrega. Porém, caso o lojista queira retornar, será um diferencial para a experiência do cliente em nossos sites.
Lembrando que caso o lojista queira retornar duas modalidades, a opção expressa precisa ser sempre a mais rápida e enviada apenas junto com a opção normal, ou seja, nunca somente sozinho.
Cotação com SKUs diferentes
Neste cenário mostraremos o retorno do cálculo do frete onde o cliente cotou dois ou mais SKUs diferentes do lojista em nosso site para obter a informação do frete. Abaixo o bodyresponse retornado, considerando o cenário onde o cliente colocou no carrinho dois SKUs diferentes e a loja retornou a entrega mais barata e a modalidade que atende os dois itens:
Status_code de retorno: 200 Retornando todos os campos, tanto obrigatório quanto opcional.
{
"seller_mp_token": "12345",
"items": [
{
"sku": "RO7",
"quantity": 1
},
{
"sku": "RO8",
"quantity": 1
}
],
"delivery_options": [
{
"price": 68.50,
"delivery_time": 6,
"method_type": "PAC",
"method_name": "Normal",
"method_id": 1,
"delivery_estimate_date_min": "03/04/2023",
"delivery_estimate_date_max": "10/04/2023",
"lead_time_business_days": 2,
"delivery_estimate_business_days": 5,
"delivery_estimate_transit_time_business_days": 1,
"delivery_processing_time_business_days": 1,
"warehouse_handling_time": 2,
"delivery_additional_transit_time_business_days": 1,
"business_or_calendar_days": "B"
}
]
}
Retornando apenas os campos obrigatórios
{
"seller_mp_token": "12345",
"items": [
{
"sku": "RO7",
"quantity": 1
},
{
"sku": "RO8",
"quantity": 1
}
],
"delivery_options": [
{
"price": 68.50,
"delivery_time": 6,
"method_type": "PAC",
"method_name": "Normal",
"method_id": 1,
"delivery_estimate_transit_time_business_days": 1,
"delivery_processing_time_business_days": 1,
"warehouse_handling_time": 2
}
]
}
Atenção
Sempre que houver na cotação SKUs diferentes, o serviço deve ser retornado sempre a entrega mais barata, sendo o tipo de entrega que atendem todos os SKUs dentro da cotação.
Códigos de erro
Quando ocorrer algum erro no cálculo do frete, relacionado à regra de negócios que vocês desenvolveram, o serviço deve retornar um status_code de erro da família 4xx, indicando que a cotação não foi realizada. Esse retorno é essencial para evitar chamadas indesejadas na contingência. Nesses casos, mostraremos uma mensagem genérica para o cliente, como "Desculpe! No momento este produto não pode ser entregue na região informada." Os erros possíveis são:
Códigos HTTPS Retornado | Mensagem | code |
---|---|---|
400 | Não entrega na região informada | delivery_not_available |
400 | Produto fora de estoque | out_of_stock |
409 | CEP Inválido | invalid_zipcode |
409 | SKU não encontrado | sku_not_found |
Importante
Os retornos devem ser enviados em conceito de lista. Caso na cotação tenha 2 SKUs e os retornos de erros diferentes, cada SKU terá uma mensagem de erro específica. O mesmo vale para cotações com mais de um item com o mesmo retorno.
Exemplos de responses contendo a mensagem de erro
- status_code retornado: 400
- header: Para o retorno, devem utilizar Content-Type:application/json
- message: Não entrega na região informada
- code: delivery_not_available
{
"seller_mp_token": "ce94c3db-c657-4ad9-bc1a-81957fca4837",
"errors": [
{
"message": "Não entrega na região informada",
"code": "delivery_not_available",
"sku": 123,
"available_quantity": 3
},
{
"message": "Sku não encontrado",
"code": "sku_not_found",
"sku": 4567,
"available_quantity": 1
}
]
}
- Status_code enviado: 400
- Header: Para o retorno, devem utilizar Content-Type: application/json
- message: Produto fora de estoque
- code: out_of_stock
{
"seller_mp_token": "ce94c3db-c657-4ad9-bc1a-81957fca4837",
"errors": [
{
"message": "Produto fora de estoque",
"code": "out_of_stock",
"sku": 123,
"available_quantity": 3
},
{
"message": "Sku não encontrado",
"code": "sku_not_found",
"sku": 4567,
"available_quantity": 1
}
]
}
- Status_code enviado: 409
- Header: Para o retorno, devem utilizar Content-Type: application/json
- message: CEP inválido
- code: invalid_zipcode
{
"seller_mp_token": "ce94c3db-c657-4ad9-bc1a-81957fca4837",
"errors": [
{
"message": "CEP inválido",
"code": "invalid_zipcode",
"sku": 123,
"available_quantity": 3
},
{
"message": "Sku não encontrado",
"code": "sku_not_found",
"sku": 4567,
"available_quantity": 1
}
]
}
- Status_code enviado: : 409
- Header: Para o retorno, devem utilizar Content-Type: :application/json
- message: SKU não encontrado
- code: sku_not_found
Dúvidas frequentes
Dúvida 1
Ao receber a cotação de mais de um SKU e apenas um deles não tiver estoque, qual deverá ser o retorno correto?
- Deverá ser retornado ( 400 - Produto fora de estoque ) para o SKU sem estoque e para o outro a cotação correta com os prazos e preços.
Dúvida 2
Ao receber a cotação de mais de um SKU e apenas um é atendido pela respectiva região, qual deverá ser o retorno correto?
- Deverá ser retornado ( 400 - Não entrega na região informada ) para o SKU não atendido e o outro a cotação correta com os prazos e preços .
Dúvida 3
Ao receber a cotação de mais de um SKU, sendo que um atende o método normal e expresso, já o outro, atende somente o normal, qual deverá ser o retorno correto?
- Deverá retornar somente a opção disponível para ambos SKUs, que neste caso é a opção “normal”.
Importante!
Pedimos que ao final do desenvolvimento ou em caso de dúvidas, para que possamos auxiliar na homologação, entre em contato com nosso time de integração através do seguinte endereço de e-mail: integracao.mktp@viavarejo.com.br.