Plano e itens

Calcular pró-rata ou crédito

Simula uma troca de plano ou de quantidade sem alterar nada. Mostra quanto será cobrado agora, quanto vira crédito e qual será a próxima cobrança. Use antes de Trocar plano ou quantidade: o cálculo é exatamente o mesmo que a troca vai executar.

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

Os três resultados possíveis (type):

  • CHARGE_NOW — plano mais caro na mesma periodicidade. O cliente recebe uma cobrança agora com a diferença proporcional aos dias que faltam (pró-rata).
  • NEXT_CHARGE — plano mais barato sem crédito, ou troca que só vale na próxima cobrança. Nada é cobrado agora; a próxima cobrança já vem no valor novo.
  • CREDIT — troca de periodicidade (ex.: anual para mensal) ou plano mais barato com crédito. O que já foi pago vira crédito que abate as próximas cobranças.

Como o crédito funciona na troca de periodicidade: o valor já pago e não usado vira dias do plano novo. A próxima cobrança vai para o dia seguinte ao último dia coberto. A sobra, menor que o valor de um dia do plano novo, é descontada dessa próxima cobrança.

Exemplo: faltam 72 dias de um plano anual de R$ 1.080 (R$ 216 de crédito). Na troca para um mensal de R$ 100 (R$ 3,33 por dia), o crédito cobre 64 dias; a próxima cobrança fica para depois desses 64 dias e sai por R$ 97,33 (R$ 100 − R$ 2,67 de sobra).

Quando a troca de periodicidade é recusada:

  • RECURRENCE_CHANGE_REQUIRES_PAID_CYCLE: o ciclo atual ainda não foi pago; o crédito sai dele.
  • NEXT_CYCLE_ALREADY_BILLED: a próxima cobrança já foi emitida; troque depois que ela for paga.
  • RECURRENCE_CHANGE_WITH_ADDONS: o plano precisa ser o único item recorrente da assinatura.
  • RECURRENCE_CHANGE_REQUIRES_NEW_ADHESION: no Pix Automático, troque antes a forma de pagamento.

O formato antigo (old e new no corpo) continua aceito, mas está descontinuado e não considera troca de periodicidade, cupom nem desconto.

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
{
    "itemId": "item_xxx", 
    "priceId": "price_yyy", 
    "quantity": 1 
}

Schema

itemIdstringobrigatório
Item que será trocado, em items[].itemId de Ver uma assinatura
priceIdstringopcional
Plano novo. Informe priceId, quantity ou os dois
quantitynumberopcional
Quantidade nova. Sem ela, mantém a atual
const url = 'https://sandbox.validapay.com.br/v1/subscriptions/:subscriptionId/prorata';

const options = {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer {{token}}',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    "itemId": "item_xxx", 
    "priceId": "price_yyy", 
    "quantity": 1 
})
};

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

Response Examples

200plano mais caro▾
JSON
{
    "subscriptionId": "sub_xxx", 
    "itemId": "item_xxx", 
    "type": "CHARGE_NOW", 
    "current": { 
        "priceId": "price_xxx", 
        "amount": 99.9, 
        "recurrence": "MONTHLY", 
        "recurrenceInterval": 1 
    },
    "new": { 
        "priceId": "price_yyy", 
        "amount": 149.9, 
        "recurrence": "MONTHLY", 
        "recurrenceInterval": 1 
    },
    "charge": { 
        "amount": 25.0, 
        "prorataAmount": 25.0, 
        "paymentType": "CREDIT_CARD", 
        "dueDate": null, 
        "period": { 
            "startDate": "2026-09-24", 
            "endDate": "2026-10-09", 
            "days": 15 
        }
    },
    "credit": null, 
    "nextCharge": { 
        "date": "2026-10-10", 
        "amount": 149.9 
    },
    "warnings": [] 
}

Campos da resposta

subscriptionIdstring
ID da assinatura
itemIdstring
Item que seria trocado
typestring
Resultado da troca. CHARGE_NOW: cobra a diferença agora. NEXT_CHARGE: nada é cobrado agora, o valor novo vale a partir da próxima cobrança. CREDIT: o que já foi pago vira crédito
Valores aceitos:CHARGE_NOWNEXT_CHARGECREDIT
currentobject
Plano atual
newobject
Plano depois da troca
chargeobject
Cobrança gerada ao confirmar a troca. Só vem em CHARGE_NOW
creditobject
Crédito gerado pela troca. Só vem em CREDIT
nextChargeobject
Próxima cobrança recorrente depois da troca
warningsarray[0]
Avisos sobre efeitos da troca, como cupom que será encerrado
200troca de periodicidade▾
JSON
{
    "subscriptionId": "sub_xxx",
    "itemId": "item_xxx",
    "type": "CREDIT",
    "current": { "priceId": "price_anual", "amount": 1080.0, "recurrence": "YEARLY", "recurrenceInterval": 1 },
    "new": { "priceId": "price_mensal", "amount": 100.0, "recurrence": "MONTHLY", "recurrenceInterval": 1 },
    "charge": null,
    "credit": { 
        "amount": 216.0, 
        "unusedDays": 72, 
        "coveredDays": 64, 
        "coveredUntil": "2026-11-26", 
        "remainder": 2.67, 
        "lost": 0, 
        "allocations": null 
    },
    "nextCharge": {
        "date": "2026-11-27", 
        "amount": 97.33 
    },
    "warnings": ["O cupom BEMVINDO tinha ciclos limitados e será encerrado com a troca de recorrência."]
}

Campos da resposta

subscriptionIdstring
itemIdstring
typestring
currentobject
newobject
chargeobject
creditobject
Crédito gerado pela troca
nextChargeobject
warningsarray[1]
200plano mais barato com crédito▾
JSON
{
    "subscriptionId": "sub_xxx",
    "itemId": "item_xxx",
    "type": "CREDIT",
    "current": { "priceId": "price_yyy", "amount": 149.9, "recurrence": "MONTHLY", "recurrenceInterval": 1 },
    "new": { "priceId": "price_xxx", "amount": 99.9, "recurrence": "MONTHLY", "recurrenceInterval": 1 },
    "charge": null,
    "credit": {
        "amount": 25.0, 
        "unusedDays": null,
        "coveredDays": null,
        "coveredUntil": null,
        "remainder": null,
        "lost": 0, 
        "allocations": [ 
            {
                "cycleNumber": 3, 
                "chargeDate": "2026-10-10", 
                "amount": 25.0, 
                "coverage": "PARTIAL" 
            }
        ]
    },
    "nextCharge": { "date": "2026-10-10", "amount": 74.9 },
    "warnings": []
}

Campos da resposta

subscriptionIdstring
itemIdstring
typestring
currentobject
newobject
chargeobject
creditobject
nextChargeobject
warningsarray[0]
400sem itemId▾
JSON
{
    "error": {
        "message": "itemId é obrigatório",
        "code": "MISSING_ITEM_ID",
        "details": null,
        "timestamp": "2026-09-24T12:00:00.000Z"
    }
}
400ciclo atual não pago▾
JSON
{
    "error": {
        "message": "A troca de recorrência aproveita o que já foi pago no ciclo atual; quite a cobrança em aberto antes de trocar",
        "code": "RECURRENCE_CHANGE_REQUIRES_PAID_CYCLE",
        "details": null,
        "timestamp": "2026-09-24T12:00:00.000Z"
    }
}