Descontos e cupons

Aplicar cupom

Aplica um cupom a uma assinatura que já está ativa. Serve para desconto recorrente (percentual ou em reais por algumas cobranças) e para período grátis — por exemplo, "indicou um amigo, ganhou um mês".

POST/v1/subscriptions/:subscriptionId/coupons
Base URL Produção:https://api.validapay.com.br
Base URL Sandbox:https://sandbox.validapay.com.br

Como usar para indicação ou cortesia: crie uma vez um cupom do tipo EXTRA_PERIOD (em Cupons), por exemplo INDICACAO com 1 mês. Quando o cliente ganhar o benefício, aplique esse código na assinatura dele.

A partir de quando vale (applyTo):

  • NEXT_CYCLE (padrão): a cobrança atual não muda; o cupom vale a partir da próxima. No período grátis, a próxima cobrança é adiada.
  • CURRENT_CYCLE: vale já para a cobrança atual.
    • Desconto: a cobrança em aberto é reemitida com o valor novo.
    • Período grátis: a cobrança em aberto é reemitida com o vencimento adiado pelo período, mesmo valor.
    • Se a cobrança atual está vencida, envie um dueDate posterior a hoje: a nova cobrança sai nessa data.

Regras:

  • Uma assinatura tem um cupom por vez. Se já houver cupom em vigor, a resposta é COUPON_ALREADY_ACTIVE; aplique o próximo quando ele terminar.
  • Valem as mesmas regras do checkout: validade, limite de usos, produtos permitidos e primeiro uso.
  • No boleto, o boleto antigo não é cancelado ao reemitir, a menos que você envie cancelOpenBoleto: true.
  • No Pix Automático com instrução já enviada ao banco, só é aceito NEXT_CYCLE.

Para um abatimento pontual em uma cobrança, sem cupom, use Aplicar desconto em uma cobrança.

Envie dryRun: true para ver o efeito sem aplicar.

Authorizations

bearer

Authorization

string obrigatório

Cabeçalho de autenticação Bearer no formato Bearer {{token}} onde {{token}} é o seu token OAuth2.

Escopos requeridos

subscriptions/write

Path Parameters

subscriptionIdstringobrigatório
ID da assinatura (ex: sub_xxx) - required

Body

application/json

Content-Type:application/json
JSON
{
    "code": "INDICACAO", 
    "applyTo": "NEXT_CYCLE", 
    "dueDate": "2026-10-05", 
    "cancelOpenBoleto": false, 
    "dryRun": false 
}

Schema

codestringobrigatório
Código do cupom
applyTostringopcional
NEXT_CYCLE: a partir da próxima cobrança. CURRENT_CYCLE: já na cobrança atual (padrão NEXT_CYCLE)
Valores aceitos:NEXT_CYCLECURRENT_CYCLE
dueDatestringopcional
Vencimento da cobrança reemitida (YYYY-MM-DD). Obrigatório com CURRENT_CYCLE quando a cobrança atual está vencida
Regra:^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
cancelOpenBoletobooleanopcional
true: cancela o boleto em aberto ao reemitir. Só com CURRENT_CYCLE
dryRunbooleanopcional
true: só simula
const url = 'https://sandbox.validapay.com.br/v1/subscriptions/:subscriptionId/coupons';

const options = {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer {{token}}',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    "code": "INDICACAO", 
    "applyTo": "NEXT_CYCLE", 
    "dueDate": "2026-10-05", 
    "cancelOpenBoleto": false, 
    "dryRun": false 
})
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));

Response Examples

200cupom aplicado▾
JSON
{
    "success": true, 
    "type": "COUPON_APPLIED", 
    "subscriptionId": "sub_xxx", 

    "coupon": { 
        "code": "INDICACAO", 
        "discountType": "EXTRA_PERIOD", 
        "discountValue": 1, 
        "extraPeriodUnit": "MONTHS", 
        "maxCycles": 1 
    },
    "applyTo": "NEXT_CYCLE", 
    "firstCycleNumber": 4, 
    "action": "SHIFT_UNBILLED_CYCLES", 
    "currentDueDate": null, 
    "newDueDate": null, 
    "reissuesOpenCharge": false, 
    "redemptionId": "red_xxx", 
    "reissued": null, 
    "shiftedCycles": [ 
        {
            "cycleNumber": 4, 
            "previousChargeDate": "2026-11-10", 
            "chargeDate": "2026-12-10" 
        }
    ],
    "repricedCycles": [], 
    "restoredStatus": null 
}

Campos da resposta

successboolean
true quando o cupom foi aplicado
typestring
COUPON_APPLIED: aplicado. PREVIEW: simulação (dryRun)
Valores aceitos:COUPON_APPLIEDPREVIEW
subscriptionIdstring
ID da assinatura
couponobject
Cupom aplicado
applyTostring
A partir de qual cobrança o cupom vale
Valores aceitos:CURRENT_CYCLENEXT_CYCLE
firstCycleNumbernumber
Primeiro ciclo afetado pelo cupom
actionstring
O que foi feito. APPLIED_ON_BILLING: vale quando a cobrança for gerada. SHIFT_UNBILLED_CYCLES: próximas cobranças remarcadas. REISSUE_WITH_DISCOUNT: cobrança atual reemitida com desconto. REISSUE_WITH_NEW_DUE_DATE: cobrança atual reemitida com vencimento adiado
Valores aceitos:APPLIED_ON_BILLINGSHIFT_UNBILLED_CYCLESREISSUE_WITH_DISCOUNTREISSUE_WITH_NEW_DUE_DATE
currentDueDateobject
Vencimento da cobrança atual antes do cupom
Regra:date
newDueDateobject
Vencimento da cobrança atual depois do cupom
Regra:date
reissuesOpenChargeboolean
true quando a cobrança atual é reemitida
redemptionIdstring
ID do uso do cupom nesta assinatura
reissuedobject
Cobrança reemitida, com CURRENT_CYCLE
shiftedCyclesarray[1]
Cobranças agendadas que foram adiadas pelo período grátis
repricedCyclesarray[0]
Cobranças agendadas que tiveram o valor recalculado com o desconto
restoredStatusobject
ACTIVE quando a nova data tirou a assinatura da inadimplência
200prévia (dryRun)▾
JSON
{
    "success": true,
    "type": "PREVIEW",
    "subscriptionId": "sub_xxx",

    "coupon": { 
        "code": "INDICACAO", 
        "discountType": "EXTRA_PERIOD", 
        "discountValue": 1, 
        "extraPeriodUnit": "MONTHS", 
        "maxCycles": 1 
    },
    "applyTo": "NEXT_CYCLE", 
    "firstCycleNumber": 4, 
    "action": "SHIFT_UNBILLED_CYCLES", 
    "currentDueDate": null, 
    "newDueDate": null, 
    "reissuesOpenCharge": false 
}

Campos da resposta

successboolean
typestring
subscriptionIdstring
couponobject
Cupom aplicado
applyTostring
A partir de qual cobrança o cupom vale
Valores aceitos:CURRENT_CYCLENEXT_CYCLE
firstCycleNumbernumber
Primeiro ciclo afetado pelo cupom
actionstring
O que foi feito. APPLIED_ON_BILLING: vale quando a cobrança for gerada. SHIFT_UNBILLED_CYCLES: próximas cobranças remarcadas. REISSUE_WITH_DISCOUNT: cobrança atual reemitida com desconto. REISSUE_WITH_NEW_DUE_DATE: cobrança atual reemitida com vencimento adiado
Valores aceitos:APPLIED_ON_BILLINGSHIFT_UNBILLED_CYCLESREISSUE_WITH_DISCOUNTREISSUE_WITH_NEW_DUE_DATE
currentDueDateobject
Vencimento da cobrança atual antes do cupom
Regra:date
newDueDateobject
Vencimento da cobrança atual depois do cupom
Regra:date
reissuesOpenChargeboolean
true quando a cobrança atual é reemitida
400cupom em vigor▾
JSON
{
    "error": {
        "message": "A assinatura já tem o cupom BEMVINDO em vigor; aplique outro quando ele terminar",
        "code": "COUPON_ALREADY_ACTIVE",
        "details": null,
        "timestamp": "2026-09-24T12:00:00.000Z"
    }
}
400cobrança atual vencida▾
JSON
{
    "error": {
        "message": "A cobrança atual está vencida; informe um dueDate posterior a hoje para emitir a nova cobrança",
        "code": "DUE_DATE_REQUIRED",
        "details": null,
        "timestamp": "2026-09-24T12:00:00.000Z"
    }
}
400cupom inválido▾
JSON
{
    "error": {
        "message": "Cupom expirado",
        "code": "COUPON_EXPIRED",
        "details": null,
        "timestamp": "2026-09-24T12:00:00.000Z"
    }
}