# Trocar cartão ou método de pagamento

**Área:** Pagamento

Troca o cartão ou a forma de pagamento da assinatura. Também é o caminho para **regularizar uma assinatura com cobrança vencida** usando um cartão novo.

`PUT /v1/subscriptions/:subscriptionId/payment-method`

**Base URL Produção:** `https://api.validapay.com.br`  
**Base URL Sandbox:** `https://sandbox.validapay.com.br`

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

**Trocar o cartão com a assinatura em dia:** envie `paymentMethod: "creditcard"` e o `cardToken` do cartão novo. As próximas cobranças usam o cartão novo; nada é cobrado agora.

**Assinatura com cobrança vencida (`PAST_DUE` ou `DEFAULT`):**
- **Com `cardToken`:** cobra na hora **todas as faturas vencidas**, uma por vez, da mais antiga para a mais nova, e passa a usar o cartão novo. Se uma recusa, as seguintes não são tentadas e a resposta traz o link da fatura que ficou em aberto. A assinatura volta a `ACTIVE` quando não sobra nenhuma fatura vencida.
- **Sem `cardToken`:** devolve o link da fatura (`checkoutUrl`) para o cliente informar o cartão e pagar sozinho.

**Dados do cartão:** nunca envie o número do cartão para esta rota.
1. Tokenize o cartão com o SDK de tokenização (veja **SDKs › Tokenização**). O `cardToken` vale por 5 minutos.
2. Envie o `deviceId` gerado pelo SDK (fingerprint do dispositivo); ele é usado na análise antifraude.
3. Se a conta exige 3DS, autentique com o SDK de 3DS e envie `authentication.authenticationId`.

**Pix, boleto e Pix Automático:** envie `paymentMethod` com `applyTo`. Com `NEXT_CYCLE` a troca vale a partir da próxima cobrança; com `CURRENT_CYCLE` a cobrança em aberto é reemitida na forma nova. O boleto antigo não é cancelado, a menos que você envie `cancelOpenBoleto: true`. No Pix Automático a resposta traz o link para o cliente autorizar o débito no banco.

> Envie `dryRun: true` com o `cardToken` para ver quais faturas serão cobradas e o total, sem cobrar.

### Path parameters

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

### Request body

```json
{
    "paymentMethod": "creditcard", 
    "cardToken": "ctk_xxx", 
    "deviceId": "dfp_xxx", 
    "authentication": { 
        "authenticationId": "auth_xxx" 
    },
    "applyTo": "CURRENT_CYCLE", 
    "dueDate": "2026-09-30", 
    "cancelOpenBoleto": false, 
    "dryRun": false 
}
```

### Campos do body

**Obrigatórios:** `paymentMethod`, `authentication.authenticationId`

| Campo | Descrição |
|---|---|
| `paymentMethod` | Nova forma de pagamento (valores: creditcard, pix, boleto, pix_automatico) |
| `authentication.authenticationId` | ID devolvido pelo SDK de 3DS |

**Opcionais**

| Campo | Descrição |
|---|---|
| `cardToken` | Token do cartão gerado pelo SDK (vale 5 minutos). Obrigatório para trocar o cartão ou cobrar faturas vencidas |
| `deviceId` | Fingerprint do dispositivo gerado pelo SDK. Envie sempre junto com o cardToken |
| `authentication` | Resultado da autenticação 3DS. Obrigatório quando a conta exige 3DS |
| `applyTo` | CURRENT_CYCLE: vale para a cobrança atual. NEXT_CYCLE: vale a partir da próxima. Padrão: CURRENT_CYCLE com cobrança vencida, NEXT_CYCLE nos demais casos (valores: CURRENT_CYCLE, NEXT_CYCLE) |
| `dueDate` | Vencimento da cobrança reemitida em Pix ou boleto (YYYY-MM-DD). Só com CURRENT_CYCLE |
| `cancelOpenBoleto` | true: cancela o boleto em aberto ao reemitir. Só com CURRENT_CYCLE (padrão false) |
| `dryRun` | true: mostra as faturas que seriam cobradas no cartão, sem cobrar |

### Resposta 200: 200 faturas vencidas cobradas no cartão

```json
{
    "success": true, 
    "type": "CARD_CHARGED", 
    "subscriptionId": "sub_xxx", 
    "paymentType": "CREDIT_CARD", 
    "paymentMethodId": "pm_xxx", 
    "appliedTo": "CURRENT_CYCLE", 
    "totalCharged": 220.0, 
    "cycles": [ 
        {

            "cycleNumber": 2, 
            "invoiceId": "inv_2", 
            "amount": 100.0, 
            "dueDate": "2026-08-10", 
            "status": "PAID", 
            "chargeId": "cha_xxx" 
        },
        { "cycleNumber": 3, "invoiceId": "inv_3", "amount": 120.0, "dueDate": "2026-09-10", "status": "PAID", "chargeId": "cha_yyy" }
    ]
}
```

#### Campos da resposta

| Campo | Descrição |
|---|---|
| `success` | true quando ao menos uma fatura foi paga |
| `type` | CARD_CHARGED: todas as faturas vencidas foram pagas. PARTIALLY_CHARGED: parte foi paga (valores: CARD_CHARGED, PARTIALLY_CHARGED) |
| `subscriptionId` | ID da assinatura |
| `paymentType` | Nova forma de pagamento |
| `paymentMethodId` | Cartão que passa a ser usado nas cobranças |
| `appliedTo` | A troca valeu para a cobrança atual |
| `totalCharged` | Total cobrado agora, em reais |
| `cycles` | Resultado de cada fatura vencida, da mais antiga para a mais nova |
| `cycleNumber` | Ciclo cobrado |
| `invoiceId` | Fatura do ciclo |
| `amount` | Valor da fatura, em reais |
| `dueDate` | Vencimento original do ciclo (formato: date) |
| `status` | PAID: paga. DECLINED: recusada. NOT_ATTEMPTED: não tentada porque uma anterior foi recusada (valores: PAID, DECLINED, NOT_ATTEMPTED) |
| `chargeId` | Cobrança feita no cartão |

### Resposta 200: 200 cobrança parcial

```json
{
    "success": true,
    "type": "PARTIALLY_CHARGED",
    "subscriptionId": "sub_xxx",
    "paymentType": "CREDIT_CARD",
    "paymentMethodId": "pm_xxx",
    "appliedTo": "CURRENT_CYCLE",
    "totalCharged": 100.0,
    "cycles": [
        { "cycleNumber": 2, "invoiceId": "inv_2", "amount": 100.0, "dueDate": "2026-08-10", "status": "PAID", "chargeId": "cha_xxx" },
        {
            "cycleNumber": 3,
            "invoiceId": "inv_3",
            "amount": 120.0,
            "dueDate": "2026-09-10",
            "status": "DECLINED",
            "chargeId": "cha_yyy",
            "declineCode": "insufficient_funds", 
            "declineReason": "Cartão recusado por saldo insuficiente" 
        }
    ],
    "checkoutUrl": "https://app.validapay.com.br/fatura/inv_3" 
}
```

#### Campos da resposta

| Campo | Descrição |
|---|---|
| `cycles.declineCode` | Código da recusa devolvido pela operadora |
| `cycles.declineReason` | Motivo da recusa, em texto |
| `checkoutUrl` | Link da primeira fatura que ficou em aberto, para o cliente pagar |

### Resposta 200: 200 prévia (dryRun)

```json
{
    "success": true,
    "type": "PREVIEW", 
    "subscriptionId": "sub_xxx",
    "paymentType": "CREDIT_CARD",
    "total": 220.0, 
    "cycles": [ 
        {

            "cycleNumber": 2, 
            "invoiceId": "inv_2", 
            "amount": 100.0, 
            "dueDate": "2026-08-10" 
        },
        { "cycleNumber": 3, "invoiceId": "inv_3", "amount": 120.0, "dueDate": "2026-09-10" }
    ]
}
```

#### Campos da resposta

| Campo | Descrição |
|---|---|
| `type` | Simulação; nada foi cobrado |
| `total` | Total que será cobrado, em reais |
| `cycles` | Faturas que serão cobradas, na ordem da cobrança |
| `cycleNumber` | Ciclo cobrado |
| `invoiceId` | Fatura do ciclo |
| `amount` | Valor da fatura, em reais |
| `dueDate` | Vencimento original do ciclo (formato: date) |

### Resposta 200: 200 link para o cliente informar o cartão

```json
{
    "success": true,
    "type": "CARD_COLLECTION_REQUIRED", 
    "subscriptionId": "sub_xxx",
    "paymentType": "BOLETO", 
    "appliedTo": "CURRENT_CYCLE",
    "invoiceId": "inv_3", 
    "checkoutUrl": "https://app.validapay.com.br/fatura/inv_3", 
    "message": "Envie o link ao cliente para que ele informe os dados do cartão"
}
```

#### Campos da resposta

| Campo | Descrição |
|---|---|
| `type` | O cliente precisa informar o cartão na fatura |
| `paymentType` | Forma de pagamento atual; muda quando o cliente pagar com o cartão |
| `invoiceId` | Fatura que o cliente vai pagar |
| `checkoutUrl` | Link para enviar ao cliente |

### Resposta 200: 200 forma de pagamento trocada

```json
{
    "success": true,
    "type": "PAYMENT_METHOD_CHANGED", 
    "subscriptionId": "sub_xxx",
    "paymentType": "PIX", 
    "paymentMethodId": null, 
    "appliedTo": "NEXT_CYCLE", 
    "reason": "SCOPED_TO_NEXT_CYCLE", 
    "reissued": null, 
    "updatedCycles": [3] 
}
```

#### Campos da resposta

| Campo | Descrição |
|---|---|
| `type` | PAYMENT_METHOD_CHANGED: trocada. NO_CHANGE: a forma pedida já era a atual (valores: PAYMENT_METHOD_CHANGED, NO_CHANGE) |
| `paymentType` | Nova forma de pagamento (valores: CREDIT_CARD, PIX, BOLETO, PIX_AUTOMATICO) |
| `paymentMethodId` | Cartão usado, quando a forma é cartão |
| `appliedTo` | A partir de quando a troca vale (valores: NEXT_CYCLE, CURRENT_CYCLE) |
| `reason` | Por que a cobrança em aberto não foi reemitida (valores: NO_OPEN_CHARGE, SAME_PAYMENT_METHOD, SCOPED_TO_NEXT_CYCLE) |
| `reissued` | Cobrança reemitida na forma nova, quando applyTo é CURRENT_CYCLE |
| `updatedCycles` | Ciclos já agendados que passaram para a forma nova |

### Resposta 400: 400 cartão recusado

```json
{
    "error": {
        "message": "Cartão recusado por saldo insuficiente",
        "code": "PAYMENT_DECLINED",
        "details": { "cycles": [ { "cycleNumber": 2, "invoiceId": "inv_2", "amount": 100.0, "dueDate": "2026-08-10", "status": "DECLINED", "chargeId": "cha_xxx", "declineCode": "insufficient_funds", "declineReason": "Cartão recusado por saldo insuficiente" }, { "cycleNumber": 3, "invoiceId": "inv_3", "amount": 120.0, "dueDate": "2026-09-10", "status": "NOT_ATTEMPTED" } ] },
        "timestamp": "2026-09-24T12:00:00.000Z"
    }
}
```


---

Página: https://docs.validapay.com.br/referencia/put-trocar-cartao-ou-metodo-de-pagamento  
Contrato OpenAPI: https://docs.validapay.com.br/openapi.json