VenddorDocumentação API
API atualAPI legada
Guia rápidoReferência completa
Carregando índice…
API atual/Referência completa/Cotações e preços B2B

Negociação em rodadas

Contrapropostas, histórico e aceite ou recusa de rodadas de uma cotação B2B.

Quando o preço não fecha de primeira, comprador e seller trocam ofertas em rodadas. Cada rodada é uma proposta completa (linhas, quantidades e preços). Esta página cobre o lado do seller. As quatro rotas exigem o módulo enhanced-rfq ligado, além de b2b-pricing.

Fluxo típico

Leia o histórico, aceite a rodada pending do comprador ou envie uma contraproposta. Quem aceita fecha a cotação como accepted; o comprador então converte em carrinho ou pedido pelo lado da loja.

Status em letra ou nome

O status da rodada sai por extenso (pending, accepted...). O status da cotação também. Só os filtros aceitam as duas formas.

Enviar contraproposta

Abre uma nova rodada com as linhas, preços e quantidades que o seller propõe. A rodada anterior ainda pending vira countered, o total da cotação passa a ser o da nova rodada e o status da cotação vira negotiating. O limite é de 5 rodadas por cotação (max_rounds).

POST/api/v1/vendor/quotes/{id}/counterSeller

Nova rodada de negociação

Cabeçalhos

Authorizationstringobrigatório
Bearer $TOKEN. Token de acesso de um usuário seller (veja Tokens).
Content-Typestringobrigatório
application/json.

Parâmetros de caminho

idintegerobrigatório
Id da cotação (inteiro). Letras dão 400 invalid quote id.

Corpo da requisição

itemsobject[]obrigatório

Linhas da proposta. Pelo menos uma.

product_iduuidobrigatório
Produto.
quantityintegerobrigatório
Quantidade, 1 ou mais.
price_centsintegerobrigatório
Preço unitário em centavos, zero ou mais.
notesstring
Observação da linha.
messagestring
Mensagem para o comprador.
expires_atstring
Validade desta rodada, RFC 3339.

Exemplo de requisição

bash
curl -X POST "$BASE_URL/api/v1/vendor/quotes/69/counter" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "items": [
    {
      "product_id": "c7bc3778-2c79-4561-b9d7-979768f364c8",
      "quantity": 38,
      "price_cents": 4200
    }
  ],
  "message": "Consigo 38 unidades a R$ 42,00."
}'

Resposta

201Rodada criada
json
{
  "id": "08199264-d0cf-4eb9-a26d-7216f7c450ba",
  "quote_id": 69,
  "round_number": 2,
  "initiated_by": "vendor",
  "message": "Consigo 38 unidades a R$ 42,00.",
  "items": [
    {
      "product_id": "c7bc3778-2c79-4561-b9d7-979768f364c8",
      "product_name": "Notebook Plus Rosa",
      "quantity": 38,
      "price_cents": 4200
    }
  ],
  "total_cents": 159600,
  "status": "pending",
  "created_at": "2026-10-11T15:00:00Z"
}

Campos da resposta

iduuid
Id da rodada (UUID). É o roundId das rotas de aceitar e recusar.
quote_idinteger
Cotação da rodada.
round_numberinteger
Número da rodada, a partir de 1.
initiated_bystring
customervendoradmin
Quem fez a oferta.
messagestring
Mensagem que acompanha a oferta. Omitida se vazia.
itemsobject[]
Linhas da oferta: product_id, product_name, quantity, price_cents (unitário, centavos) e notes.
total_centsinteger
Total da rodada em centavos.
statusstring
pendingacceptedrejectedcounteredexpired
Situação da rodada.
expires_atstring|null
Validade da rodada, RFC 3339. Omitido se não definida.
created_atstring
Criação, RFC 3339 em UTC.

Erros

StatusQuandoCorpo de exemplo
400Falha de regra, com o motivo em detail: cotação fora de um estado negociável (pending, quoted ou negotiating), limite de rodadas, lista de itens vazia, quantidade menor que 1 ou preço negativo.{"error":"counter-offer failed","detail":"maximum negotiation rounds (5) exceeded"}
404A cotação não existe.{"error":"quote not found"}
403A cotação é de outro seller.{"error":"quote does not belong to this vendor"}
401Token ausente, inválido, expirado ou revogado.{"error":"missing authorization header"}
403O token não é de um usuário seller (por exemplo, é de administrador), ou o usuário não está vinculado a nenhum seller.{"error":"insufficient permissions"}
403O módulo b2b-pricing está desligado nesta loja.{"error":"module_disabled","module":"b2b-pricing"}
403O módulo enhanced-rfq está desligado nesta loja.{"error":"module_disabled","module":"enhanced-rfq"}

Histórico da negociação

Devolve o limite de rodadas, a rodada atual e todas as rodadas da cotação em ordem. Use para saber qual rodada está pending e pode ser aceita.

GET/api/v1/vendor/quotes/{id}/negotiationsSeller

Todas as rodadas da cotação

Cabeçalhos

Authorizationstringobrigatório
Bearer $TOKEN. Token de acesso de um usuário seller (veja Tokens).

Parâmetros de caminho

idintegerobrigatório
Id da cotação (inteiro). Letras dão 400 invalid quote id.

Exemplo de requisição

bash
curl "$BASE_URL/api/v1/vendor/quotes/69/negotiations" \
  -H "Authorization: Bearer $TOKEN"

Resposta

200Histórico
json
{
  "quote_id": 69,
  "max_rounds": 5,
  "current_round": 1,
  "rounds": [
    {
      "id": "08199264-d0cf-4eb9-a26d-7216f7c450ba",
      "quote_id": 69,
      "round_number": 1,
      "initiated_by": "customer",
      "message": "",
      "items": [
        {
          "product_id": "c7bc3778-2c79-4561-b9d7-979768f364c8",
          "product_name": "Notebook Plus Rosa",
          "quantity": 38,
          "price_cents": 4000
        }
      ],
      "total_cents": 152000,
      "status": "pending",
      "created_at": "2026-10-11T15:00:00Z"
    }
  ]
}

Campos da resposta

quote_idinteger
Cotação.
max_roundsinteger
Máximo de rodadas (5 por padrão).
current_roundinteger
Número da última rodada aberta. 0 se ninguém negociou.
expires_atstring|null
Validade da negociação, quando definida.
roundsobject[]

Rodadas, da primeira para a última.

iduuid
Id da rodada (UUID). É o roundId das rotas de aceitar e recusar.
quote_idinteger
Cotação da rodada.
round_numberinteger
Número da rodada, a partir de 1.
initiated_bystring
customervendoradmin
Quem fez a oferta.
messagestring
Mensagem que acompanha a oferta. Omitida se vazia.
itemsobject[]
Linhas da oferta: product_id, product_name, quantity, price_cents (unitário, centavos) e notes.
total_centsinteger
Total da rodada em centavos.
statusstring
pendingacceptedrejectedcounteredexpired
Situação da rodada.
expires_atstring|null
Validade da rodada, RFC 3339. Omitido se não definida.
created_atstring
Criação, RFC 3339 em UTC.

Erros

StatusQuandoCorpo de exemplo
400id não é um inteiro.{"error":"invalid quote id"}
404A cotação não existe.{"error":"quote not found"}
403A cotação é de outro seller.{"error":"quote does not belong to this vendor"}
401Token ausente, inválido, expirado ou revogado.{"error":"missing authorization header"}
403O token não é de um usuário seller (por exemplo, é de administrador), ou o usuário não está vinculado a nenhum seller.{"error":"insufficient permissions"}
403O módulo b2b-pricing está desligado nesta loja.{"error":"module_disabled","module":"b2b-pricing"}
403O módulo enhanced-rfq está desligado nesta loja.{"error":"module_disabled","module":"enhanced-rfq"}

Aceitar uma rodada

Aceita uma rodada pending: as outras rodadas pendentes viram rejected, as linhas da cotação passam a ter os preços e quantidades da rodada (linhas que ficaram de fora são apagadas, produtos novos entram) e a cotação vira accepted com o total da rodada. A plataforma não confere quem fez a oferta: o seller consegue aceitar até uma rodada criada por ele mesmo.

POST/api/v1/vendor/quotes/{id}/accept-round/{roundId}Seller

Aceitar a oferta de uma rodada

Cabeçalhos

Authorizationstringobrigatório
Bearer $TOKEN. Token de acesso de um usuário seller (veja Tokens).

Parâmetros de caminho

idintegerobrigatório
Id da cotação (inteiro). Letras dão 400 invalid quote id.
roundIduuidobrigatório
Id da rodada (campo id de uma rodada de negotiations).

Exemplo de requisição

bash
curl -X POST "$BASE_URL/api/v1/vendor/quotes/69/accept-round/08199264-d0cf-4eb9-a26d-7216f7c450ba" \
  -H "Authorization: Bearer $TOKEN"

Resposta

200Rodada aceita
json
{
  "message": "round accepted"
}

Erros

StatusQuandoCorpo de exemplo
400Rodada inexistente na cotação ou que não está pending. O motivo vem em detail.{"error":"failed to accept round","detail":"round is not in pending status (current: A)"}
422A trava de margem da loja bloqueou: algum preço da rodada fica abaixo do piso de margem. O corpo é o veredito da trava.{"ok":false,"floor_bps":1500,"reason":"below_floor"}
404A cotação não existe.{"error":"quote not found"}
403A cotação é de outro seller.{"error":"quote does not belong to this vendor"}
401Token ausente, inválido, expirado ou revogado.{"error":"missing authorization header"}
403O token não é de um usuário seller (por exemplo, é de administrador), ou o usuário não está vinculado a nenhum seller.{"error":"insufficient permissions"}
403O módulo b2b-pricing está desligado nesta loja.{"error":"module_disabled","module":"b2b-pricing"}
403O módulo enhanced-rfq está desligado nesta loja.{"error":"module_disabled","module":"enhanced-rfq"}

Recusar uma rodada

Marca a rodada pending como rejected. O motivo é opcional e é anexado à mensagem da rodada. Diferente de recusar a cotação, a negociação continua possível: você ou o comprador podem abrir outra rodada.

POST/api/v1/vendor/quotes/{id}/reject-round/{roundId}Seller

Recusar a oferta de uma rodada

Cabeçalhos

Authorizationstringobrigatório
Bearer $TOKEN. Token de acesso de um usuário seller (veja Tokens).
Content-Typestringobrigatório
application/json.

Parâmetros de caminho

idintegerobrigatório
Id da cotação (inteiro). Letras dão 400 invalid quote id.
roundIduuidobrigatório
Id da rodada (campo id de uma rodada de negotiations).

Corpo da requisição

reasonstring
Motivo da recusa. Opcional; um corpo ausente ou inválido é ignorado.

Exemplo de requisição

bash
curl -X POST "$BASE_URL/api/v1/vendor/quotes/69/reject-round/08199264-d0cf-4eb9-a26d-7216f7c450ba" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "reason": "Abaixo do nosso custo."
}'

Resposta

200Rodada recusada
json
{
  "message": "round rejected"
}

Erros

StatusQuandoCorpo de exemplo
400Rodada inexistente na cotação ou que não está pending.{"error":"failed to reject round","detail":"negotiation round not found"}
404A cotação não existe.{"error":"quote not found"}
403A cotação é de outro seller.{"error":"quote does not belong to this vendor"}
401Token ausente, inválido, expirado ou revogado.{"error":"missing authorization header"}
403O token não é de um usuário seller (por exemplo, é de administrador), ou o usuário não está vinculado a nenhum seller.{"error":"insufficient permissions"}
403O módulo b2b-pricing está desligado nesta loja.{"error":"module_disabled","module":"b2b-pricing"}
403O módulo enhanced-rfq está desligado nesta loja.{"error":"module_disabled","module":"enhanced-rfq"}

Veja também

  • Cotações
  • Visão geral da seção
Anterior
Cotações
Próxima
Regras de preço B2B
Nesta página
  • Enviar contraproposta
  • Exemplo de requisição
  • Resposta
  • Erros
  • Histórico da negociação
  • Exemplo de requisição
  • Resposta
  • Erros
  • Aceitar uma rodada
  • Exemplo de requisição
  • Resposta
  • Erros
  • Recusar uma rodada
  • Exemplo de requisição
  • Resposta
  • Erros
  • Veja também