Descontos e cupons
Aplicar desconto em uma cobrança
Dá um desconto de valor livre em uma cobrança específica — por exemplo, para negociar uma fatura vencida. Com cycles, o desconto vale também para as cobranças seguintes.
/v1/subscriptions/:subscriptionId/discountshttps://api.validapay.com.brhttps://sandbox.validapay.com.brQual cobrança: informe invoiceId, chargeId ou cycleNumber. Sem nenhum deles, vale para a cobrança atual.
Por quantas cobranças (cycles): conta a partir da cobrança escolhida, incluindo ela.
1(padrão): só esta cobrança.3: esta e as duas seguintes.null: todas a partir desta.
Com mais de uma cobrança, o desconto vira o desconto recorrente da assinatura. Os ciclos seguintes já criados e ainda não emitidos recebem o desconto na hora, e os próximos já nascem com ele.
O que acontece com a cobrança: se ela já foi emitida em Pix ou boleto, é reemitida com o valor novo (a menos que reissueOpenCharge seja false). O boleto antigo não é cancelado, a menos que você envie cancelOpenBoleto: true. Para remover um desconto, envie discount: null.
Regras do desconto recorrente:
- A assinatura tem um desconto recorrente por vez. Outro desconto recorrente numa cobrança coberta substitui o atual a partir dela.
discount: nullnuma cobrança coberta encerra o desconto recorrente a partir dela. As cobranças anteriores mantêm o desconto.- Desconto recorrente e cupom não valem juntos: com cupom em vigor, a resposta é
DISCOUNT_CONFLICTS_WITH_COUPON. - A troca de plano encerra o desconto recorrente: o novo plano começa sem ele.
- Vale só para a mensalidade. A fatura avulsa de um ciclo aceita apenas
cycles: 1. - No Pix Automático com autorização de valor fixo, o desconto recorrente não é aceito.
O desconto não pode zerar a cobrança. Para período grátis, use Aplicar cupom.
Envie
dryRun: truepara ver o valor novo, e os ciclos seguintes afetados, sem aplicar.
Erros:
DISCOUNT_EXCEEDS_CHARGE_AMOUNT: o desconto zeraria esta cobrança ou um dos ciclos seguintes.DISCOUNT_SCHEDULE_ACTIVE:cycles: 1numa cobrança coberta pelo desconto recorrente. Envie outro desconto recorrente para substituí-lo, oudiscount: nullpara encerrá-lo.LATER_CYCLE_ALREADY_BILLED: um ciclo seguinte dentro do período já foi emitido. Aplique o desconto recorrente a partir dele.DISCOUNT_SCHEDULE_REQUIRES_RECURRING_CHARGE: desconto recorrente em fatura avulsa do ciclo.DISCOUNT_CONFLICTS_WITH_COUPON: a assinatura tem cupom em vigor.PIX_AUTOMATICO_FIXED_AMOUNT: a autorização Pix Automático do cliente tem valor fixo.PIX_AUTOMATICO_INSTRUCTED: a instrução de débito do ciclo já foi enviada ao banco.INVOICE_NOT_PAYABLE,CYCLE_ALREADY_SETTLED: a cobrança já foi paga ou cancelada.
Authorizations
Authorization
string obrigatório
Cabeçalho de autenticação Bearer no formato Bearer {{token}} onde {{token}} é o seu token OAuth2.
Escopos requeridos
Path Parameters
subscriptionIdstringobrigatórioBody
application/json
{
"cycleNumber": 3,
"discount": {
"type": "PERCENTAGE",
"value": 10
},
"cycles": 3,
"reissueOpenCharge": true,
"cancelOpenBoleto": false,
"reason": "Negociação da fatura",
"dryRun": false
}Schema
discountobjectobrigatóriocycleNumbernumberopcionalcyclesnumberopcionalreissueOpenChargebooleanopcionalcancelOpenBoletobooleanopcionalreasonstringopcionaldryRunbooleanopcionalconst url = 'https://sandbox.validapay.com.br/v1/subscriptions/:subscriptionId/discounts';
const options = {
method: 'POST',
headers: {
'Authorization': 'Bearer {{token}}',
'Content-Type': 'application/json'
},
body: JSON.stringify({
"cycleNumber": 3,
"discount": {
"type": "PERCENTAGE",
"value": 10
},
"cycles": 3,
"reissueOpenCharge": true,
"cancelOpenBoleto": false,
"reason": "Negociação da fatura",
"dryRun": false
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));Response Examples
200▾
{
"success": true,
"type": "DISCOUNT_APPLIED",
"subscriptionId": "sub_xxx",
"target": {
"kind": "INVOICE",
"cycleNumber": 3,
"invoiceId": "inv_xxx",
"invoiceNumber": "000003",
"isPrimaryInvoice": true
},
"discount": { "type": "PERCENTAGE", "value": 10 },
"previousDiscount": null,
"grossAmount": 99.9,
"discountAmount": 9.99,
"currentAmount": 99.9,
"newAmount": 89.91,
"reissue": {
"willReissue": true,
"skipReason": null,
"paymentType": "BOLETO",
"subscriptionPaymentType": "BOLETO",
"openChargeId": "cha_xxx"
},
"discountSchedule": {
"current": null,
"coversTarget": false,
"next": {
"type": "PERCENTAGE",
"value": 10,
"startCycleNumber": 3,
"cycles": 3,
"lastCycleNumber": 5,
"endedAt": null
},
"laterCycles": [
{ "cycleNumber": 4, "amount": 89.91 }
]
},
"warnings": [],
"reissued": { "chargeId": "cha_yyy", "paymentType": "BOLETO", "dueDate": "2026-10-10", "amount": 89.91 }
}Campos da resposta
successbooleantypestringDISCOUNT_APPLIEDDISCOUNT_REMOVEDNO_CHANGEPREVIEWsubscriptionIdstringtargetobjectdiscountobjectpreviousDiscountobjectgrossAmountnumberdiscountAmountnumbercurrentAmountnumbernewAmountnumberreissueobjectdiscountScheduleobjectwarningsarray[0]reissuedobject400desconto zera a cobrança▾
{
"error": {
"message": "O desconto não pode zerar a cobrança, hoje em 99.90",
"code": "DISCOUNT_EXCEEDS_CHARGE_AMOUNT",
"details": null,
"timestamp": "2026-09-24T12:00:00.000Z"
}
}400cobrança coberta por desconto recorrente▾
{
"error": {
"message": "Esta cobrança faz parte de um desconto recorrente; encerre-o ou aplique outro desconto recorrente para substituí-lo",
"code": "DISCOUNT_SCHEDULE_ACTIVE",
"details": null,
"timestamp": "2026-11-04T12:00:00.000Z"
}
}