price) descreve quanto e como você cobra: o valor unitário, a moeda, se é compra única ou recorrente e o comportamento tributário. Ele sempre pertence a um produto — o produto diz o que você vende, o preço diz os termos da cobrança. Essa separação deixa o mesmo produto ter várias formas de cobrança sem duplicar a oferta.
Preços são imutáveis nos campos de valor.
currency, unit_amount, type, recurring e o produto vinculado não se editam depois que o preço existe — eles precisam ser auditáveis. Para mudar valor, cadência ou trial padrão, você cria um preço novo e desativa o antigo. Só name, is_active, tax_behavior e metadata são editáveis.Modelo conceitual
| Objeto | Responsabilidade | Campos centrais |
|---|---|---|
| Product | O que você vende (catálogo) | name, description, image_url, default_price |
| Price | Termos da cobrança vinculados ao produto | unit_amount, currency, type, recurring, tax_behavior, is_active |
Anatomia do preço
| Campo | Tipo | Descrição |
|---|---|---|
id | string | ID do preço (price_*). |
object | string | Sempre "price". |
product | string | Produto dono do preço. No create, você informa esse vínculo como product_id. |
name | string | null | Rótulo interno opcional (Mensal, Anual Early Bird). |
type | string | one_time (compra única) ou recurring (assinatura). Default one_time. |
currency | string | Código ISO 4217 em minúsculas (brl). |
unit_amount | integer | Valor unitário em centavos, inteiro ≥ 0. |
recurring | object | null | Cadência recorrente (interval, interval_count, trial_period_days, usage_type). null em one_time. |
tax_behavior | string | unspecified, inclusive ou exclusive. Default unspecified. |
is_active | boolean | false tira o preço de novas vendas sem apagar histórico. |
livemode | boolean | true em produção; false em ambiente de teste. |
metadata | object | Pares chave→valor livres, controlados por você. {} quando vazio. |
created_at | string | ISO 8601. |
updated_at | string | null | ISO 8601 ou null. |
Tipos de preço
Um preço éone_time ou recurring. O tipo define se o objeto carrega recurring.
One-time — compra única
Cobrança avulsa, sem renovação. O camporecurring fica null e não pode ser enviado. unit_amount pode ser 0 (oferta gratuita).
Recurring — assinatura
Cobrança que renova na cadência definida porrecurring.interval ×
recurring.interval_count. unit_amount é inteiro ≥ 0; envie 0 para uma
assinatura gratuita naquela cadência.
Preço recorrente gratuito continua sendo
type: "recurring" e precisa de
recurring.interval. Assinaturas compostas só por preços zero geram invoices
pagas, sem tentativa de cobrança.Cadências suportadas
recurring.interval combinado com recurring.interval_count cobre praticamente qualquer ritmo de cobrança:
| Cadência | interval | interval_count |
|---|---|---|
| Diária | day | 1 |
| Semanal | week | 1 |
| Quinzenal | week | 2 |
| Mensal | month | 1 |
| Bimestral | month | 2 |
| Trimestral | month | 3 |
| Semestral | month | 6 |
| Anual | year | 1 |
| Bienal | year | 2 |
interval_count é inteiro ≥ 1 (default 1); enviar valor não-inteiro ou menor que 1 retorna 400.
Criar um preço
Um preço sempre nasce atrelado a um produto existente, viaproduct_id.
Crie ou tenha um produto
O preço precisa de um
product_id válido daquela organização. Crie o
produto antes em Produtos, com ou sem preço inicial.200 OK com o objeto price completo e dispara o webhook price.created. Contrato completo em Criar preço.
Preço padrão do produto
product.default_price é o preço que os fluxos usam quando partem do produto. Há três formas de defini-lo:
| Quando | Como |
|---|---|
| Na criação do produto | default_price_index aponta o índice em prices[] (default 0) quando prices[] tem itens. |
| Ao adicionar um preço novo | POST /v1/prices com set_as_default: true. |
| A qualquer momento | POST /v1/products/{id} com default_price_id apontando um preço daquele produto. A resposta pública vem como default_price. |
Múltiplos preços no mesmo produto
O padrão recomendado para variações de cobrança é um produto com vários preços, em vez de produtos duplicados. Casos comuns:- mensal + anual no mesmo plano
- compra única + versão recorrente do mesmo item
- preço padrão + preço promocional desativado depois
- preços com
nameinterno comoMensal,Anual Early BirdouEquipe 10+
GET /v1/prices?product_id=prod_123. Por padrão a lista traz só is_active=true; envie is_active=false para ver os arquivados ou is_active=all para ambos.
Quantidade
Umprice é sempre unitário. A multiplicação acontece no checkout, pela quantidade:
Comportamento tributário
tax_behavior declara como o imposto se relaciona com unit_amount:
tax_behavior | Significado |
|---|---|
unspecified | Sem comportamento fiscal declarado (default). |
inclusive | O imposto já está embutido em unit_amount. |
exclusive | O imposto é somado por cima de unit_amount. |
Hoje
tax_behavior é declarativo: faz parte do contrato público do preço, mas não altera sozinho o valor final cobrado. Ele é editável a qualquer momento via POST /v1/prices/{id}.Atualizar um preço
O update é merge: você envia só os campos que mudam, viaPOST /v1/prices/{id}. Apenas estes são editáveis:
| Campo | Observação |
|---|---|
name | Rótulo interno. Envie null para limpar. |
is_active | false arquiva; true reativa. Boolean obrigatório. |
tax_behavior | unspecified, inclusive ou exclusive. |
metadata | Substitui o objeto inteiro quando enviado. |
price.updated, que traz o objeto completo em data.object e os campos alterados em data.previous_attributes. Contrato completo em Atualizar preço.
Trocar o valor de um preço
Como os campos de valor são imutáveis, “mudar o preço” é sempre criar um novo e desativar o antigo:Crie o preço novo
POST /v1/prices com o mesmo product_id e o valor/cadência atualizados. Use set_as_default: true se ele deve virar o padrão do produto.Arquivar e remover
DELETE /v1/prices/{id} expressa “tirar de uso”. O efeito depende do histórico:
Preço nunca usado
Preço nunca usado
É removido de fato. A resposta é
{ "id": "price_123", "object": "price", "deleted": true }.Preço já referenciado por checkout, venda ou assinatura
Preço já referenciado por checkout, venda ou assinatura
Não pode sumir sem quebrar histórico, então é desativado (
is_active = false) e a resposta é o objeto price completo atualizado. Ele sai de novas vendas, mas pagamentos e assinaturas em curso permanecem íntegros.POST /v1/prices/{id} enviando is_active: false, sem tentar a remoção. Para reativar um preço arquivado: POST /v1/prices/{id} com is_active: true.
Próximos passos
Objeto price
Schema público completo e campos retornados.
Produtos
O catálogo que dá origem aos preços.
Criar preço (API)
Contrato do
POST /v1/prices.Checkout Sessions
Como o preço vira uma cobrança.

