Skip to main content
Um desconto (discount) é a regra econômica que abate valor de uma cobrança — um percentual ou um valor fixo, com janela de validade, limite de uso e escopo de produtos. Ele habilita campanhas promocionais, cupons digitáveis no checkout e abatimentos automáticos em links de pagamento, sempre com um registro auditável de cada aplicação.
Discount ≠ Discount codeUm desconto descreve quanto abater (percentage ou fixed), por quanto tempo e onde se aplica. Um código de desconto (discount_code) é a string que o comprador digita para resgatar aquele desconto. Um desconto pode existir sem código (aplicado automaticamente via discount_id) e pode ter vários códigos apontando para ele.

Modelo conceitual

ObjetoResponsabilidadeCampos centrais
DiscountA regra: tipo, valor, duração, validade, limite e escopotype, amount_off, currency, percent_off_basis_points, duration, applies_to, max_redemptions
Discount codeA string resgatável atrelada a um descontocode, discount_id, customer, first_time_transaction, minimum_amount, expires_at, max_redemptions, max_redemptions_per_customer
RedemptionA aplicação concreta numa cobrança, com snapshot imutávelregistrada internamente
O schema público completo está em Objeto discount e Objeto discount_code. A redemption é um registro interno de auditoria — ela guarda um snapshot da regra e do código no momento da cobrança e não é um recurso editável via API.

Anatomia do desconto

CampoTipoDescrição
namestringNome do desconto. Obrigatório.
typestringpercentage ou fixed. Obrigatório.
percent_off_basis_pointsinteger | nullPercentual em basis points (1 a 10000, onde 10000 = 100%). Presente só em percentage.
amount_offinteger | nullValor fixo em centavos. Presente só em fixed.
currencystring | nullCódigo ISO de 3 letras minúsculas. Presente só em fixed.
durationstringonce, repeating ou forever. Default once.
duration_in_monthsinteger | nullNúmero de meses. Obrigatório quando duration=repeating.
applies_toobject{ "products": [...] }. Array vazio aplica a todos os produtos.
starts_atstring | nullA partir de quando passa a valer (ISO 8601).
expires_atstring | nullQuando expira (ISO 8601).
max_redemptionsinteger | nullLimite total de aplicações. null é ilimitado.
redemptions_countintegerQuantas vezes já foi aplicado.
is_activebooleanfalse tira de novos fluxos sem apagar histórico.
validbooleanResumo: true quando está ativo, dentro da janela e abaixo do limite.
metadataobjectPares chave→valor livres, controlados por você.

Tipo: percentual ou valor fixo

São mutuamente exclusivos — a forma define quais campos o objeto carrega.
TipoCampos obrigatóriosSignificado
percentagepercent_off_basis_pointsAbate uma porcentagem do subtotal. 2000 = 20%, 500 = 5%, 10000 = 100%.
fixedamount_off + currencyAbate um valor fixo em centavos. 5000 = R$ 50,00 em brl.
O abatimento de um desconto fixed nunca passa do subtotal — um amount_off de 5000 aplicado a um subtotal de 3000 abate apenas 3000, e o total não fica negativo.

Duração

A duração descreve por quanto tempo o desconto acompanha uma cobrança recorrente (assinatura). Em cobrança avulsa, só a primeira aplicação importa.
durationSignificado
onceAplica uma única vez (default).
repeatingAplica por duration_in_months meses seguidos. Exige duration_in_months > 0.
foreverAplica em todas as cobranças enquanto a assinatura existir.

Limites e validade

MecanismoOndeEfeito
Janelastarts_at / expires_at no descontoFora da janela, o desconto é recusado. starts_at deve ser anterior a expires_at.
Limite totalmax_redemptions no descontoQuando redemptions_count atinge o limite, novas aplicações são recusadas.
Escopo de produtoapplies_to.productsSó abate o subtotal das linhas dos produtos listados. Vazio = todos.
Cada cobrança (checkout, link, assinatura) recebe no máximo um desconto — a mesma cobrança não acumula dois.

Anatomia do código de desconto

O código herda a regra econômica do desconto pai (discount_id) e adiciona suas próprias condições de resgate.
CampoTipoDescrição
discount_idstringDesconto pai (disc_*). Obrigatório.
codestringA string digitável. Letras, números e hífens; normalizada para maiúsculas. Se omitida na criação, é gerada automaticamente.
customerstring | nullCliente específico que pode resgatar o código. null permite qualquer cliente.
first_time_transactionbooleanQuando true, o código só vale para clientes sem atividade de cobrança anterior.
minimum_amountinteger | nullValor mínimo da compra em centavos para o código valer.
minimum_amount_currencystring | nullMoeda do valor mínimo. Obrigatória quando minimum_amount é enviado.
expires_atstring | nullExpiração própria do código (não pode ser posterior à do desconto).
max_redemptionsinteger | nullLimite próprio do código (não pode exceder o do desconto).
max_redemptions_per_customerinteger | nullLimite de resgates por cliente para este código.
redemptions_countintegerQuantas vezes este código foi resgatado.
is_activebooleanfalse desativa o código sem mexer no desconto.
validbooleantrue quando o código e o desconto pai estão válidos.
metadataobjectPares chave→valor livres.
Um código público ativo é único por organização. Códigos restritos a clientes podem repetir a mesma string para clientes diferentes; um código público ativo bloqueia reutilizar essa string para qualquer cliente.

Criar um desconto

POST /v1/discounts cria a regra. Para um cupom digitável, crie em seguida um discount_code apontando para o disc_*.
curl https://api.chargefy.io/v1/discounts \
  -H "Authorization: Bearer {{API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Promo 20%",
    "type": "percentage",
    "percent_off_basis_points": 2000,
    "duration": "once",
    "max_redemptions": 500
  }'
O contrato completo do body, com erros e variantes, está em Criar desconto.

Criar um código de desconto

Com o desconto criado, gere a string que o comprador vai digitar. O code é opcional — quando omitido, a Chargefy gera um.
curl https://api.chargefy.io/v1/discount-codes \
  -H "Authorization: Bearer {{API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
    "discount_id": "disc_123",
    "code": "PROMO20",
    "max_redemptions": 500
  }'
O contrato completo está em Criar código de desconto.

Como o desconto é aplicado

Há dois caminhos, e eles podem coexistir no mesmo fluxo de cobrança. Ambos valem para Checkout Sessions e Links de pagamento.
1

Cupom digitável (discount_code)

O comprador digita o código no checkout. A Chargefy valida janela, limite, restrições de cliente, valor mínimo e escopo de produto e calcula o abatimento. Controle isso por allow_discount_codes no checkout/link (default true); false esconde o campo de cupom.
2

Desconto automático (discount_id)

Você atrela um discount_id direto ao checkout ou link de pagamento. O abatimento é aplicado sem o comprador digitar nada — útil para campanhas dirigidas e links promocionais.
Campo no checkout/linkTipoEfeito
allow_discount_codesbooleanHabilita o campo de cupom para o comprador. Default true.
discount_idstring | nullDesconto aplicado automaticamente, sem código digitado.
O cálculo é sobre o subtotal: amount_total = amount_subtotal − amount_discount, com amount_discount nunca maior que o subtotal. O comprador pode pré-visualizar o abatimento de um cupom antes de confirmar — a sessão expõe o desconto calculado.

Casos de uso

Um desconto percentage (ex.: 20%) com um discount_code divulgado em campanha (PROMO20). Limite o alcance com max_redemptions e a janela com starts_at/expires_at. Quem digitar o cupom no checkout recebe o abatimento.
Um desconto percentage com duration=once (só a próxima cobrança), duration=repeating + duration_in_months para abater as invoices dentro desse período, ou duration=forever para acompanhar a assinatura por toda a vida dela.
Um desconto fixed (ex.: amount_off: 5000, currency: "brl" = R50).Bompara"R 50). Bom para "R 50 OFF acima de R$ 100” combinando o código com minimum_amount: 10000 e minimum_amount_currency: "brl".
Use applies_to.products com os prod_* elegíveis. O desconto só vale quando o checkout contém pelo menos um produto da lista; caso contrário é recusado.

Atualizar

O update é merge — você envia só os campos que mudam.
Depois que um desconto tem ao menos uma aplicação (redemptions_count > 0), os campos econômicos ficam congelados: type, amount_off, currency, percent_off_basis_points, duration e duration_in_months não podem mais mudar (retorna 409). Para mudar o valor, crie um desconto novo e desative o antigo. O mesmo vale para os campos de valor de um código (code, discount_id, minimum_amount, minimum_amount_currency).
Continuam editáveis a qualquer momento: name, applies_to, starts_at, expires_at, max_redemptions (nunca abaixo de redemptions_count), is_active e metadata.

Desativar e remover

DELETE /v1/discounts/{id} e DELETE /v1/discount-codes/{id} expressam “tirar de circulação”. O efeito depende do uso:
É removido de fato. A resposta é { "id": "disc_123", "object": "discount", "deleted": true }.
Não pode sumir sem quebrar a auditoria, então é desativado (is_active = false) e a resposta é o objeto completo atualizado. Ele sai de novos fluxos, mas as aplicações passadas e seus snapshots permanecem íntegros.
Você também pode desativar diretamente com POST /v1/discounts/{id} enviando is_active: false.

Próximos passos

Objeto discount

Schema público completo e campos retornados.

Checkout Sessions

Como cupom digitável e desconto automático entram numa cobrança.

Links de pagamento

Atrelar um desconto ou habilitar cupons num link.

Assinaturas

Como duration rege o abatimento ao longo dos ciclos.

Preços

O valor que o desconto abate vem do preço.

Criar desconto (API)

Contrato do POST /v1/discounts.