Negociações (RFQ)
Acompanha as contrapropostas em rodadas entre cliente e seller e registra a mediação do administrador.
Quando o cliente não aceita o preço da cotação, comprador e seller podem trocar contrapropostas em rodadas (até um máximo, padrão de 5). Cada rodada traz os itens e os preços propostos por um dos lados. O administrador não negocia por eles, mas pode acompanhar o histórico e registrar uma nota quando está mediando.
Listar negociações
Mesma lista de cotações, com os dados da negociação em rodadas: em que rodada está, o máximo de rodadas, se o administrador está mediando e a nota dele.
/api/v1/admin/rfq/negotiationsAdminLista as cotações com os dados da negociação
Autenticação: Authorization: Bearer <token> de um administrador com manage_orders. Requer o módulo enhanced-rfq ativo.
Parâmetros de consulta
statusstringvendor_iduuiduser_iduuidpageintegerpadrão: 1per_pageintegerpadrão: 20Exemplo de requisição
curl "$BASE_URL/api/v1/admin/rfq/negotiations?status=negotiating" \
-H "Authorization: Bearer $TOKEN"Resposta
{
"quotes": [
{
"id": 69,
"user_id": "220b672c-90fe-4841-ae86-bd4f1ace982e",
"vendor_id": "94bd7e9a-fdad-4d01-8fc2-ba9d677d8b36",
"status": "negotiating",
"notes": "Preciso de 5 unidades para o escritório novo",
"vendor_notes": "Prazo de entrega de 7 dias",
"total_cents": 20000,
"valid_until": "2026-11-10T07:04:19Z",
"created_at": "2026-10-01T07:01:32Z",
"updated_at": "2026-10-02T09:00:00Z",
"user_email": "ana.souza@example.com",
"user_name": "Ana Souza",
"vendor_name": "Loja Seller Teste",
"item_count": 1,
"max_rounds": 5,
"current_round": 1,
"admin_mediated": false
}
],
"total": 1,
"page": 1,
"per_page": 20,
"total_pages": 1
}Campos da resposta
quotesarrayquotes[].max_roundsinteger5.quotes[].current_roundinteger0 se ainda não houve negociação.quotes[].negotiation_expires_atstringquotes[].admin_mediatedbooleanquotes[].admin_notesstringtotalintegerpageintegerper_pageintegertotal_pagesintegerErros
| Status | Quando | Corpo |
|---|---|---|
| 401 | Sem token ou token inválido | {"error":"missing authorization header"} |
| 403 | Sem o privilégio exigido, ou módulo desligado | {"error":"module_disabled","module":"enhanced-rfq"} / {"error":"insufficient privileges","required":"manage_orders"} |
| 500 | Falha na consulta | {"error":"failed to list negotiations","detail":"..."} |
Consultar uma negociação
Devolve a cotação completa, todas as rodadas de contraproposta em ordem e a anotação do administrador.
/api/v1/admin/rfq/negotiations/{id}AdminConsulta a cotação, o histórico de rodadas e a nota
Autenticação: Authorization: Bearer <token> de um administrador com manage_orders. Requer o módulo enhanced-rfq ativo.
Parâmetros de caminho
idintegerobrigatórioExemplo de requisição
curl "$BASE_URL/api/v1/admin/rfq/negotiations/69" \
-H "Authorization: Bearer $TOKEN"Resposta
{
"quote": {
"id": 69,
"user_id": "220b672c-90fe-4841-ae86-bd4f1ace982e",
"vendor_id": "94bd7e9a-fdad-4d01-8fc2-ba9d677d8b36",
"status": "negotiating",
"notes": "Preciso de 5 unidades para o escritório novo",
"vendor_notes": "Prazo de entrega de 7 dias",
"total_cents": 20000,
"valid_until": "2026-11-10T07:04:19Z",
"created_at": "2026-10-01T07:01:32Z",
"updated_at": "2026-10-02T09:00:00Z",
"user_email": "ana.souza@example.com",
"user_name": "Ana Souza",
"vendor_name": "Loja Seller Teste",
"item_count": 1,
"items": [
{
"id": 98,
"quote_id": 69,
"product_id": "c7bc3778-2c79-4561-b9d7-979768f364c8",
"quantity": 5,
"offered_price_cents": 4000,
"notes": "",
"product_name": "Notebook Plus Rosa",
"product_sku": "SD-000507",
"product_price": 6990
}
]
},
"history": {
"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",
"items": [
{
"product_id": "c7bc3778-2c79-4561-b9d7-979768f364c8",
"product_name": "Notebook Plus Rosa",
"quantity": 5,
"price_cents": 4000
}
],
"total_cents": 20000,
"status": "pending",
"created_at": "2026-10-01T07:19:03Z"
}
]
},
"annotation": {
"notes": "",
"admin_mediated": true,
"admin_updated_at": "2026-10-02T08:15:18Z"
}
}Campos da resposta
quoteobjectitems, como em Consultar uma cotação.history.quote_idintegerhistory.max_roundsintegerhistory.current_roundintegerhistory.expires_atstringhistory.roundsarrayhistory.rounds[].iduuidhistory.rounds[].round_numberintegerhistory.rounds[].initiated_bystringcustomervendoradmincustomer, vendor ou admin.history.rounds[].messagestringhistory.rounds[].itemsarrayproduct_id, product_name, quantity, price_cents (unitário) e notes.history.rounds[].total_centsintegerhistory.rounds[].statusstringpendingacceptedrejectedcounteredexpiredpending, accepted, rejected, countered ou expired.history.rounds[].created_atstringannotationobject | nullnotes, admin_mediated e admin_updated_at.Erros
| Status | Quando | Corpo |
|---|---|---|
| 401 | Sem token ou token inválido | {"error":"missing authorization header"} |
| 403 | Sem o privilégio exigido, ou módulo desligado | {"error":"module_disabled","module":"enhanced-rfq"} / {"error":"insufficient privileges","required":"manage_orders"} |
| 400 | id que não é número | {"error":"invalid quote id"} |
| 404 | Cotação inexistente | {"error":"quote not found"} |
Anotar uma negociação
O administrador registra uma nota interna sobre a negociação e, se quiser, marca que está mediando. Não altera preços, rodadas nem o estado da cotação: é só anotação.
/api/v1/admin/rfq/negotiations/{id}AdminGrava a nota do administrador e a marca de mediação
Autenticação: Authorization: Bearer <token> de um administrador com manage_orders. Requer o módulo enhanced-rfq ativo.
Parâmetros de caminho
idintegerobrigatórioCorpo da requisição
notesstringadmin_mediatedbooleanExemplo de requisição
curl -X PATCH "$BASE_URL/api/v1/admin/rfq/negotiations/69" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"notes": "Cliente pediu 8% de desconto; seller topou 5%",
"admin_mediated": true
}'Resposta
{
"notes": "Cliente pediu 8% de desconto; seller topou 5%",
"admin_mediated": true,
"admin_updated_at": "2026-10-11T21:40:00Z"
}Campos da resposta
notesstringadmin_mediatedbooleanadmin_updated_atstringErros
| Status | Quando | Corpo |
|---|---|---|
| 401 | Sem token ou token inválido | {"error":"missing authorization header"} |
| 403 | Sem o privilégio exigido, ou módulo desligado | {"error":"module_disabled","module":"enhanced-rfq"} / {"error":"insufficient privileges","required":"manage_orders"} |
| 400 | id que não é número ou corpo inválido | {"error":"invalid quote id"} |
| 500 | Falha ao gravar | {"error":"failed to annotate quote","detail":"..."} |