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_typeFaixas permitidasmin_quantity
defaultExatamente 1Sempre 1
wholesale1 a 5 progressivas1, 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 wholesale para default? Só depois de deixar uma faixa só. Como o default é, 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

POST/api/products/{id}/prices

{
  "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 o auto_wholesale_pricing, você informa só o discount_percent de 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:

Faixamin_quantityprice (unitário)Quando vale
11R$ 50,001 a 9 unidades
210R$ 45,0010 a 49 unidades
350R$ 40,0050 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:

CampoUnidadeRegra
package_weightkg> 0
package_heightcm> 0
package_widthcm> 0
package_lengthcm> 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)

POST/api/products/{id}/prices

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_percento 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 responde 422.
  • O discount_percent vai de 0 a menos de 100.
  • 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": 20 e a API calcula o preço a partir do base. No modo manual o discount_percent é ignorado.


Listar a tabela

GET/api/products/{id}/prices

{
  "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.