Pular para o conteúdo principal
Um entitlement de feature flag transforma o Dodo Payments em um armazenamento de flags de recurso ciente de faturamento. Anexe uma flag como advanced_reports a um produto, e todo cliente pagante recebe uma concessão que sua aplicação pode verificar via API ou manter sincronizado com webhooks. Nenhuma plataforma externa, sem OAuth, sem etapa de entrega — a própria concessão é a capacidade.

O que é entregue

Nada sai do Dodo Payments — a concessão é a entrega:
  • Na compra, a concessão é criada e move-se diretamente para delivered. Não há fase pending, nenhuma ação do cliente, e nenhuma possibilidade de falha na entrega.
  • A concessão carrega um payload digitado feature: { "feature_type": "boolean", "feature_id": "advanced_reports" }. Sua aplicação lê feature_id para decidir o que desbloquear.
  • Cancelamento, reembolso, ou revogação manual movem a concessão para revoked, e sua aplicação vê a flag desaparecer.
Usos comuns incluem feature gating baseado em plano (Pro desbloqueia analytics), capacidades adicionais (um upgrade de “acesso à API”), e programas de acesso antecipado vendidos como compras únicas.
feature_id é um identificador escolhido pelo comerciante, não único entre os entitlements. Dois entitlements podem conferir o mesmo feature_id — por exemplo, um plano Pro mensal e anual ambos concedendo advanced_reports.

Criar uma feature flag

1

Open Entitlements

No seu painel do Dodo Payments, vá para Entitlements e clique em + para iniciar um novo entitlement, depois escolha Feature Flags.
2

Name the flag

Dê à flag um Nome de Exibição para seu painel, um ID de Recurso que sua aplicação irá verificar (o painel sugere um a partir do nome), e uma Descrição para que sua equipe saiba o que controla.
Novo formulário de Feature Flag com nome de exibição, ID de recurso, descrição e entradas de metadados chave-valor
3

Optionally add metadata

Alternar Meta Data para anexar configuração chave-valor — limites, nomes de níveis, cotas — que é entregue à sua aplicação junto com a flag. Veja Anexar limites com metadados.
4

Confirm

Clique em Confirmar. A flag aparece na sua lista de entitlements, pronta para ser anexada aos produtos.
Painel de Entitlements mostrando a feature flag de Advanced Reports com seu painel de atividades de concessão

Anexar a um produto

Abra um produto (ou crie um), encontre o cartão Entitlements, e clique em + para anexar entitlements existentes. Selecione sua feature flag e clique em Concluir.
Painel de anexação de Entitlements com a feature flag de Advanced Reports selecionada
A flag anexada aparece no formulário do produto, e a visualização da finalização da compra a lista em Inclui.
Formulário de produto com a feature flag de Advanced Reports anexada no cartão de Entitlements

Configuração obrigatória

CampoObrigatórioDescrição
feature_idSimIdentificador que sua aplicação verifica, por exemplo, advanced_reports. Não único entre os entitlements.
feature_typeSimTipo de capacidade conferida. Apenas boolean é suportado hoje.

Criar via API

import DodoPayments from 'dodopayments';

const client = new DodoPayments({
  bearerToken: process.env['DODO_PAYMENTS_API_KEY'],
  environment: 'test_mode',
});

const entitlement = await client.entitlements.create({
  name: 'Advanced Reports',
  integration_type: 'feature_flag',
  integration_config: {
    feature_type: 'boolean',
    feature_id: 'advanced_reports',
  },
  metadata: {
    tier: 'pro',
    monthly_report_limit: 100,
  },
});
client.entitlements.create(
    name="Advanced Reports",
    integration_type="feature_flag",
    integration_config={
        "feature_type": "boolean",
        "feature_id": "advanced_reports",
    },
    metadata={
        "tier": "pro",
        "monthly_report_limit": 100,
    },
)
client.Entitlements.New(ctx, dodopayments.EntitlementNewParams{
  Name:            dodopayments.F("Advanced Reports"),
  IntegrationType: dodopayments.F(dodopayments.EntitlementIntegrationTypeFeatureFlag),
  IntegrationConfig: dodopayments.F[dodopayments.IntegrationConfigUnionParam](
    dodopayments.IntegrationConfigFeatureFlagConfigParam{
      FeatureType: dodopayments.F(dodopayments.FeatureTypeBoolean),
      FeatureID:   dodopayments.F("advanced_reports"),
    },
  ),
})

Anexar limites com metadados

Uma flag booleana responde “este cliente possui o recurso?”. Os metadados respondem “com qual configuração?”. Os metadados de entitlement aceitam valores de string, inteiro, número e booleano, e cada concessão toma um instantâneo congelado dos metadados do entitlement no momento em que é criada. Esse comportamento de instantâneo é o que torna os metadados seguros para usar em limites de plano:
  • Editar os metadados do entitlement posteriormente afeta apenas as concessões futuras. Os clientes mantêm os limites sob os quais foram comprados.
  • O instantâneo é retornado em cada concessão como seu campo metadata, então uma chamada API fornece tanto a flag quanto sua configuração.
Por exemplo, uma flag advanced_reports com { "tier": "pro", "monthly_report_limit": 100 } permite que sua aplicação desbloqueie o dashboard e imponha a cota de 100 relatórios sem uma segunda consulta. Se mais tarde você aumentar o limite para 250, os clientes existentes permanecem em 100 até receberem uma nova concessão (por exemplo, após uma mudança de plano).
Use metadados para limites e configuração; use feature_id apenas para identidade. Codificar limites no id (advanced_reports_100) força uma nova flag para cada mudança de limite e quebra as verificações da sua aplicação.

Verificar recursos de um cliente

Liste concessões de feature-flag entregues a um cliente e construa o conjunto de recursos habilitados. O endpoint retorna uma linha por concessão em todos os entitlements, filtrável por integration_type e status.
const features = new Map<string, Record<string, unknown>>();

for await (const grant of client.customers.listEntitlementGrants('cus_abc123', {
  integration_type: 'feature_flag',
  status: 'Delivered',
})) {
  if (grant.feature) {
    features.set(grant.feature.feature_id, grant.metadata ?? {});
  }
}

if (features.has('advanced_reports')) {
  const limit = features.get('advanced_reports')?.monthly_report_limit;
  // unlock the dashboard, enforce the limit
}
page = client.customers.list_entitlement_grants(
    customer_id="cus_abc123",
    integration_type="feature_flag",
    status="Delivered",
)

features = {
    grant.feature.feature_id: grant.metadata
    for grant in page.items
    if grant.feature
}

if "advanced_reports" in features:
    limit = features["advanced_reports"].get("monthly_report_limit")
page, _ := client.Customers.ListEntitlementGrants(
  ctx, "cus_abc123",
  dodopayments.CustomerListEntitlementGrantsParams{
    IntegrationType: dodopayments.F("feature_flag"),
    Status:          dodopayments.F("Delivered"),
  },
)

features := map[string]bool{}
for _, grant := range page.Items {
  if grant.Feature.FeatureID != "" {
    features[grant.Feature.FeatureID] = true
  }
}
O payload feature é populado apenas nas concessões feature_flag; ele é null para todos os outros tipos de integração. Veja a referência de API List Customer Grants para a forma completa da resposta.
Verificar a API em cada solicitação adiciona latência ao seu caminho quente. Armazene em cache o conjunto de funcionalidades por cliente com um TTL curto (minutos, não horas), e invalide o cache do seu manipulador de webhook quando uma concessão mudar de estado — essa combinação mantém as verificações rápidas e as revogações quase instantâneas.

Ciclo de vida

As concessões de feature flag seguem o ciclo de vida padrão da concessão com uma simplificação: não há etapa de entrega, então as concessões nunca se encontram em pending e nunca se movem para failed.
AcionadorEfeito
Pagamento único bem-sucedido / assinatura torna-se ativaConcessão criada com status: delivered e delivered_at definidos.
Assinatura em espera, cancelada ou expiradaConcessão revogada com revocation_reason correspondente.
Reembolso em um pagamento únicoConcessão revogada com revocation_reason: refund.
Assinatura recupera (por exemplo, cobrança bem-sucedida)A concessão revogada é restaurada para delivered — mesma concessão id, campos de revogação limpos.
Revogação manual via APIConcessão revogada com revocation_reason: manual. Não é restaurada automaticamente na renovação.
As concessões são idempotentes por entitlement e cliente: enquanto um cliente tiver uma concessão não revogada para uma flag, compras repetidas e renovações não criam duplicatas.

Webhooks

Assine os eventos entitlement_grant.* para espelhar flags no seu próprio banco de dados em vez de fazer polling:
  • entitlement_grant.created — chega já delivered com o payload feature. Habilite o recurso.
  • entitlement_grant.delivered — dispara quando uma concessão anteriormente revogada é restaurada. Re-habilite o recurso.
  • entitlement_grant.revoked — acesso retirado. Desabilite o recurso e verifique revocation_reason para decidir sua mensagem.
TypeScript
app.post('/webhooks/dodo', async (req, res) => {
  const event = req.body;

  if (event.type.startsWith('entitlement_grant.') && event.data.feature) {
    const { customer_id, feature } = event.data;
    const enabled = event.type !== 'entitlement_grant.revoked';

    await db.customerFeatures.upsert({
      customerId: customer_id,
      featureId: feature.feature_id,
      enabled,
      config: event.data.metadata ?? {},
    });
  }

  res.sendStatus(200);
});
Não há entitlement_grant.failed para feature flags — a entrega acontece inteiramente dentro do Dodo Payments e não pode falhar.

Exemplo: Plano Pro desbloqueia relatórios avançados

  1. Crie a flag. feature_id: advanced_reports com metadados { "tier": "pro", "monthly_report_limit": 100 }.
  2. Anexe-a ao seu produto de assinatura Pro Plan.
  3. Um cliente se inscreve. O Dodo Payments cria uma concessão delivered e dispara entitlement_grant.created; seu manipulador de webhook habilita advanced_reports para o cliente com um limite de 100.
  4. Sua aplicação bloqueia o recurso. Ao carregar o dashboard, verifique o conjunto de funcionalidades em cache (ou chame listEntitlementGrants) e exiba a aba de relatórios apenas quando advanced_reports estiver presente.
  5. O cliente cancela. O Dodo Payments revoga a concessão e dispara entitlement_grant.revoked; seu manipulador desabilita o recurso. Se o cliente se recuperar posteriormente por meio de dunning, entitlement_grant.delivered o restaura — nenhuma alteração de código necessária.

Melhores práticas

  • Use ids de recursos estáveis e em snake_case. O código da sua aplicação verifica essas strings; renomear uma é uma mudança quebradora em ambos os lados.
  • Uma flag por capacidade. Prefira advanced_reports + api_access como dois entitlements ao invés de um único pro_bundle — a revogação e as misturas de planos permanecem limpas.
  • Dirija o estado a partir de webhooks, verifique com a API. Webhooks mantêm seu banco de dados atualizado; o endpoint de lista é a fonte de verdade para trabalhos de reconciliação e falhas de cache.
  • Trate revoked como imediato. Uma flag revogada significa que o cliente não está mais pagando pelo recurso. Bloqueie na próxima solicitação, não na próxima sessão.
  • Coloque limites em metadados, não em código. Alterar uma cota só requer editar o entitlement — novos clientes a capturam automaticamente enquanto concessões existentes mantêm seu instantâneo comprado.
Última modificação em 9 de julho de 2026