> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Feature Flag Entitlement

> 購入に基づいてアプリケーション内の機能を制御する。機能フラグの認可は、支払い時にブール型の機能を即座に提供し、キャンセル時に自動的に取り消される。

<Info>
  機能フラグの認可により、Dodo Paymentsを請求対応の機能フラグストアに変えることができます。`advanced_reports`のようなフラグを製品に付けると、支払済みの顧客全員に付与が行われ、APIを通じてチェックしたり、Webhookで同期を維持したりできます。外部プラットフォームやOAuth、配信ステップは不要で、付与そのものが機能です。
</Info>

## What gets delivered

Dodo Paymentsからは何も離れません。付与が**成果物**です：

* 購入時に付与が作成され、即座に`delivered`に移行します。`pending`フェーズはなく、顧客の行動も不要で、配信が失敗することはありません。
* 付与には型指定された`feature`ペイロードが含まれます：`{ "feature_type": "boolean", "feature_id": "advanced_reports" }`。アプリケーションは`feature_id`を読み込んでどの機能を解除するかを判断します。
* キャンセル、払い戻し、または手動による取り消しは、付与を`revoked`に移動させ、アプリケーションからフラグが消えることがわかります。

よくある使用例として、プランに基づく機能制御（プロが分析を解除）、アドオン機能（"APIアクセス"のアップグレード）、一度限りの購入として販売されるアーリーアクセスプログラムがあります。

<Note>
  `feature_id`は商人が選択した識別子で、認可全体にわたって一意ではありません。2つの認可が同じ`feature_id`を付与することがあります。たとえば、月次および年次のプロプランの両方が`advanced_reports`を付与する場合があります。
</Note>

## Create a feature flag

<Steps>
  <Step title="Open Entitlements">
    Dodo Paymentsダッシュボードで**Entitlements**に移動し、\*\*+\*\*をクリックして新しい認可を開始し、**Feature Flags**を選択します。
  </Step>

  <Step title="Name the flag">
    フラグにダッシュボード用の**表示名**、アプリケーションが確認する**機能ID**（ダッシュボードが名前から提案するもの）およびそれが制御する内容をチームに知らせる**説明**を設定します。

    <Frame caption="Creating a feature flag. The Feature ID is what your application checks; Meta Data attaches limits alongside the flag.">
      <img src="https://mintcdn.com/dodopayments/oS2MTbJuY6MeBjjs/images/entitlements/feature-flags/create.png?fit=max&auto=format&n=oS2MTbJuY6MeBjjs&q=85&s=08d8fc2cfee102ff08fd150c76b5fcf9" alt="表示名、機能ID、説明、メタデータのキー-バリューエントリを備えた新しい機能フラグフォーム" style={{ maxHeight: '500px', width: 'auto' }} width="1196" height="776" data-path="images/entitlements/feature-flags/create.png" />
    </Frame>
  </Step>

  <Step title="Optionally add metadata">
    **メタデータ**を切り替えて、フラグとともにアプリケーションに配信されるキー-バリュー設定（制限、ティエ名、クオータなど）をアタッチします。詳細は[メタデータで制限を付ける](#attach-limits-with-metadata)を参照してください。
  </Step>

  <Step title="Confirm">
    **確認**をクリックします。フラグが認可リストに表示され、製品に付属する準備が整います。

    <Frame caption="The created feature flag. The right pane tracks every customer grant issued from it.">
      <img src="https://mintcdn.com/dodopayments/oS2MTbJuY6MeBjjs/images/entitlements/feature-flags/list.png?fit=max&auto=format&n=oS2MTbJuY6MeBjjs&q=85&s=02eedcbbf7ece9f67d375c984c5515b9" alt="付与活動パネルを備えたAdvanced Reports機能フラグを示す認可ダッシュボード" style={{ maxHeight: '500px', width: 'auto' }} width="1316" height="898" data-path="images/entitlements/feature-flags/list.png" />
    </Frame>
  </Step>
</Steps>

## Attach to a product

製品を開く（または作成する）、**Entitlements**カードを見つけて\*\*+\*\*をクリックし、既存の認可をアタッチします。機能フラグを選択し、**完了**をクリックします。

<Frame caption="Attaching the feature flag to a product. One product can deliver multiple entitlements.">
  <img src="https://mintcdn.com/dodopayments/oS2MTbJuY6MeBjjs/images/entitlements/feature-flags/attach-picker.png?fit=max&auto=format&n=oS2MTbJuY6MeBjjs&q=85&s=da2137873e285cc6ce0ce234fe899ed3" alt="Advanced Reports機能フラグが選択された認可アタッチパネル" style={{ maxHeight: '500px', width: 'auto' }} width="1316" height="898" data-path="images/entitlements/feature-flags/attach-picker.png" />
</Frame>

アタッチされたフラグは製品フォームに表示され、チェックアウトプレビューには**含まれている**としてリストされます。

<Frame caption="The product now includes the feature flag. Every successful purchase or active subscription grants it.">
  <img src="https://mintcdn.com/dodopayments/oS2MTbJuY6MeBjjs/images/entitlements/feature-flags/attach-to-product.png?fit=max&auto=format&n=oS2MTbJuY6MeBjjs&q=85&s=3556181389997edddde9c396d0ce408d" alt="EntitlementsカードにAdvanced Reports機能フラグがアタッチされた製品フォーム" style={{ maxHeight: '500px', width: 'auto' }} width="1316" height="898" data-path="images/entitlements/feature-flags/attach-to-product.png" />
</Frame>

## Required configuration

| Field          | Required | Description                                                 |
| -------------- | -------- | ----------------------------------------------------------- |
| `feature_id`   | はい       | アプリケーションがチェックする識別子、例：`advanced_reports`。認可全体にわたって一意ではありません。 |
| `feature_type` | はい       | 付与される機能の種類。今日サポートされているのは、`boolean`のみです。                     |

### Create via API

<CodeGroup>
  ```typescript TypeScript theme={null} theme={null}
  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,
    },
  });
  ```

  ```python Python theme={null} theme={null}
  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,
      },
  )
  ```

  ```go Go theme={null} theme={null}
  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"),
      },
    ),
  })
  ```
</CodeGroup>

***

## Attach limits with metadata

ブールフラグは「この顧客がこの機能を持っていますか？」に答えます。メタデータは「どのような設定で？」に答えます。認可メタデータは文字列、整数、数値、ブール値を受け入れることができ、各認可は作成時に認可のメタデータの**固定スナップショット**を取得します。

このスナップショット動作がメタデータをプランの制限に利用する際の安全性を提供します：

* 後に認可のメタデータを編集しても、**将来の**付与にのみ影響します。顧客は購入時の制限が維持されます。
* スナップショットは各付与にその`metadata`フィールドとして返されるため、1回のAPIコールでフラグとその設定の両方を取得できます。

たとえば、`advanced_reports`フラグと`{ "tier": "pro", "monthly_report_limit": 100 }`を持つ場合、アプリケーションはダッシュボードを解除し、100件のレポートクオータを強制することができます。後で制限を250に引き上げても、既存の顧客は100のままで、プランが変更されたときに新しい付与を受け取るまで変更されません。

<Tip>
  制限や設定にメタデータを使用してください。`feature_id`はアイデンティティのみに使用します。識別子に制限をエンコードする（`advanced_reports_100`）は、制限変更のたびに新しいフラグを強制し、アプリケーションのチェックを壊します。
</Tip>

***

## Check a customer's features

顧客にデリバリーされた機能フラグの付与をリストアップして、利用可能な機能のセットを構築します。このエンドポイントはすべての認可にわたって、付与ごとに1行を返し、`integration_type`や`status`でフィルタリング可能です。

<CodeGroup>
  ```typescript TypeScript theme={null} theme={null}
  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
  }
  ```

  ```python Python theme={null} theme={null}
  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")
  ```

  ```go Go theme={null} theme={null}
  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
    }
  }
  ```
</CodeGroup>

<Note>
  `feature`ペイロードは`feature_flag`付与のみに入力されます。他のすべての統合タイプに対しては`null`です。完全な応答形状については、[List Customer Grants](/api-reference/entitlements/list-customer-grants) APIリファレンスを参照してください。
</Note>

毎回のリクエストでAPIをチェックすると、ホットパスに遅延が生じます。顧客ごとの機能セットを短いTTLでキャッシュし（数分、数時間ではない）、付与の状態が変わるとWebhookハンドラからキャッシュを無効化します。この組み合わせで、チェックが速く、取り消しが即座に近くなります。

***

## Lifecycle

機能フラグの付与は、[付与のライフサイクル](/features/entitlements/introduction#how-grants-work)と同じ標準に従いますが、一つ簡素化されています：配信ステップがないため、付与は`pending`に置かれることがなく、`failed`に移動することがありません。

| Trigger                    | Effect                                                      |
| -------------------------- | ----------------------------------------------------------- |
| 一回払いの成功 / サブスクリプションのアクティブ化 | `status: delivered`と`delivered_at`が設定された付与が作成されます。          |
| サブスクリプションの保留、キャンセル、または期限切れ | 対応する`revocation_reason`で付与が取り消されます。                         |
| 一回払いの払い戻し                  | `revocation_reason: refund`で付与が取り消されます。                     |
| サブスクリプションの回復（例えば、督促が成功）    | 無効になった付与が`delivered`に復元されます。 — 同じ付与`id`で、取り消しフィールドがクリアされます。 |
| 手動API取り消し                  | `revocation_reason: manual`で付与が取り消されます。更新時には自動復元されません。      |

付与は認可および顧客ごとに冪等性を持ちます：顧客がフラグの未取り消しの付与を持つ間は、リピート購入と更新は重複を作成しません。

***

## Webhooks

[`entitlement_grant.*`イベント](/developer-resources/webhooks/intents/entitlement-grant)を購読して、フラグをポーリングする代わりに自分のデータベースにミラーリングします：

* `entitlement_grant.created` — `delivered`としてすでに到着しており、`feature`ペイロード付きです。機能を有効にします。
* `entitlement_grant.delivered` — 以前に取り消された付与が復元されたときに発火します。機能を再有効化します。
* `entitlement_grant.revoked` — アクセスが取り消されました。機能を無効にし、メッセージングを決定するために`revocation_reason`を確認します。

```typescript TypeScript theme={null} theme={null}
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);
});
```

機能フラグに対して`entitlement_grant.failed`はありません — 配信は完全にDodo Payments内で行われ、失敗することはありません。

***

## Example: Pro plan unlocks advanced reports

1. **フラグを作成します。** `feature_id: advanced_reports`とメタデータ`{ "tier": "pro", "monthly_report_limit": 100 }`。
2. **それを**プロプランのサブスクリプション製品にアタッチします。
3. **顧客がサブスクライブします。** Dodo Paymentsが`delivered`の付与を作成し、`entitlement_grant.created`を発火します。Webhookハンドラが顧客のために100の制限で`advanced_reports`を有効にします。
4. **アプリが機能を制御します。** ダッシュボードのロード時にキャッシュされた機能セットを確認（または`listEntitlementGrants`を呼び出して）、`advanced_reports`が存在する場合のみレポートタブを表示します。
5. **顧客がキャンセルします。** Dodo Paymentsが付与を取り消し、`entitlement_grant.revoked`を発火します。ハンドラが機能を無効にします。顧客が督促を介して後で回復すると、`entitlement_grant.delivered`がそれを復元します — コードの変更は不要です。

***

## Best practices

* **安定したsnake\_case機能IDを使用します。** アプリケーションコードはこれらの文字列をチェックします。名前を変更することは、両側での破壊的変更です。
* **1つの機能につき1つのフラグ。** SINGLE\_`advanced_reports` + `api_access`を2つの認可として選択し、単一の`pro_bundle`とします。取り消しおよびプランの組み合わせがスムーズになります。
* **状態をwebhooksで駆動し、APIで検証します。** Webhooksはデータベースを最新に保ちます。リストエンドポイントは、調整ジョブとキャッシュミスのための真実の源です。
* **`revoked`を即時とみなします。** 取り消されたフラグは、顧客がもはやその機能に対して支払っていないことを意味します。次のリクエストで、次のセッションではなく制御します。
* **メタデータに制限を設定し、コードには設定しません。** クオータを変更する場合、それは認可の編集だけを必要とし、新しい顧客は自動的にそれを取り入れ、既存の付与は購入したスナップショットを維持します。
