Skip to main content
Um preço (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

ObjetoResponsabilidadeCampos centrais
ProductO que você vende (catálogo)name, description, image_url, default_price
PriceTermos da cobrança vinculados ao produtounit_amount, currency, type, recurring, tax_behavior, is_active
O schema público completo está em Objeto price.

Anatomia do preço

CampoTipoDescrição
idstringID do preço (price_*).
objectstringSempre "price".
productstringProduto dono do preço. No create, você informa esse vínculo como product_id.
namestring | nullRótulo interno opcional (Mensal, Anual Early Bird).
typestringone_time (compra única) ou recurring (assinatura). Default one_time.
currencystringCódigo ISO 4217 em minúsculas (brl).
unit_amountintegerValor unitário em centavos, inteiro ≥ 0.
recurringobject | nullCadência recorrente (interval, interval_count, trial_period_days, usage_type). null em one_time.
tax_behaviorstringunspecified, inclusive ou exclusive. Default unspecified.
is_activebooleanfalse tira o preço de novas vendas sem apagar histórico.
livemodebooleantrue em produção; false em ambiente de teste.
metadataobjectPares chave→valor livres, controlados por você. {} quando vazio.
created_atstringISO 8601.
updated_atstring | nullISO 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 campo recurring fica null e não pode ser enviado. unit_amount pode ser 0 (oferta gratuita).
{
  "currency": "brl",
  "recurring": null,
  "type": "one_time",
  "unit_amount": 4990
}

Recurring — assinatura

Cobrança que renova na cadência definida por recurring.interval × recurring.interval_count. unit_amount é inteiro ≥ 0; envie 0 para uma assinatura gratuita naquela cadência.
{
  "currency": "brl",
  "recurring": {
    "interval": "month",
    "interval_count": 1
  },
  "type": "recurring",
  "unit_amount": 9990
}
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ênciaintervalinterval_count
Diáriaday1
Semanalweek1
Quinzenalweek2
Mensalmonth1
Bimestralmonth2
Trimestralmonth3
Semestralmonth6
Anualyear1
Bienalyear2
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, via product_id.
1

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.
2

POST /v1/prices

Envie product_id, currency, unit_amount e o type. Para recurring, inclua recurring.interval. Use set_as_default: true para apontar o default_price do produto para este preço logo após a criação.
curl -X POST "https://api.chargefy.io/v1/prices" \
  -H "Authorization: Bearer {{API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "currency": "brl",
    "name": "Avulso",
    "product_id": "prod_123",
    "type": "one_time",
    "unit_amount": 4990
  }'
A criação retorna 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:
QuandoComo
Na criação do produtodefault_price_index aponta o índice em prices[] (default 0) quando prices[] tem itens.
Ao adicionar um preço novoPOST /v1/prices com set_as_default: true.
A qualquer momentoPOST /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 name interno como Mensal, Anual Early Bird ou Equipe 10+
Para listar os preços de um produto: 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

Um price é sempre unitário. A multiplicação acontece no checkout, pela quantidade:
Total da linha = price.unit_amount × quantidade
Se você vende por assento, licença ou unidade, o caminho é esse: preço unitário no catálogo + quantidade no checkout. Não crie um preço por faixa de quantidade.

Comportamento tributário

tax_behavior declara como o imposto se relaciona com unit_amount:
tax_behaviorSignificado
unspecifiedSem comportamento fiscal declarado (default).
inclusiveO imposto já está embutido em unit_amount.
exclusiveO 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, via POST /v1/prices/{id}. Apenas estes são editáveis:
CampoObservação
nameRótulo interno. Envie null para limpar.
is_activefalse arquiva; true reativa. Boolean obrigatório.
tax_behaviorunspecified, inclusive ou exclusive.
metadataSubstitui o objeto inteiro quando enviado.
Tentar atualizar currency, unit_amount, type, recurring ou product_id retorna 400 — esses campos são imutáveis. Enviar active também é rejeitado: o campo público é is_active.
A resposta direta não carrega diff; quem precisa do diff lê o webhook 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:
1

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.
2

Desative o antigo

POST /v1/prices/{id_antigo} com is_active: false (ou DELETE /v1/prices/{id_antigo}). Vendas e assinaturas existentes seguem no preço antigo; novos fluxos passam a usar o novo.

Arquivar e remover

DELETE /v1/prices/{id} expressa “tirar de uso”. O efeito depende do histórico:
É removido de fato. A resposta é { "id": "price_123", "object": "price", "deleted": true }.
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.
Você também pode arquivar diretamente com 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.
Arquivar (is_active: false) não cancela assinaturas nem vendas que já usam o preço — só impede que ele entre em novos fluxos de compra.

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.