Plano e itens

Trocar plano ou quantidade

Troca o plano de um item (inclusive por um plano de outro produto) ou muda a quantidade.

PUT/v1/subscriptions/:subscriptionId/items/:itemId
Base URL Produção:https://api.validapay.com.br
Base URL Sandbox:https://sandbox.validapay.com.br

O que acontece com a cobrança:

  • Plano mais caro: cobra agora a diferença proporcional aos dias que faltam (pró-rata). O plano novo vale quando essa cobrança é paga.
  • Plano mais barato: nada é cobrado agora; o valor novo vale a partir da próxima cobrança. Os dias restantes podem virar crédito nas próximas cobranças.
  • Outra periodicidade (ex.: anual para mensal): nada é cobrado agora; o que já foi pago vira dias do plano novo e a próxima cobrança é remarcada.

Quer saber o valor antes? Use Calcular pró-rata ou crédito. Ela faz exatamente o mesmo cálculo desta rota, sem alterar nada.

O formato antigo (PATCH /v1/subscriptions/{id} com old e new) continua aceito, mas está descontinuado.

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
itemIdstringobrigatório
ID do item da assinatura, em items[].itemId de Ver uma assinatura (ex: item_xxx) - required

Body

application/json

Content-Type:application/json
JSON
{
    "priceId": "price_yyy", 
    "quantity": 2, 

    "prorata": { 
        "enabled": true, 
        "mergeWithNextCycle": false, 
        "dueDate": "2026-09-27" 
    },
    "boletoInstructions": { 
        "fine": 2.0, 
        "interest": 1.0 
    },
    "expirationAfterDueDate": 30, 
    "dryRun": false 

}

Schema

priceIdstringopcional
Plano novo. Informe priceId, quantity ou os dois
quantitynumberopcional
Quantidade nova
prorataobjectopcional
Como cobrar a diferença dos dias restantes
boletoInstructionsobjectopcional
Multa, juros e desconto do boleto da pró-rata
expirationAfterDueDatenumberopcional
Dias depois do vencimento em que o boleto ou Pix ainda pode ser pago (0 a 60)
Regra:0 a 60
dryRunbooleanopcional
true: só simula e não altera nada
const url = 'https://sandbox.validapay.com.br/v1/subscriptions/:subscriptionId/items/:itemId';

const options = {
  method: 'PUT',
  headers: {
    'Authorization': 'Bearer {{token}}',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    "priceId": "price_yyy", 
    "quantity": 2, 

    "prorata": { 
        "enabled": true, 
        "mergeWithNextCycle": false, 
        "dueDate": "2026-09-27" 
    },
    "boletoInstructions": { 
        "fine": 2.0, 
        "interest": 1.0 
    },
    "expirationAfterDueDate": 30, 
    "dryRun": false 

})
};

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

Response Examples

200plano trocado▾
JSON
{
    "success": true, 
    "intent": "REPLACE", 
    "mode": "PRORATA_NOW", 
    "settlement": "AWAITING_PAYMENT", 
    "item": { 
        "itemId": "item_yyy", 
        "priceId": "price_yyy", 
        "quantity": 1, 
        "amount": 149.9, 
        "status": "PENDING_UPGRADE" 
    },
    "replacedItemId": "item_xxx", 
    "adjustmentItemId": null, 
    "amounts": { 
        "delta": 50.0, 
        "prorata": 25.0, 
        "recurringTotal": 149.9, 
        "chargeTotal": 25.0 
    },
    "prorataPeriod": { 
        "startDate": "2026-09-24", 
        "endDate": "2026-10-09", 
        "days": 15, 
        "factor": 0.5, 
        "prorataAmount": 25.0 
    },
    "effectiveAt": "2026-10-10T00:00:00.000Z", 
    "invoiceId": "inv_yyy", 
    "charge": { 
        "chargeId": "cha_yyy", 
        "status": "AWAITING_PAYMENT", 
        "paymentType": "PIX", 
        "dueDate": "2026-09-27" 
    },
    "payment": { 
        "method": "PIX", 
        "pix": { 
            "emv": "00020126...", 
            "qrCode": "data:image/png;base64,iVBOR...", 
            "transactionId": "tx_xxx" 
        },
        "boleto": null, 
        "dueDate": "2026-09-27" 
    },
    "type": "DEFERRED_UPGRADE", 
    "chargeId": "cha_yyy", 
    "prorataAmount": 25.0, 
    "newAmount": 149.9, 
    "recurringTotal": 149.9, 
    "amount": 25.0, 
    "paymentMethod": "PIX", 
    "pix": { "emv": "00020126...", "qrCode": "data:image/png;base64,iVBOR...", "transactionId": "tx_xxx" }, 
    "dueDate": "2026-09-27" 
}

Campos da resposta

successboolean
true quando a alteração foi registrada
intentstring
ADD: item adicionado. REPLACE: item trocado
Valores aceitos:ADDREPLACE
modestring
Como a diferença de valor foi tratada
Valores aceitos:PRORATA_NOWNO_PRORATAPRORATA_NEXT_CYCLESCHEDULED_DOWNGRADERECURRENCE_CHANGEPENDING_REWRITE
settlementstring
Situação da cobrança da diferença. PAID: paga no cartão. AWAITING_PAYMENT: Pix ou boleto emitido. NEXT_CYCLE_ENGINE: entra na próxima cobrança. CREDITED: virou crédito. RESCHEDULED: próxima cobrança remarcada. NONE: nada a cobrar
Valores aceitos:PAIDAWAITING_PAYMENTNONENEXT_CYCLE_ENGINEMERGED_INTO_OPEN_CHARGEMERGED_INTO_CHECKOUTCREDITEDRESCHEDULED
itemobject
Item criado ou alterado, no mesmo formato de items[] em Ver uma assinatura
replacedItemIdstring
Item substituído. Só na troca
adjustmentItemIdobject
Ajuste de pró-rata lançado na próxima cobrança
amountsobject
Valores da alteração, em reais
prorataPeriodobject
Dias considerados na pró-rata
effectiveAtstring
Quando o valor novo passa a valer nas cobranças
invoiceIdstring
Fatura da cobrança da diferença
chargeobject
Cobrança da diferença
paymentobject
Como pagar a cobrança da diferença
typestring
Resultado no formato antigo. Use mode e settlement
chargeIdstring
Use charge.chargeId
prorataAmountnumber
Use amounts.prorata
newAmountnumber
Valor novo do item. Use item.amount
recurringTotalnumber
Use amounts.recurringTotal
amountnumber
Use amounts.chargeTotal
paymentMethodstring
Use payment.method
Valores aceitos:pixcreditcardboletopix_automatico
pixobject
Use payment.pix
dueDatestring
Use charge.dueDate
Regra:^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
400pagamento recusado▾
JSON
{
    "error": {
        "message": "Cartão recusado por saldo insuficiente",
        "code": "PAYMENT_DECLINED",
        "details": { "declinedCode": "insufficient_funds" },
        "timestamp": "2026-09-24T12:00:00.000Z"
    }
}
404▾
JSON
{
    "error": {
        "message": "Item não encontrado",
        "code": "ITEM_NOT_FOUND",
        "details": null,
        "timestamp": "2026-09-24T12:00:00.000Z"
    }
}