Saltar para o conteúdo

Troca a opção de plano da assinatura

POST/api/subscriptions/{id}/change-tier

Auth
Exige token
X-CommunityId
X-CommunityId Envie o X-CommunityId da comunidade em que a operação acontece.

FIN-68. Move a assinatura do plano para outra opção de plano à venda na mesma comunidade (de outro plano também, ex.: Starter → Growth). Só o próprio assinante; assinatura de outra pessoa ou de outra comunidade responde 404. A assinatura continua a mesma (mesmo `id`, histórico, período e adicionais); muda `productId`, `billingAmount` e `billingInterval`. Veja a prévia em `POST /change-tier/quote`. **Upgrade** (opção mais cara na mesma periodicidade, com `immediate: true`): vale na hora e cobra agora, no cartão salvo do membro (o padrão, ou `paymentMethodId`), a diferença proporcional aos dias que faltam no período; a próxima renovação já vem no preço novo. Abaixo do piso (menos de 3 dias ou de R$ 10) troca sem cobrar. A cobrança é uma venda como as outras: taxa da plataforma e `feePayer` da opção nova, parcelas até o `maxInstallments` da prévia (`installments`). Se o cartão for recusado ou a cobrança não for confirmada na hora, **nada muda**: 402 (recusa) ou 502 (provedor fora do ar). Sem cartão salvo: 400 `param = paymentMethodId`. **Agendada** (opção mais barata ou de mesmo preço, outra periodicidade — mensal ↔ anual, sem proporcional entre períodos —, upgrade com `immediate: false`, ou upgrade que tiraria um adicional): nada é cobrado agora. Na renovação de `effectiveDate` a assinatura passa para a opção nova e a cobrança já é no preço e na periodicidade dela. Uma nova troca agendada substitui a anterior; dá para desfazer com `DELETE /scheduled-change`. **Adicionais** (F-37): os que a opção nova oferece continuam (no valor da periodicidade nova); os que ela não oferece terminam na troca. **Contrato** (F-35): o contrato em vigor continua até o fim; sem contrato, uma opção nova com contrato começa o dela na troca. **Cupom**: deixa de valer na troca. Recusas, todas antes de qualquer cobrança: 400 `param = id` quando a assinatura não está `ACTIVE`, tem cancelamento agendado, é cortesia ou é um adicional ligado a um plano; 400 `param = newProductId` para a mesma opção, opção que não é de plano, fora de venda, em outra moeda, ou já assinada; 404 `newProductId` de outra comunidade ou inexistente; 403 `newProductId` para um adicional sem o plano que ele exige; 403 `param = id` quando a comunidade não tem informações comerciais aprovadas (só no upgrade cobrado); 409 `param = id` enquanto há uma cobrança de renovação do próximo período em aberto (PIX ou boleto já gerado, ou cartão em análise). O texto da recusa vem em `errors[0].message`. Responde 200. `data`: `mode` (`IMMEDIATE` ou `SCHEDULED`), `changeType`, `scheduledReason`, `effectiveDate`, `currentProduct`, `newProduct`, `subscription` (como ficou), `scheduledChange` (o mesmo objeto de `GET /scheduled-change`, ou `null`), `charge` (`purchaseId`, `orderId`, `amount`, `currency`, `installments`, `feeBreakdown` só com a taxa da plataforma; `null` sem cobrança), `addOns`, `contract`, `couponEnds`.

Parâmetros

NomeOndeTipoDescrição
idobrigatóriopathstring (uuid)

Headers

NomeTipoDescrição
X-CommunityIdopcionalstring (uuid)ID da comunidade em que a operação acontece. Obrigatório na maioria dos endpoints com escopo de comunidade.

Corpo da requisição application/json

NomeTipoDescrição
newProductIdobrigatóriostring (uuid)
immediateopcionalboolean`true` aplica um upgrade agora, com a cobrança proporcional; ausente ou `false`, agenda para o fim do período. Downgrade e troca de periodicidade são sempre agendados.
paymentMethodIdopcionalstring (uuid)Cartão salvo do membro (/payment-methods) para o upgrade cobrado agora. Ausente: o cartão padrão.
installmentsopcionalintegerParcelas do proporcional, até o `maxInstallments` da prévia. · ≥ 1, ≤ 12

Respostas

CódigoDescrição
200Operação realizada com sucesso.
400Requisição inválida — falha de validação.
401Token ausente, inválido ou expirado.
402Requisição inválida — falha de validação.
403Autenticado, mas sem permissão para esta operação.
404Recurso não encontrado.
409Conflito com o estado atual do recurso.
500Erro interno do servidor.
502Erro interno do servidor.

Exemplo com curl

curl -X POST "https://api.memberfy.net/api/subscriptions/<id>/change-tier" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-CommunityId: $COMMUNITY_ID" \
  -H "Content-Type: application/json" \
  -d '{"newProductId":"e8a1c3f5-7b9d-4f2a-8c6e-0d2f4a6b8c1e"}'