Preços
Tabela de preços do produto. Dois modelos: único (default) ou progressivo por quantidade (wholesale, até 5 faixas).
Pré-requisitos: leia Produtos: visão geral. O
price_typeé definido no próprio produto (POST /api/products); este guia trata só da tabela de preços por trás dele.
Conceitos
price_type vive no produto e dita o comportamento da tabela:
price_type | Faixas permitidas | min_quantity |
|---|---|---|
default | Exatamente 1 | Sempre 1 |
wholesale | 1 a 5 progressivas | 1, depois valores crescentes |
Faixa é cada linha da tabela: par (min_quantity, price). A faixa que vale numa venda é a de maior min_quantity cujo valor é ≤ quantidade comprada.
A chave de cada faixa é o min_quantity. É por isso que PUT e DELETE recebem ele no path.
Quer voltar de
wholesaleparadefault? Só depois de deixar uma faixa só. Como odefaulté, por definição, uma tabela de uma linha, a plataforma não tem como adivinhar qual das suas faixas de atacado deve sobreviver — então a decisão fica com você: apague as faixas extras primeiro e aí a troca é liberada.
GET /products/{id}/prices devolve sempre um array de faixas — o que muda é o conteúdo conforme o price_type.
Padrão (default) — exatamente 1 faixa, sem medidas:
[
{
"min_quantity": 1, // sempre 1 no default
"value": 89.9, // preço unitário único
"discount_percent": null, // não se aplica
"package_weight": null, // medidas ficam null no default
"package_height": null,
"package_width": null,
"package_length": null
}
]Atacado (wholesale) — 1 a 5 faixas progressivas, cada uma com as medidas da embalagem:
[
{
"min_quantity": 1, // faixa base: preço e medidas de UMA unidade
"value": 50.0,
"discount_percent": null, // no atacado automático a base fica 0; o % vai nas faixas seguintes
"package_weight": 1.2,
"package_height": 10.0,
"package_width": 12.0,
"package_length": 15.0
},
{
"min_quantity": 10, // faixa de atacado: a partir de 10 un
"value": 45.0, // preço unitário menor
"discount_percent": null,
"package_weight": 12.5, // medidas da EMBALAGEM fechada
"package_height": 30.0,
"package_width": 40.0,
"package_length": 50.0
}
]Preço padrão (default)
Produto vendido por valor unitário. Uma única faixa, sempre com min_quantity = 1.
Criar
{
"min_quantity": 1,
"price": 89.90
}Atualizar
PUT/api/products/{id}/prices/1
{
"price": 79.90
}Preço de atacado (wholesale)
Tabela progressiva por volume, até 5 faixas. Cada faixa tem o preço unitário vendido a partir daquela quantidade.
Recomendado: precifique por desconto (
%), não por valor fixo. Ligando oauto_wholesale_pricing, você informa só odiscount_percentde cada faixa e deixa o preço ser derivado do preço base. A gestão fica automática: você reajusta o preço base num lugar só e todas as faixas se recalculam sozinhas — sem reabrir faixa por faixa e sem risco de a tabela ficar inconsistente. Os dois modos estão documentados abaixo, mas comece pelo Atacado automático.
Exemplo de tabela montada:
| Faixa | min_quantity | price (unitário) | Quando vale |
|---|---|---|---|
| 1 | 1 | R$ 50,00 | 1 a 9 unidades |
| 2 | 10 | R$ 45,00 | 10 a 49 unidades |
| 3 | 50 | R$ 40,00 | 50 unidades ou mais |
A faixa base (min_quantity = 1) é sempre o preço unitário. As faixas de atacado são as de min_quantity ≥ 2.
Medidas da embalagem (obrigatórias)
Toda faixa de atacado representa uma embalagem fechada (caixa/fardo) — é com ela que a plataforma calcula o frete da venda fracionada. Por isso, a primeira faixa de atacado precisa trazer as medidas completas da embalagem:
| Campo | Unidade | Regra |
|---|---|---|
package_weight | kg | > 0 |
package_height | cm | > 0 |
package_width | cm | > 0 |
package_length | cm | > 0 |
Os quatro campos são tudo-ou-nada: ou você manda os quatro, ou nenhum. Mandar só parte deles é recusado com 422.
Depois que existe uma faixa medida, as faixas seguintes podem ser criadas sem as medidas — elas herdam a embalagem de referência. O produto só não pode ficar sem nenhuma faixa medida: por isso a remoção da última faixa com medidas (havendo outras faixas dependendo dela) também é recusada com 422.
A faixa base (
min_quantity = 1) carrega as medidas de uma unidade (o produto avulso); as faixas de atacado (min_quantity ≥ 2) carregam as medidas da embalagem fechada vendida naquela faixa. Assim o frete sai correto tanto na venda unitária quanto no fardo.
Adicionar uma faixa (modo manual)
No modo manual você informa o price de cada faixa diretamente — e fica responsável por reajustar faixa a faixa quando o preço mudar. (Para uma gestão mais simples, prefira o Atacado automático — a abordagem recomendada — em que você precifica por desconto.)
Faixa base (min_quantity = 1) — só o preço. As medidas de uma unidade vivem no cadastro do produto (dimensions, ver Produtos: visão geral) e são apenas projetadas na leitura da faixa base — enviar package_* aqui não tem efeito:
{
"min_quantity": 1,
"price": 50.00
}Primeira faixa de atacado — com as medidas da embalagem fechada:
{
"min_quantity": 10,
"price": 45.00,
"package_weight": 12.5,
"package_height": 30.0,
"package_width": 40.0,
"package_length": 50.0
}Faixas seguintes podem omitir as medidas (herdam a referência):
{
"min_quantity": 50,
"price": 40.00
}Reajustar uma faixa existente
PUT/api/products/{id}/prices/10
O corpo aceita o price e/ou as medidas. O merge parcial vale só para as medidas e o discount_percent — o price não: se você não mandar, ele é zerado (no modo manual e na faixa base). Sempre reenvie o price no PUT.
{
"price": 42.50
}Remover uma faixa
DELETE/api/products/{id}/prices/10
Atacado automático
É a abordagem recomendada para o atacado: o preço passa a ser gerido num ponto só, o que mantém a tabela sempre coerente.
O produto tem um interruptor auto_wholesale_pricing (definido no próprio produto, junto do price_type). Quando ligado, você para de informar o price das faixas de atacado e passa a informar só o desconto (discount_percent) — o preço de cada faixa é derivado do preço unitário base menos o desconto.
O discount_percent é sempre relativo ao preço base. O que fica salvo na faixa é o desconto, não um valor fixo: por isso, se você mudar o preço base, todas as faixas de atacado são recalculadas aplicando de novo o desconto de cada uma. Você ajusta o preço num lugar só.
Exemplo: preço base R$ 50,00, faixa de 50 un com discount_percent: 20 → preço da faixa = R$ 40,00. Se depois o base virar R$ 60,00, a mesma faixa passa sozinha para R$ 48,00.
Regras desse modo:
- O preço base (
min_quantity = 1) precisa existir antes de criar faixas de atacado — é dele que sai o cálculo. Sem ele, a API responde422. - O
discount_percentvai de0a menos de100. - Os descontos precisam ser progressivos: faixa de quantidade maior exige desconto maior que a anterior (o preço sempre cai conforme a quantidade sobe). Caso contrário,
422.
Faixa de atacado por desconto (em vez de price):
{
"min_quantity": 50,
"discount_percent": 20,
"package_weight": 12.5,
"package_height": 30.0,
"package_width": 40.0,
"package_length": 50.0
}Comparando os dois modos para a mesma faixa: no manual você manda
"price": 40.00; no automático você manda"discount_percent": 20e a API calcula o preço a partir do base. No modo manual odiscount_percenté ignorado.
Listar a tabela
{
"success": true,
"message_code": "SUCCESS",
"data": [
{
"value": 50.00,
"min_quantity": 1,
"discount_percent": null,
"package_weight": 1.2,
"package_height": 10.0,
"package_width": 12.0,
"package_length": 15.0
},
{
"value": 45.00,
"min_quantity": 10,
"discount_percent": null,
"package_weight": 12.5,
"package_height": 30.0,
"package_width": 40.0,
"package_length": 50.0
}
]
}Cada faixa traz o valor (value), o min_quantity, o discount_percent (preenchido no atacado automático) e as medidas da embalagem. Já vem ordenado por min_quantity ascendente, pronto pra renderizar na tela do comprador.

