Faixas de preço por quantidade
Lê, substitui e acrescenta as faixas de preço por quantidade de um produto, com preço fixo ou percentual e público por grupo de usuário.
Uma faixa de preço (em inglês, price tier) é um preço especial que vale quando o cliente compra a partir de uma certa quantidade: "de 10 unidades por R$ 45,00 cada, de 50 unidades 20% de desconto". É a forma de vender no atacado dentro da mesma loja. Cada faixa pode valer para todos os clientes ou só para um público: visitantes, clientes logados ou um grupo de usuários específico.
Leitura exige view_catalog ou manage_catalog; escrita exige manage_catalog. Todo valor em dinheiro é inteiro em centavos (4500 = R$ 45,00).
Como as faixas valem
Quem enxerga e usa cada faixa
O campo usergroup_id diz para quem a faixa vale:
usergroup_id | Vale para |
|---|---|
null (ou omitido, ou texto vazio) | Todos os clientes, inclusive visitantes. |
"guest" | Só visitantes (sem login). |
"registered" | Qualquer cliente com login. |
| UUID de um grupo de usuários | Só os membros desse grupo. |
A API não confere se o UUID é de um grupo que existe nem se o texto é um dos valores acima: um valor qualquer é gravado e a faixa simplesmente nunca é usada. Confira o grupo antes de enviar.
Preço fixo ou percentual
percentage_discountigual a 0: o preço unitário da faixa é o campoprice.percentage_discountmaior que 0 (de 0 a 100): o preço unitário é o preço do produto menos esse percentual, calculado na hora da compra. O campopriceé ignorado nesse cálculo. Valores acima de 100 viram 100 e negativos viram 0.
Qual faixa vence
Na compra, a plataforma junta as faixas que servem ao cliente (quantidade do pedido maior ou igual a lower_limit, e público compatível: faixas gerais, as de visitante ou de logado conforme o caso, e as dos grupos do cliente) e escolhe uma:
- Regra padrão da loja: a de menor preço unitário.
- Regra alternativa ("maior quantidade atingida"): a faixa com o maior
lower_limitalcançado; entre faixas com o mesmolower_limit, a mais barata.
Em qualquer regra, se o resultado não for menor que o preço do produto, a faixa não é aplicada. Qual regra a loja usa é uma configuração da loja.
Uma faixa por combinação
Só existe uma faixa por combinação de produto, lower_limit e público. Enviar de novo a mesma combinação atualiza a faixa existente (o id não muda), tanto no POST quanto no PUT.
A faixa base e o preço do produto
A faixa com lower_limit 1 e sem público é o preço de balcão do produto. Quando você a grava com PUT, a plataforma também atualiza o campo price do produto, já descontado o percentage_discount dela. O POST não faz isso.
Consultar as faixas
/api/v1/admin/products/{id}/price-tiersAdminLista as faixas de preço de um produto
Devolve todas as faixas do produto, sem filtrar por público, e o preço base atual.
Path parameters
iduuidobrigatórioExemplo de requisição
curl "$BASE_URL/api/v1/admin/products/$PRODUCT_ID/price-tiers" \
-H "Authorization: Bearer $TOKEN"Resposta
{
"product_id": "c3f92551-9dda-4fc7-b518-353d1c4e4035",
"base_price": 4990,
"tiers": [
{
"id": "853cd706-4367-4ec7-bc9d-17a1ab493b3b",
"product_id": "c3f92551-9dda-4fc7-b518-353d1c4e4035",
"lower_limit": 10,
"price": 4400,
"percentage_discount": 0,
"usergroup_id": null,
"created_at": "2026-10-11T20:55:43.329333Z"
},
{
"id": "679006f5-3e81-4138-8743-d140ae063fff",
"product_id": "c3f92551-9dda-4fc7-b518-353d1c4e4035",
"lower_limit": 50,
"price": 0,
"percentage_discount": 20,
"usergroup_id": null,
"created_at": "2026-10-11T20:55:43.341064Z"
},
{
"id": "16a61629-19a7-46c7-b5c6-2b2a279d7962",
"product_id": "c3f92551-9dda-4fc7-b518-353d1c4e4035",
"lower_limit": 5,
"price": 4700,
"percentage_discount": 0,
"usergroup_id": "registered",
"value_per_unit": 470,
"created_at": "2026-10-11T20:55:43.363483Z"
}
]
}Response fields
product_iduuidbase_priceintegertiersarrayAs faixas, agrupadas por público (as gerais primeiro) e, dentro de cada grupo, por lower_limit crescente. Lista vazia se não há faixas.
iduuidproduct_iduuidlower_limitintegerpriceintegerpercentage_discount é maior que 0.percentage_discountnumber0 significa "use price".usergroup_idstringnull (todos), "guest", "registered" ou o UUID de um grupo de usuários.value_per_kgintegervalue_per_unitintegercreated_atstringErros
| Status | Quando | Corpo |
|---|---|---|
| 401 | Sem token. | {"error":"missing authorization header"} |
| 403 | Sem view_catalog nem manage_catalog. | {"error":"insufficient privileges","privilege_required_any":["manage_catalog","view_catalog"]} |
| 404 | Produto inexistente ou na lixeira. | {"error":"product not found"} |
| 500 | O id não é um UUID válido. | {"error":"failed to get price tiers","detail":"..."} |
Substituir todas as faixas
/api/v1/admin/products/{id}/price-tiersAdminSubstitui todas as faixas de preço de um produto
Exige manage_catalog. Apaga todas as faixas atuais do produto e grava as que você enviou. Use quando seu sistema é a fonte da tabela de preços e você sempre manda a tabela completa. Se uma das faixas for a base (lower_limit 1, sem público), o preço do produto também é atualizado.
Path parameters
iduuidobrigatórioCorpo da requisição
tiersarrayobrigatórioAs faixas novas. Uma lista vazia ([]) apaga todas as faixas e não altera o preço do produto.
lower_limitintegerobrigatóriopriceintegerobrigatóriopercentage_discount.percentage_discountnumberpadrão: 0price.usergroup_idstringnull para todos, "guest", "registered" ou o UUID de um grupo.value_per_kgintegervalue_per_unitintegerExemplo de requisição
curl -X PUT "$BASE_URL/api/v1/admin/products/$PRODUCT_ID/price-tiers" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tiers": [
{
"lower_limit": 1,
"price": 4990
},
{
"lower_limit": 10,
"price": 4500
},
{
"lower_limit": 50,
"price": 0,
"percentage_discount": 20
},
{
"lower_limit": 5,
"price": 4700,
"usergroup_id": "registered"
}
]
}'Resposta
{
"product_id": "c3f92551-9dda-4fc7-b518-353d1c4e4035",
"base_price": 4990,
"tiers": [
{ "id": "c6601ef1-2128-4f8a-8ed3-71915c1f3935", "product_id": "c3f92551-9dda-4fc7-b518-353d1c4e4035", "lower_limit": 1, "price": 4990, "percentage_discount": 0, "usergroup_id": null, "created_at": "2026-10-11T20:55:50.175033Z" },
{ "id": "1a5bc3a3-4181-4dd8-9716-d05594c79a49", "product_id": "c3f92551-9dda-4fc7-b518-353d1c4e4035", "lower_limit": 10, "price": 4500, "percentage_discount": 0, "usergroup_id": null, "created_at": "2026-10-11T20:55:50.179409Z" },
{ "id": "d2b7f610-5a39-4c1e-8f0a-93e6c4d1a7b2", "product_id": "c3f92551-9dda-4fc7-b518-353d1c4e4035", "lower_limit": 50, "price": 0, "percentage_discount": 20, "usergroup_id": null, "created_at": "2026-10-11T20:55:50.183772Z" },
{ "id": "fcec9695-cb16-419c-82a0-8ce59d7e1d6d", "product_id": "c3f92551-9dda-4fc7-b518-353d1c4e4035", "lower_limit": 5, "price": 4700, "percentage_discount": 0, "usergroup_id": "registered", "created_at": "2026-10-11T20:55:50.181042Z" }
]
}A resposta é a visão de administração completa, igual à da consulta. Os ids das faixas mudam a cada PUT, porque as faixas são recriadas.
Erros
| Status | Quando | Corpo |
|---|---|---|
| 400 | Corpo inválido. | {"error":"invalid request body","detail":"..."} |
| 404 | Produto inexistente. | {"error":"product not found"} |
| 500 | O id não é um UUID válido, ou outra falha ao gravar. | {"error":"failed to set price tiers","detail":"..."} |
| 401 / 403 | Sem token / sem manage_catalog. | {"error":"insufficient privileges","required":"manage_catalog"} |
Acrescentar ou atualizar uma faixa
/api/v1/admin/products/{id}/price-tiersAdminAdiciona ou atualiza uma faixa de preço
Exige manage_catalog. Grava uma faixa sem mexer nas outras. Se já existir uma faixa com o mesmo lower_limit e o mesmo público, ela é atualizada (resposta 201 com o mesmo id). Diferente do PUT, não altera o preço do produto, mesmo para lower_limit 1.
Path parameters
iduuidobrigatórioCorpo da requisição
lower_limitintegerobrigatóriopriceintegerobrigatóriopercentage_discountnumberpadrão: 0price.usergroup_idstringnull para todos, "guest", "registered" ou o UUID de um grupo.value_per_kgintegervalue_per_unitintegerExemplo de requisição
curl -X POST "$BASE_URL/api/v1/admin/products/$PRODUCT_ID/price-tiers" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"lower_limit": 10,
"price": 4500
}'Resposta
{
"id": "853cd706-4367-4ec7-bc9d-17a1ab493b3b",
"product_id": "c3f92551-9dda-4fc7-b518-353d1c4e4035",
"lower_limit": 10,
"price": 4500,
"percentage_discount": 0,
"usergroup_id": null,
"created_at": "2026-10-11T20:55:43.329333Z"
}Os campos são os da consulta, para a faixa gravada.
Erros
| Status | Quando | Corpo |
|---|---|---|
| 400 | Corpo inválido. | {"error":"invalid request body","detail":"..."} |
| 400 | lower_limit ausente ou menor que 1. | {"error":"lower_limit must be at least 1"} |
| 500 | O produto não existe (diferente do GET e do PUT, que respondem 404) ou o id não é UUID. | {"error":"failed to add price tier","detail":"..."} |
| 401 / 403 | Sem token / sem manage_catalog. | {"error":"insufficient privileges","required":"manage_catalog"} |
Veja também
- Preço e estoque do produto: visão geral e o mapa das rotas.
- Estoque do produto
- Atualizar produto: o preço base do produto.
- Produtos: dinheiro em centavos, ids e status.