# Aplicar cupom

**Área:** Descontos e cupons

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`

**Scopes necessários:** `subscriptions/write`

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

### Path parameters

| Campo | Obrigatório | Descrição |
|---|---|---|
| `subscriptionId` | **sim** | ID da assinatura (ex: sub_xxx) - required |

### Request body

```json
{
    "code": "INDICACAO", 
    "applyTo": "NEXT_CYCLE", 
    "dueDate": "2026-10-05", 
    "cancelOpenBoleto": false, 
    "dryRun": false 
}
```

### Campos do body

**Obrigatórios:** `code`

| Campo | Descrição |
|---|---|
| `code` | Código do cupom |

**Opcionais**

| Campo | Descrição |
|---|---|
| `applyTo` | NEXT_CYCLE: a partir da próxima cobrança. CURRENT_CYCLE: já na cobrança atual (padrão NEXT_CYCLE) (valores: NEXT_CYCLE, CURRENT_CYCLE) |
| `dueDate` | Vencimento da cobrança reemitida (YYYY-MM-DD). Obrigatório com CURRENT_CYCLE quando a cobrança atual está vencida |
| `cancelOpenBoleto` | true: cancela o boleto em aberto ao reemitir. Só com CURRENT_CYCLE |
| `dryRun` | true: só simula |

### Resposta 200: 200 cupom 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

| Campo | Descrição |
|---|---|
| `success` | true quando o cupom foi aplicado |
| `type` | COUPON_APPLIED: aplicado. PREVIEW: simulação (dryRun) (valores: COUPON_APPLIED, PREVIEW) |
| `subscriptionId` | ID da assinatura |
| `coupon` | Cupom aplicado |
| `coupon.code` | Código do cupom |
| `coupon.discountType` | PERCENTAGE: percentual. FIXED: valor em reais. EXTRA_PERIOD: período grátis (valores: PERCENTAGE, FIXED, EXTRA_PERIOD) |
| `coupon.discountValue` | Percentual, valor em reais ou quantidade de períodos grátis |
| `coupon.extraPeriodUnit` | Unidade do período grátis (valores: DAYS, MONTHS) |
| `coupon.maxCycles` | Por quantas cobranças o cupom vale. null: enquanto a assinatura durar |
| `applyTo` | A partir de qual cobrança o cupom vale (valores: CURRENT_CYCLE, NEXT_CYCLE) |
| `firstCycleNumber` | Primeiro ciclo afetado pelo cupom |
| `action` | 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: APPLIED_ON_BILLING, SHIFT_UNBILLED_CYCLES, REISSUE_WITH_DISCOUNT, REISSUE_WITH_NEW_DUE_DATE) |
| `currentDueDate` | Vencimento da cobrança atual antes do cupom (formato: date) |
| `newDueDate` | Vencimento da cobrança atual depois do cupom (formato: date) |
| `reissuesOpenCharge` | true quando a cobrança atual é reemitida |
| `redemptionId` | ID do uso do cupom nesta assinatura |
| `reissued` | Cobrança reemitida, com CURRENT_CYCLE |
| `shiftedCycles` | Cobranças agendadas que foram adiadas pelo período grátis |
| `shiftedCycles.cycleNumber` | Ciclo adiado |
| `shiftedCycles.previousChargeDate` | Data anterior (formato: date) |
| `shiftedCycles.chargeDate` | Data nova (formato: date) |
| `repricedCycles` | Cobranças agendadas que tiveram o valor recalculado com o desconto |
| `restoredStatus` | ACTIVE quando a nova data tirou a assinatura da inadimplência |

### Resposta 200: 200 pré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

| Campo | Descrição |
|---|---|
| `coupon` | Cupom aplicado |
| `coupon.code` | Código do cupom |
| `coupon.discountType` | PERCENTAGE: percentual. FIXED: valor em reais. EXTRA_PERIOD: período grátis (valores: PERCENTAGE, FIXED, EXTRA_PERIOD) |
| `coupon.discountValue` | Percentual, valor em reais ou quantidade de períodos grátis |
| `coupon.extraPeriodUnit` | Unidade do período grátis (valores: DAYS, MONTHS) |
| `coupon.maxCycles` | Por quantas cobranças o cupom vale. null: enquanto a assinatura durar |
| `applyTo` | A partir de qual cobrança o cupom vale (valores: CURRENT_CYCLE, NEXT_CYCLE) |
| `firstCycleNumber` | Primeiro ciclo afetado pelo cupom |
| `action` | 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: APPLIED_ON_BILLING, SHIFT_UNBILLED_CYCLES, REISSUE_WITH_DISCOUNT, REISSUE_WITH_NEW_DUE_DATE) |
| `currentDueDate` | Vencimento da cobrança atual antes do cupom (formato: date) |
| `newDueDate` | Vencimento da cobrança atual depois do cupom (formato: date) |
| `reissuesOpenCharge` | true quando a cobrança atual é reemitida |

### Resposta 400: 400 cupom 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"
    }
}
```


### Resposta 400: 400 cobranç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"
    }
}
```


### Resposta 400: 400 cupom inválido

```json
{
    "error": {
        "message": "Cupom expirado",
        "code": "COUPON_EXPIRED",
        "details": null,
        "timestamp": "2026-09-24T12:00:00.000Z"
    }
}
```


---

Página: https://docs.validapay.com.br/referencia/post-aplicar-cupom  
Contrato OpenAPI: https://docs.validapay.com.br/openapi.json