Frete, totais e validação
Cota o frete para um CEP, calcula o total exato do pedido, confere exigências da sacola e lista consultores e formas de pagamento.
Estas cinco rotas são a revisão que vem antes de fechar o pedido. Nenhuma cria pedido nem cobra. Elas mostram ao cliente o que vai acontecer: as opções de entrega, o total final com impostos e descontos, as exigências que travam o pedido (idade, CNPJ) e as formas de pagamento disponíveis.
Quatro delas (shipping, totals, validate e checkout) aceitam line_ids: a lista de item_id das linhas marcadas pelo cliente. Só essas linhas são cotadas, validadas e pedidas; as outras ficam na sacola. Os brindes (is_gift) acompanham os itens que dão direito a eles e não se marcam sozinhos. Um combo (bundle_id) ou mix vai inteiro ou nenhum.
Erros de line_ids, iguais nas quatro rotas:
| Status | Quando | Corpo |
|---|---|---|
| 400 | Um id da lista não está na sacola. | {"error":"unknown_line","line_id":"<id>"} |
| 409 | A linha deixou de ser vendida ou não tem estoque. | {"error":"line_unavailable","line_id":"<id>","available_qty":0,"message":"..."} |
| 409 | Só brindes marcados, sem o item que dá direito a eles. | {"error":"line_unavailable","line_id":"<id>","reason":"bonus_requires_qualifier","message":"O brinde só vem junto com os itens que dão direito a ele."} |
| 409 | Marcou parte de um combo ou mix. | {"error":"line_unavailable","line_id":"<id>","reason":"bundle_requires_all","message":"Este combo é vendido junto: marque todos os itens dele ou nenhum."} |
Cotar o frete
/api/v1/storefront/wa-coex/cart/{token}/shippingPúblicaLista as opções de entrega da sacola para um CEP
Pergunta ao servidor quais métodos de entrega atendem a sacola atual naquele destino, com preço, prazo e, quando existem, pontos de retirada e janelas de agendamento. O valor que o cliente escolhe aqui não é confiado depois: no totals e no checkout o servidor cota de novo e usa o preço dele.
Parâmetros de caminho
tokenstringobrigatórioCorpo da requisição
cepstringobrigatóriocep.address_iduuidlatnumberlngnumberstreetstringnumberstringdistrictstringcitystringstatestringline_idsarrayitem_id das linhas a cotar. Ausente cota a sacola inteira.Exemplo de requisição
curl -X POST "$BASE_URL/api/v1/storefront/wa-coex/cart/$TOKEN/shipping" \
-H "Content-Type: application/json" \
-d '{"cep":"01310-100"}'Resposta
{
"shipping_options": [
{
"choice": "50000000-0000-0000-0000-000000000001",
"label": "Entrega Padrão",
"price_cents": 0,
"eta_days": 10,
"eta_min_days": 10,
"eta_text": "7-10 dias úteis",
"method_id": "50000000-0000-0000-0000-000000000001",
"position": 5,
"express": false,
"pickup": false,
"delivery_from": "2026-10-29",
"delivery_to": "2026-10-30",
"delivery_days_min": 12,
"delivery_days_max": 12,
"delivery_format": "date_range",
"delivery_slots": [
{ "date": "2026-10-12", "slots": [{ "id": "17b60b02-d01b-419d-8faa-d09ff8a00940", "start": "08:00", "end": "12:00" }] }
]
},
{
"choice": "85e87a54-dcee-4947-8cfa-f6406f2f3cbb",
"label": "Motoboy",
"price_cents": 0,
"eta_days": 0,
"eta_text": "30 min",
"method_id": "85e87a54-dcee-4947-8cfa-f6406f2f3cbb",
"position": 0,
"express": false,
"pickup": false,
"courier": true
}
]
}Campos da resposta
shipping_optionsarray[] quando nenhuma atende (veja unavailable_reason).unavailable_reasonstringoutside_delivery_areaaddress_not_locatedmin_order_not_reachedmin_order_centsintegermin_order_not_reached.min_order_missing_centsintegervendor_groupsarrayvendor_key, vendor_id, vendor_name, product_ids, shipping_options), para o front-end dizer qual seller não entrega ali.Campos de cada opção de entrega
choicestringshipping_choice no totals e no checkout.labelstringprice_centsintegereta_daysintegereta_min_days é o início. eta_text é o texto configurado ("7-10 dias úteis").method_idstringchoice pode ser <method_id>|<codigo> quando um método se abre em várias opções.positionintegericon_urlstringexpressbooleantotals e o checkout recusam pagamento na entrega com ela.pickupbooleancourierbooleandelivery_fromstringYYYY-MM-DD. delivery_to é a última. delivery_days_min e delivery_days_max são os mesmos prazos em dias. Vazios em retirada ou sem prazo calculável.delivery_formatstringdate_rangebusiness_dayshiddenpickup_pointsarrayid, name, address, city, state, zip). Só em opção de retirada. O pedido de retirada precisa de um deles (pickup_point_id).delivery_slotsarraydate e slots (id, start, end, em HH:MM). Vazio quando o método não agenda.Erros
| Status | Quando | Corpo |
|---|---|---|
| 400 | Corpo ilegível ou sem cep. | {"error":"cep required"} |
| 403 | A loja esconde preços até o login e o cliente não entrou. | {"error":"account_required","message":"Entre para consultar os preços de entrega."} |
| 502 | Falha ao cotar. | {"error":"<texto>"} |
Calcular o total
/api/v1/storefront/wa-coex/cart/{token}/totalsPúblicaPrévia do total exato do pedido, sem criar pedido
Roda o mesmo cálculo do checkout (endereço, frete, impostos, desconto Pix, cupom, cashback, preço por estado) sem criar nada. Use o resultado como o valor que o botão "Fazer pedido" mostra e envie esse mesmo número como expected_total_cents no checkout: se algo mudar entre os dois, o checkout recusa com 409 em vez de cobrar diferente.
Rodar o cálculo pode consultar um ERP externo e demorar. O servidor limita a consulta (60 segundos por padrão, configurável pela loja) e responde 504 totals_timeout.
Parâmetros de caminho
tokenstringobrigatórioCorpo da requisição
addressobjectEndereço de entrega digitado.
streetstringobrigatórionumberstringobrigatóriocomplementstringdistrictstringcitystringobrigatóriostatestringobrigatóriozipstringobrigatóriorecipientstringsaved_address_iduuidaddress.shipping_choicestringobrigatóriochoice da opção escolhida em /shipping. Em sacola com vários sellers, a escolha é uma lista ms:<vendor_key>=<choice>;<vendor_key>=<choice>, uma por seller, sem repetir nem faltar nenhum.payment_methodstringcode da forma de pagamento (veja formas disponíveis). Muda o total: Pix tem desconto, método pode ter taxa.invoiced_plan_idstringcpfstringpickup_point_idstringpayment_condition_idstringline_idsarrayitem_id das linhas a calcular.Exemplo de requisição
curl -X POST "$BASE_URL/api/v1/storefront/wa-coex/cart/$TOKEN/totals" \
-H "Content-Type: application/json" \
-d '{
"address": {"street":"Avenida Paulista","number":"1000","district":"Bela Vista","city":"São Paulo","state":"SP","zip":"01310100"},
"shipping_choice": "50000000-0000-0000-0000-000000000001",
"payment_method": "pix"
}'Resposta
{
"subtotal_cents": 23000,
"discount_cents": 6613,
"shipping_cents": 0,
"tax_cents": 0,
"pix_discount_cents": 863,
"pix_base_cents": 17250,
"tax_included": false,
"total_cents": 16387,
"earned_gift_line_ids": []
}Campos da resposta
subtotal_centsintegerdiscount_centsintegershipping_centsintegertax_centsintegertax_included é false.tax_includedbooleantrue quando o imposto já está embutido nos preços (informativo).payment_adjustment_centsintegerpix_discount_centsintegerpix_base_cents é a base sobre a qual o desconto incide (produtos depois dos descontos, sem frete). Omitidos quando não é Pix.invoiced_surcharge_centsintegerinstallmentsintegerinstallment_interest_cents é o juro. Omitidos à vista ou sem juros.withholding_centsintegertotal_centsintegercoupon_noticestringearned_gift_line_idsarrayitem_id dos brindes que as linhas marcadas conquistaram. Sempre presente, [] quando não há.ordersarraysplit_notice traz a explicação para o cliente.Erros
| Status | Quando | Corpo |
|---|---|---|
| 400 | Corpo ilegível. | {"error":"invalid body"} |
| 400 | Faltou shipping_choice. | {"error":"shipping_method_id is required"} |
| 400 | Há shipping_choice mas nenhum endereço ou CEP. | {"error":"address_required_for_shipping"} |
| 400 | Endereço incompleto. | {"error":"invalid shipping address: address_line1 is required"} |
| 400 | shipping_choice que não existe na cotação do servidor. | {"error":"invalid_shipping_choice"} |
| 400 | Entrega rápida com pagamento na entrega. | {"error":"online_payment_required","message":"Entrega rápida exige pagamento online"} |
| 400 | Há shipping_choice, mas nenhuma entrega atende ao destino. | {"error":"shipping_unavailable"} |
| 403 | A loja esconde preços até o login e o cliente não entrou. | {"error":"account_required","message":"Entre para consultar os preços e finalizar a compra."} |
| 422 | cpf com dígitos inválidos. | {"error":"invalid_document"} |
| 422 | Há shipping_choice, nenhuma entrega atende e a causa é o pedido mínimo da região. | {"error":"min_order_not_reached","min_cents":10000,"missing_cents":2500,"message":"O pedido mínimo para esta região é R$ 100,00. Faltam R$ 25,00."} |
| 422 | Regra de pedido da loja recusou. | {"error":"<codigo>","message":"..."} |
| 502 | Falha ao cotar o frete ou ao calcular. | {"error":"shipping_quote_failed"} ou {"error":"<texto>"} |
| 503 | Não foi possível identificar a conta agora. | {"error":"account_resolution_unavailable"} |
| 504 | O cálculo passou do limite de tempo. | {"error":"totals_timeout"} |
Mais os erros de line_ids do começo da página.
Validar exigências da sacola
/api/v1/storefront/wa-coex/cart/{token}/validatePúblicaConfere idade, CNPJ e limites antes de fechar o pedido
Simulação de conformidade, sem criar nada. Alguns produtos exigem idade mínima, CNPJ, compatibilidade com veículo, cotação ou têm quantidade máxima. Chame antes de mostrar o botão final para pedir ao cliente o que falta.
Parâmetros de caminho
tokenstringobrigatórioCorpo da requisição
age_confirmedbooleanpadrão: falsecnpjstringline_idsarrayitem_id das linhas a validar.Resposta
{ "ok": true, "needs_age_confirm": false }{
"ok": false,
"gates": [
{ "code": "age", "message": "customer must confirm age >= 18", "product_id": "c3f92551-9dda-4fc7-b518-353d1c4e4035", "min_age": 18 }
],
"needs_age_confirm": true,
"required_min_age": 18
}Campos da resposta
okbooleantrue quando nenhuma exigência trava o pedido.gatesarrayExigências pendentes. Omitido quando ok é true.
codestringagequotecnpjfitmentmax_qtymessagestringcode.product_iduuidmin_ageintegerneeds_age_confirmbooleanrequired_min_age traz a maior idade mínima entre os itens.Erros
| Status | Quando | Corpo |
|---|---|---|
| 400 | A sacola não pôde ser lida. | {"error":"cart unavailable"} |
| 422 | cnpj que não é um CNPJ válido. | {"error":"invalid_cnpj"} |
| 500 | Falha inesperada. | {"error":"<texto>"} |
Mais os erros de line_ids do começo da página.
Escolher o consultor
/api/v1/storefront/wa-coex/cart/{token}/sales-repsPúblicaConsultores que o cliente pode indicar no pedido
Algumas lojas perguntam no checkout "Foi atendido por um consultor?" e gravam o consultor no pedido. Esta rota diz se a pergunta existe e a lista de opções. O valor escolhido volta no checkout como sales_rep_id.
Parâmetros de caminho
tokenstringobrigatórioResposta
{ "enabled": false, "reps": [] }{
"enabled": true,
"reps": [
{ "id": 12, "name": "Vanessa Souza", "code": "VAN" },
{ "id": 15, "name": "Carlos Lima" }
],
"selected_id": 12,
"selected_source": "portfolio"
}Campos da resposta
enabledbooleanrepsarrayid (inteiro), name e code (opcional).selected_idintegerselected_sourcestringassistantportfolioFormas de pagamento disponíveis
/api/v1/storefront/wa-coex/payments/{token}/eligiblePúblicaFormas de pagamento que este cliente pode usar neste pedido
Lista só o que o checkout aceitaria para este cliente: respeita grupos de cliente, regras por cliente, limite de crédito e as formas que a loja ligou para o WhatsApp. Funciona com o token, sem login. Para cartão, passe order_total para receber as parcelas.
Parâmetros de caminho
tokenstringobrigatórioParâmetros de consulta
order_totalintegertotal_cents de /totals). Habilita parcelas do cartão e filtra métodos por valor mínimo e máximo.item_countintegerstatestringshipping_method_idstringcountrystringResposta
{
"methods": [
{
"id": "02000000-0000-0000-0000-000000000001",
"name": "PIX",
"code": "pix",
"processor_type": "online",
"gateway": "pix",
"status": "A",
"position": 1,
"uses_credit_limit": false,
"surcharge_fixed": 0,
"surcharge_percent": 0
},
{
"id": "02000000-0000-0000-0000-000000000010",
"name": "Pagamento na Entrega (COD)",
"code": "pagamento-na-entrega",
"processor_type": "offline",
"gateway": "",
"status": "A",
"position": 10,
"uses_credit_limit": false,
"surcharge_fixed": 0,
"surcharge_percent": 0
}
],
"total": 2
}Campos da resposta
methodsarrayFormas disponíveis, na ordem do painel.
codestringpayment_method. Pode ser também um apelido (pix, boleto, card).namestringprocessor_typestringonlineofflineonline é cobrado agora (Pix, cartão, boleto). offline é pago na entrega ou depois.gatewaystringpix, pagarme...). Vazio no offline.surcharge_fixedintegersurcharge_percentintegermin_order_amountintegermax_order_amount é o máximo.pix_discount_bpsintegerpix_expiry_minutesintegerinstallment_plansarrayorder_total informado.uses_credit_limitbooleancredit_limit_cents, credit_available_cents e credit_blocked (com credit_blocked_reason).iduuidtotalinteger