
Liberar e bloquear partes do app pelo plano do usuário
Nesta página · 8 seções
Controle de acesso por funcionalidade é a forma de decidir o que cada usuário pode usar dentro do app olhando para a funcionalidade, e não para o nome do plano que ele assina. Em vez de escrever if (plano === 'pro') em dez lugares, você marca cada parte paga com um identificador e deixa a permissão dizer se ela está liberada.
O que é uma funcionalidade
Uma funcionalidade, no Payments, é um slug: um nome curto que você escolhe e que o seu código consulta, como relatorios-avancados. O slug fica no painel, em Funcionalidades, e é ele que você copia para o código. Depois de criado, o slug não muda, porque já está escrito na sua aplicação.
Cada plano aponta para um conjunto de funcionalidades. Um plano pode incluir relatórios avançados e exportação; outro plano, só exportação. A ligação entre plano e funcionalidade é feita no painel, sem deploy.
Um usuário com uma assinatura ativa recebe as funcionalidades do plano dela. Sem assinatura ativa, não recebe nenhuma. A regra mora no Payments, e o app só pergunta.
Como o SDK React lê as permissões
O PaymentsProvider envolve a aplicação e carrega as permissões do usuário atual a partir da publicKey do projeto e do seu userId. O userId é o identificador que você já usa no seu banco, não um dado do provedor de pagamento.
Com as permissões carregadas, o SDK expõe duas formas de consultar:
import { useHasFeature, FeatureControl } from '@ciromaciel/payments-react'
// Como hook, para decidir dentro de um componente
const liberado = useHasFeature('relatorios-avancados')
// Como componente, para envolver o que é pago
<FeatureControl featureId="relatorios-avancados" fallback={<Upgrade />}>
<RelatorioAvancado />
</FeatureControl>
useHasFeature devolve um booleano. FeatureControl mostra o conteúdo quando a funcionalidade está liberada e o fallback quando não está. O fallback costuma ser um convite para assinar, com um botão que abre o checkout.
Isso resolve a experiência: o usuário que não tem acesso vê uma oferta, não uma tela quebrada. Também evita que a interface mostre botões que levam a lugar nenhum.
Por que a verificação definitiva fica no servidor
Esconder um botão não protege nada. Quem conhece a aplicação pode abrir as ferramentas do navegador, chamar a API diretamente e pedir o relatório mesmo sem o botão aparecer. O SDK roda no cliente, e tudo que roda no cliente pode ser alterado por quem está do outro lado.
Por isso a regra que importa fica no servidor. A rota que devolve o relatório avançado deve checar a permissão antes de responder. Para isso, o seu backend usa a secretKey do projeto, que nunca vai para o navegador, e consulta as permissões do usuário pela API do Payments.
GET https://payments.worker.myinfrastructure.click/sdk/v1/permissions?publicKey=pk_...&userId=...
A resposta traz se o usuário tem assinatura ativa e a lista de funcionalidades liberadas. Se o slug pedido não estiver na lista, o servidor responde com erro e não entrega os dados.
Use o SDK para a tela e o servidor para o dado. Um sem o outro deixa uma brecha.
Quando um usuário ganha ou perde acesso
O acesso muda com o estado da assinatura, e isso chega ao Payments pelo webhook do provedor. Quando o pagamento é confirmado, a assinatura fica ativa e as funcionalidades do plano passam a valer. Quando a cobrança falha ou a assinatura é cancelada, o acesso é retirado.
Você não precisa escrever nada para isso além do webhook já configurado no painel. A alteração chega a useHasFeature na próxima leitura de permissões, e a rota do servidor passa a recusar no mesmo momento.
Perguntas frequentes
Posso checar o plano em vez da funcionalidade?
Pode, mas o código fica acoplado ao nome do plano. Se você renomear o plano ou reorganizar o que ele inclui, precisa mexer no app. Com funcionalidades, a mudança acontece no painel.
O usuário pode burlar o FeatureControl pelo navegador?
Pode ver o componente escondido se o código já estiver na página, por isso o componente não protege dados. A proteção de verdade é a checagem na rota do servidor.
Preciso de um serviço separado para as permissões?
Não. O /sdk/v1/permissions do Payments já devolve o que o usuário pode usar. O seu backend só consulta e decide.
Uma funcionalidade pode estar em mais de um plano?
Sim. Um slug pode ser vinculado a vários planos, e um plano pode ter vários slugs. O usuário fica com a união das funcionalidades da assinatura ativa.
Para continuar lendo
Conhecer o Payments
Para quem já tem planos cadastrados e quer que o app respeite cada um deles, o Payments junta a cobrança, as funcionalidades e as permissões num lugar só. Conhecer o Payments
Fontes
Quem escreveu
Continue lendo
Como cobrar assinatura no seu app sem escrever webhookMais sobre Payments · · 4 min
Guardar dados e arquivos do app sem migration nem credencial de nuvemMais recente · · 5 min
E-mail transacional pelo seu domínio: verificação, eventos e supressãoMais recente · · 6 min
Função serverless com agendamento: código sob demanda com um endpointMais recente · · 6 min
Onde hospedar uma SPA em React ou Vite sem quebrar as rotasMais recente · · 5 min
Como um agente de IA faz login no seu app: OAuth 2.1 e o passo humanoMais recente · · 5 min