Proposta do representante
O cliente abre a proposta comercial que um representante da loja enviou, aceita (vira pedido) ou pede alterações.
Em lojas B2B, um representante comercial (vendedor da loja) monta uma proposta para o cliente: itens, preço combinado, frete, forma de pagamento e validade. O cliente recebe no WhatsApp uma mensagem com um botão. Ele abre a mini-loja já logada, vê a proposta e responde: aceita (a proposta vira pedido) ou pede alterações (o representante é avisado com o texto).
A proposta é identificada por um código curto (code), o que vai no botão. O token identifica o cliente: uma proposta feita para outro cliente responde 404 proposal_closed com reason: "not_yours".
As três rotas só existem em lojas com o módulo de representantes ligado. Nas outras respondem 404 proposals_unavailable.
Ver a proposta
/api/v1/storefront/wa-coex/proposal/{token}/{code}PúblicaAbre a proposta como o cliente a vê
Parâmetros de caminho
tokenstringobrigatóriocodestringobrigatórioExemplo de requisição
curl "$BASE_URL/api/v1/storefront/wa-coex/proposal/$TOKEN/K7QX2M"Resposta
{
"proposal": {
"proposal_id": "c0a8d6f2-4e55-4c06-8f0e-2a1b5d9e7c10",
"code": "K7QX2M",
"status": "sent",
"rep_name": "Carlos Lima",
"customer_name": "Distribuidora Aurora",
"valid_until": "2026-10-20T23:59:59Z",
"note": "Condição válida para pedido fechado até sexta.",
"lines": [
{
"product_id": "c3f92551-9dda-4fc7-b518-353d1c4e4035",
"name": "Notebook Slim Rosa",
"image_url": "/uploads/exemplo/notebook.png",
"quantity": 10,
"unit_cents": 8500,
"list_unit_cents": 9200,
"line_total_cents": 85000,
"agreed": true
}
],
"items_total_cents": 85000,
"list_total_cents": 92000,
"savings_cents": 7000,
"shipping_cents": 4500,
"shipping_label": "Entrega Padrão",
"payment_label": "Boleto faturado 30 dias",
"address_label": "Avenida Paulista, 1000, São Paulo/SP",
"total_cents": 89500,
"requires_approval": false
}
}Campos da resposta
proposalobjectA proposta.
proposal_iduuidcode é o código curto.statusstringdraftsentacceptedconvertedcancelledexpiredchanges_requestedsent; converted quer dizer que já virou pedido.rep_namestringcustomer_namestringvalid_untilstringnotestringlinesarrayproduct_id, name, image_url, quantity, unit_cents (preço combinado), list_unit_cents (preço de hoje do cliente, sem o corte do representante), line_total_cents e agreed (a linha tem preço combinado).items_total_centsintegerlist_total_centsintegersavings_centsintegershipping_centsintegershipping_label é o nome da entrega.payment_labelstringaddress_labelstringtotal_centsintegerrequires_approvalbooleanwarningstringErros
| Status | Quando | Corpo |
|---|---|---|
| 404 | A loja não usa propostas de representante. | {"error":"proposals_unavailable"} |
| 404 | Código inexistente, ou proposta de outro cliente. | {"error":"proposal_closed","reason":"not_found"} ou {"error":"proposal_closed","reason":"not_yours"} |
| 410 | A proposta não pode mais ser respondida. | {"error":"proposal_closed","reason":"expired"}, "used", "withdrawn" ou "answered" (com order_id quando já virou pedido) |
| 503 | Falha ao ler a proposta. | {"error":"proposal_unavailable"} |
Aceitar a proposta
/api/v1/storefront/wa-coex/proposal/{token}/{code}/acceptPúblicaAceita a proposta e cria o pedido
Cria o pedido com as condições combinadas. É idempotente: aceitar de novo uma proposta que já virou pedido devolve o mesmo pedido, com already_placed: true, sem criar outro. O representante é avisado do aceite.
Parâmetros de caminho
tokenstringobrigatóriocodestringobrigatórioNão tem corpo.
Resposta
{
"result": {
"proposal_id": "c0a8d6f2-4e55-4c06-8f0e-2a1b5d9e7c10",
"status": "created",
"order_id": "9f4a6d2e-1b7c-4c53-8d21-5e0b6a7c1f33",
"order_number": "1050",
"total_cents": 89500,
"requires_approval": false
}
}{
"result": {
"proposal_id": "c0a8d6f2-4e55-4c06-8f0e-2a1b5d9e7c10",
"status": "rejected",
"reason": "order_failed",
"message": "Não foi possível fechar este pedido agora. Seu representante foi avisado."
}
}Campos da resposta
resultobjectResultado do aceite.
statusstringcreatedrejectedcreated: o pedido existe (criado agora ou já existente). rejected: o pedido não pôde ser criado e a proposta volta a aguardar resposta.reasonstringrejected: o código que o fechamento do pedido devolveu (crédito, pagamento, preço...) ou order_failed quando não há código.messagestringrejected.order_iduuidorder_number é o número e total_cents o total.already_placedbooleantrue quando a proposta já era um pedido.requires_approvalbooleanErros
| Status | Quando | Corpo |
|---|---|---|
| 404 | A loja não usa propostas, ou o código não existe ou é de outro cliente. | {"error":"proposals_unavailable"} ou {"error":"proposal_closed","reason":"not_found"} |
| 410 | A proposta venceu, foi usada, retirada ou já respondida. | {"error":"proposal_closed","reason":"expired"} e semelhantes |
| 422 | O pedido não pôde ser criado. O corpo é o result acima, com status: "rejected". | {"result":{"status":"rejected",...}} |
| 503 | Falha ao processar. | {"error":"proposal_unavailable"} |
Pedir alterações
/api/v1/storefront/wa-coex/proposal/{token}/{code}/changesPúblicaRecusa a proposta e pede alterações ao representante
O cliente diz o que quer mudar. A proposta deixa de aguardar o aceite e o representante recebe o texto no WhatsApp para ajustar e enviar de novo.
Parâmetros de caminho
tokenstringobrigatóriocodestringobrigatórioCorpo da requisição
feedbackstringExemplo de requisição
curl -X POST "$BASE_URL/api/v1/storefront/wa-coex/proposal/$TOKEN/K7QX2M/changes" \
-H "Content-Type: application/json" \
-d '{"feedback":"Preciso de prazo de 45 dias e frete grátis."}'Resposta
{
"result": {
"proposal_id": "c0a8d6f2-4e55-4c06-8f0e-2a1b5d9e7c10",
"feedback": "Preciso de prazo de 45 dias e frete grátis."
}
}Campos da resposta
resultobjectproposal_id e feedback (o texto como foi gravado).Erros
| Status | Quando | Corpo |
|---|---|---|
| 400 | Corpo que não é JSON válido. | {"error":"invalid body"} |
| 404 | A loja não usa propostas, ou o código não existe ou é de outro cliente. | {"error":"proposals_unavailable"} ou {"error":"proposal_closed","reason":"not_found"} |
| 410 | A proposta não pode mais ser respondida. | {"error":"proposal_closed","reason":"expired"} e semelhantes |
| 503 | Falha ao processar. | {"error":"proposal_unavailable"} |