Vai al contenuto principale
Un diritto di feature flag trasforma Dodo Payments in un negozio di feature flag consapevole del billing. Associa un flag come advanced_reports a un prodotto, e ogni cliente pagante ottiene un diritto che la tua applicazione può verificare tramite API o mantenere sincronizzato con webhooks. Nessuna piattaforma esterna, nessun OAuth, nessun passo di consegna — il diritto stesso è la capacità.

Cosa viene consegnato

Nulla lascia Dodo Payments — il diritto è il deliverable:
  • Al momento dell’acquisto, il diritto viene creato e passa direttamente a delivered. Non c’è nessuna fase pending, nessuna azione del cliente e nessun modo per il fallimento della consegna.
  • Il diritto porta un payload tipizzato feature: { "feature_type": "boolean", "feature_id": "advanced_reports" }. La tua applicazione legge feature_id per decidere cosa sbloccare.
  • Cancellazione, rimborso o revoca manuale sposta il diritto a revoked, e la tua applicazione vede il flag scomparire.
Gli usi comuni includono gating di funzionalità basati su piani (Pro sblocca analitica), capacità aggiuntive (aggiornamento “API access”), e programmi di accesso anticipato venduti come acquisti una tantum.
feature_id è un identificatore scelto dal merchant, non unico tra le entitlements. Due entitlements possono conferire lo stesso feature_id — ad esempio, un piano Pro mensile e annuale che entrambi concedono advanced_reports.

Crea un feature flag

1

Open Entitlements

Nel tuo dashboard di Dodo Payments, vai a Entitlements e clicca + per iniziare un nuovo entitlement, quindi scegli Feature Flags.
2

Name the flag

Dai al flag un Display Name per il tuo dashboard, un Feature ID che la tua applicazione verificherà (il dashboard suggerisce uno dal nome), e una Description per far sapere al tuo team cosa controlla.
Nuovo modulo Feature Flag con nome di visualizzazione, ID funzionalità, descrizione, e voci di metadati chiave-valore
3

Optionally add metadata

Attiva Meta Data per allegare configurazioni chiave-valore — limiti, nomi di livelli, quote — che vengono consegnati alla tua applicazione insieme al flag. Vedi Allega limiti con metadati.
4

Confirm

Clicca Conferma. Il flag appare nella tua lista di entitlements, pronto per essere associato ai prodotti.
Dashboard Entitlements che mostra il feature flag Advanced Reports con il suo riquadro di attività di concessione

Associa a un prodotto

Apri un prodotto (o creane uno), trova la scheda Entitlements e clicca + per associare gli entitlements esistenti. Seleziona il tuo feature flag e clicca Fatto.
Pannello di associazione Entitlements con il feature flag Advanced Reports selezionato
Il flag associato appare sul modulo del prodotto, e l’anteprima del checkout lo elenca sotto Includes.
Modulo del prodotto con il feature flag Advanced Reports associato nella scheda Entitlements

Configurazione richiesta

CampoRichiestoDescrizione
feature_idIdentificatore che la tua applicazione verifica, ad es. advanced_reports. Non unico tra le entitlements.
feature_typeTipo di capacità conferita. Solo boolean è supportato oggi.

Creare 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"),
    },
  ),
})

Allega limiti con metadati

Un flag booleano risponde “questo cliente ha la funzionalità?”. I metadati rispondono “con quale configurazione?”. I metadati di entitlement accettano valori stringa, intero, numero e booleano, e ogni diritto prende un istantanea congelata dei metadati di entitlement al momento della creazione. Quel comportamento dell’istantanea è ciò che rende sicuro l’uso dei metadati per i limiti di piano:
  • Modificare i metadati dell’entitlement in un secondo momento influisce solo sui futuri diritti. I clienti mantengono i limiti sotto i quali hanno acquistato.
  • L’istantanea viene restituita su ogni diritto come suo campo metadata, quindi una chiamata API ti dà sia il flag che la sua configurazione.
Ad esempio, un flag advanced_reports con { "tier": "pro", "monthly_report_limit": 100 } consente alla tua applicazione di sbloccare il dashboard e applicare il limite di 100 report senza una seconda ricerca. Se successivamente aumenti il limite a 250, i clienti esistenti rimangono a 100 fino a quando non ricevono un nuovo diritto (ad esempio, dopo un cambio di piano).
Usa i metadati per limiti e configurazioni; usa feature_id solo per l’identità. Codificare i limiti nell’id (advanced_reports_100) forza un nuovo flag per ogni cambio di limite e interrompe i controlli della tua applicazione.

Verifica le funzionalità di un cliente

Elenca i diritti di feature flag consegnati a un cliente e costruisci l’insieme di caratteristiche abilitate. L’endpoint restituisce una riga per ogni diritto attraverso tutte le entitlements, filtrabile da 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
  }
}
Il payload feature è popolato solo su concessioni feature_flag; è null per ogni altro tipo di integrazione. Vedi il riferimento API List Customer Grants per la forma completa della risposta.
Controllare l’API su ogni richiesta aggiunge latenza al tuo percorso caldo. Memorizza nella cache l’insieme delle funzionalità per cliente con un TTL breve (minuti, non ore) e invalida la cache dal tuo gestore webhook quando un diritto cambia stato — quella combinazione mantiene i controlli veloci e le revoche quasi istantanee.

Ciclo di vita

I diritti di feature flag seguono il ciclo di vita standard grant lifecycle con una semplificazione: non c’è nessun passo di consegna, quindi i diritti non siedono mai in pending e non si spostano mai a failed.
TriggerEffetto
Pagamento una tantum riuscito / abbonamento diventa attivoDiritto creato con status: delivered e delivered_at impostati.
Abbonamento in pausa, cancellato o scadutoDiritto revocato con il corrispondente revocation_reason.
Rimborso su un pagamento una tantumDiritto revocato con revocation_reason: refund.
Abbonamento ripristinato (ad esempio, riscossione riuscita)Il diritto revocato viene ripristinato a delivered — stesso diritto id, campi di revoca cancellati.
Revoca API manualeDiritto revocato con revocation_reason: manual. Non viene ripristinato automaticamente al rinnovo.
I diritti sono idempotenti per ogni entitlement e cliente: mentre un cliente ha un diritto non revocato per un flag, acquisti e rinnovi ripetuti non creano duplicati.

Webhooks

Iscriviti agli eventi entitlement_grant.* per rispecchiare i flag nel tuo database invece di effettuare polling:
  • entitlement_grant.created — arriva già delivered con il payload feature. Abilita la funzionalità.
  • entitlement_grant.delivered — si attiva quando un diritto precedentemente revocato viene ripristinato. Riabilita la funzionalità.
  • entitlement_grant.revoked — accesso ritirato. Disabilita la funzionalità e controlla revocation_reason per decidere il tuo messaggio.
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);
});
Non ci sono entitlement_grant.failed per i feature flags — la consegna avviene interamente all’interno di Dodo Payments e non può fallire.

Esempio: Il piano Pro sblocca i report avanzati

  1. Crea il flag. feature_id: advanced_reports con metadati { "tier": "pro", "monthly_report_limit": 100 }.
  2. Associalo al prodotto di abbonamento del tuo Pro Plan.
  3. Un cliente si abbona. Dodo Payments crea un diritto delivered e genera entitlement_grant.created; il tuo gestore webhook abilita advanced_reports per il cliente con un limite di 100.
  4. La tua app attiva la funzione. Al caricamento del dashboard, controlla l’insieme delle funzionalità memorizzato nella cache (o chiama listEntitlementGrants) e visualizza la scheda dei report solo quando advanced_reports è presente.
  5. Il cliente cancella. Dodo Payments revoca il diritto e genera entitlement_grant.revoked; il tuo gestore disabilita la funzione. Se il cliente in seguito si riprende tramite riscossione, entitlement_grant.delivered la ripristina — nessuna modifica al codice necessaria.

Migliori pratiche

  • Usa ID funzionalità stabili in snake_case. Il codice della tua applicazione controlla queste stringhe; rinominare uno è un cambiamento radicale su entrambi i lati.
  • Un flag per capacità. Preferisci advanced_reports + api_access come due entitlements su un singolo pro_bundle — revoca e combinazioni di piani rimangono pulite.
  • Guida lo stato dai webhooks, verifica con l’API. I webhooks mantengono il tuo database aggiornato; l’endpoint della lista è la fonte della verità per i lavori di riconciliazione e gli eventi cache miss.
  • Tratta revoked come immediato. Un flag revocato significa che il cliente non sta più pagando per la funzionalità. Attivalo alla prossima richiesta, non alla prossima sessione.
  • Metti i limiti nei metadati, non nel codice. Cambiare una quota richiede solo di modificare la entitlement — i nuovi clienti la acquisiscono automaticamente mentre i diritti esistenti mantengono la loro istantanea acquistata.

Best practices

  • Use stable, snake_case feature ids. Your application code checks these strings; renaming one is a breaking change on both sides.
  • One flag per capability. Prefer advanced_reports + api_access as two entitlements over a single pro_bundle — revocation and plan mixes stay clean.
  • Drive state from webhooks, verify with the API. Webhooks keep your database current; the list endpoint is the source of truth for reconciliation jobs and cache misses.
  • Treat revoked as immediate. A revoked flag means the customer is no longer paying for the feature. Gate on the next request, not the next session.
  • Put limits in metadata, not in code. Changing a quota then only requires editing the entitlement — new customers pick it up automatically while existing grants keep their purchased snapshot.
Ultima modifica il 9 luglio 2026