Documentation Index Fetch the complete documentation index at: https://docs.chargefy.io/llms.txt
Use this file to discover all available pages before exploring further.
Manter o estado do cliente sincronizado com a Chargefy é essencial para controlar o acesso a funcionalidades e verificar assinaturas ativas. Este guia apresenta os padrões recomendados.
Obtendo o Estado do Cliente
Use o SDK para buscar as informações completas do cliente, incluindo assinaturas.
import { Chargefy } from '@chargefy/sdk' ;
const chargefy = new Chargefy ({
accessToken: process . env . CHARGEFY_ACCESS_TOKEN ,
server: 'production' ,
});
// Buscar cliente por ID
const customer = await chargefy . customers . get ({
id: 'customer_id' ,
});
// Buscar cliente por email
const customers = await chargefy . customers . list ({
email: 'cliente@exemplo.com' ,
});
Verificando Status da Assinatura
O padrão mais comum é verificar se o cliente possui uma assinatura ativa antes de liberar acesso a recursos.
async function checkSubscriptionStatus ( customerId : string ) {
const subscriptions = await chargefy . subscriptions . list ({
customerId ,
});
const activeSubscription = subscriptions . result . items . find (
( sub ) => sub . status === 'active'
);
return {
isActive: !! activeSubscription ,
subscription: activeSubscription ,
plan: activeSubscription ?. productId ,
currentPeriodEnd: activeSubscription ?. currentPeriodEnd ,
};
}
Status Possíveis da Assinatura
Status Descrição activeAssinatura ativa e pagamento em dia past_duePagamento atrasado, ainda dentro do período de tolerância canceledAssinatura cancelada pelo cliente ou sistema incompletePagamento inicial pendente trialingPeríodo de teste ativo
Padrão de Cache Local
Para evitar chamadas excessivas à API, implemente um cache local do estado do cliente.
interface CustomerState {
customerId : string ;
isActive : boolean ;
plan : string | null ;
lastSyncedAt : Date ;
}
class CustomerStateManager {
private cache : Map < string , CustomerState > = new Map ();
private cacheTTL = 5 * 60 * 1000 ; // 5 minutos
async getState ( customerId : string ) : Promise < CustomerState > {
const cached = this . cache . get ( customerId );
if ( cached && Date . now () - cached . lastSyncedAt . getTime () < this . cacheTTL ) {
return cached ;
}
return this . syncState ( customerId );
}
async syncState ( customerId : string ) : Promise < CustomerState > {
const subscriptions = await chargefy . subscriptions . list ({ customerId });
const activeSubscription = subscriptions . result . items . find (
( sub ) => sub . status === 'active' || sub . status === 'trialing'
);
const state : CustomerState = {
customerId ,
isActive: !! activeSubscription ,
plan: activeSubscription ?. productId ?? null ,
lastSyncedAt: new Date (),
};
this . cache . set ( customerId , state );
return state ;
}
invalidate ( customerId : string ) {
this . cache . delete ( customerId );
}
}
Sincronização via Webhooks
A forma mais confiável de manter o estado atualizado é reagir a eventos via webhooks. Isso garante que mudanças feitas fora da sua aplicação (como cancelamentos ou renovações) sejam refletidas imediatamente.
Eventos Relevantes
Evento Quando Ocorre subscription.createdNova assinatura criada subscription.updatedAssinatura atualizada (plano, status) subscription.canceledAssinatura cancelada subscription.activeAssinatura ativada após pagamento
Exemplo de Handler de Webhook
import express from 'express' ;
import { validateWebhookSignature } from '@chargefy/sdk' ;
const app = express ();
const stateManager = new CustomerStateManager ();
app . post ( '/webhooks/chargefy' , express . raw ({ type: 'application/json' }), async ( req , res ) => {
const signature = req . headers [ 'webhook-signature' ] as string ;
const payload = req . body . toString ();
// Validar assinatura do webhook
if ( ! validateWebhookSignature ( payload , signature , process . env . CHARGEFY_WEBHOOK_SECRET ! )) {
return res . status ( 401 ). send ( 'Assinatura inválida' );
}
const event = JSON . parse ( payload );
switch ( event . type ) {
case 'subscription.active' :
case 'subscription.updated' :
case 'subscription.canceled' :
// Invalidar cache para forçar re-sincronização
stateManager . invalidate ( event . data . customerId );
// Atualizar banco de dados
await updateCustomerInDatabase ( event . data . customerId , {
subscriptionStatus: event . data . status ,
plan: event . data . productId ,
});
break ;
}
res . status ( 200 ). json ({ received: true });
});
Hook React para Estado do Cliente
Use um hook customizado para acessar o estado do cliente em componentes React.
import { useState , useEffect , createContext , useContext } from 'react' ;
interface CustomerState {
isActive : boolean ;
plan : string | null ;
loading : boolean ;
error : Error | null ;
}
const CustomerStateContext = createContext < CustomerState | null >( null );
export function CustomerStateProvider ({ customerId , children } : {
customerId : string ;
children : React . ReactNode ;
}) {
const [ state , setState ] = useState < CustomerState >({
isActive: false ,
plan: null ,
loading: true ,
error: null ,
});
useEffect (() => {
let cancelled = false ;
async function fetchState () {
try {
const response = await fetch ( `/api/customers/ ${ customerId } /state` );
const data = await response . json ();
if ( ! cancelled ) {
setState ({
isActive: data . isActive ,
plan: data . plan ,
loading: false ,
error: null ,
});
}
} catch ( error ) {
if ( ! cancelled ) {
setState (( prev ) => ({
... prev ,
loading: false ,
error: error as Error ,
}));
}
}
}
fetchState ();
// Re-sincronizar a cada 5 minutos
const interval = setInterval ( fetchState , 5 * 60 * 1000 );
return () => {
cancelled = true ;
clearInterval ( interval );
};
}, [ customerId ]);
return (
< CustomerStateContext.Provider value = { state } >
{ children }
</ CustomerStateContext.Provider >
);
}
export function useCustomerState () {
const context = useContext ( CustomerStateContext );
if ( ! context ) {
throw new Error ( 'useCustomerState deve ser usado dentro de CustomerStateProvider' );
}
return context ;
}
Uso do Hook
function PremiumFeature () {
const { isActive , plan , loading } = useCustomerState ();
if ( loading ) {
return < div > Carregando... </ div > ;
}
if ( ! isActive ) {
return (
< div >
< p > Este recurso requer uma assinatura ativa. </ p >
< a href = "/pricing" > Ver planos </ a >
</ div >
);
}
return < div > Conteúdo premium disponível no plano { plan } . </ div > ;
}
Boas Práticas
Use webhooks como fonte primária
Não dependa apenas de polling. Configure webhooks para receber atualizações em tempo real e use chamadas à API apenas como fallback ou para sincronização inicial.
Cache o estado do cliente por um período curto (3-5 minutos) para reduzir chamadas à API, mas mantenha um mecanismo de invalidação via webhooks.
Trate falhas graciosamente
Se a API estiver indisponível, use o último estado conhecido do cache ou banco de dados. Nunca bloqueie o acesso do usuário por falha temporária na verificação.
Persista o estado no banco de dados
Além do cache em memória, salve o estado do cliente no seu banco de dados. Isso garante que a aplicação funcione mesmo após reinicializações.