구매를 통해 애플리케이션 내 기능을 제어합니다. 기능 플래그 권한은 결제 시 즉시 기능을 제공하며, 취소 시 자동으로 해지합니다.
기능 플래그 권한은 Dodo Payments를 결제 인식 기능 플래그 저장소로 전환합니다. 기능 플래그 advanced_reports를 제품에 연결하면, 모든 결제 고객이 API를 통해 확인하거나 웹훅과 동기화하여 애플리케이션이 확인할 수 있는 권한을 부여받습니다. 외부 플랫폼, OAuth, 전달 단계가 필요 없습니다 — 권한 자체가 기능입니다.
부울 플래그는 “이 고객이 기능을 가지고 있는가?”를 답합니다. 메타데이터는 “어떤 구성으로?”를 답합니다. 권한 메타데이터는 문자열, 정수, 숫자 및 부울 값을 수용하며, 각 권한은 생성 순간에 권한의 메타데이터를 동결 스냅샷으로 받아들입니다.이 스냅샷 동작은 메타데이터가 플랜 제한에 안전하게 사용될 수 있게 합니다:
나중에 권한 메타데이터를 수정해도 미래 권한에만 영향을 미칩니다. 고객은 구매한 한도치를 유지합니다.
스냅샷은 권한의 metadata 필드로 반환됩니다. 따라서 하나의 API 호출은 플래그 및 그 구성을 모두 제공합니다.
예를 들어, advanced_reports 플래그가 { "tier": "pro", "monthly_report_limit": 100 }와 함께 있으면 애플리케이션은 대시보드를 잠금 해제하고 100 보고 한도를 적용할 수 있습니다. 이후에 한도를 250으로 상향 조정하면 기존 고객은 새로운 권한을 받을 때까지 100에 머물러 있습니다(예: 플랜 변경 후).
메타데이터는 제한 및 구성용으로 사용하고 feature_id는 정체성용으로만 사용하세요. ID에 제한을 인코딩하면(advanced_reports_100) 변경 시마다 새로운 플래그가 필요하며 애플리케이션의 확인을 깨뜨립니다.
고객의 제공된 기능 플래그 권한을 나열하고 활성화된 기능 세트를 만듭니다. 엔드포인트는 모든 권한에 걸쳐 권한당 한 행을 반환하며 integration_type 및 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 }}
feature 페이로드는 feature_flag 권한에만 할당됩니다. 이는 다른 모든 통합 유형에 대해 null입니다. 전체 응답 형태는 List Customer Grants API 참조를 확인하세요.
모든 요청에서 API를 확인하면 핫 패스에 지연이 추가됩니다. 고객별 기능 세트를 짧은 TTL(분 단위, 시간 단위가 아님)로 캐시하고, 권한 상태가 변경될 때 웹훅 핸들러에서 캐시를 무효화하십시오. 이 조합은 검사를 빠르게 하고 해지를 거의 즉시 처리합니다.
고객이 구독합니다. Dodo Payments가 delivered 권한을 생성하고 entitlement_grant.created를 실행합니다. 웹훅 핸들러는 100의 한도로 고객을 위해 advanced_reports을 활성화합니다.
앱이 기능을 제어합니다. 대시보드가 로드될 때 캐시된 기능 세트를 확인하고(listEntitlementGrants 호출) advanced_reports가 있을 때만 보고서 탭을 렌더링합니다.
고객이 취소합니다. Dodo Payments가 권한을 해지하고 entitlement_grant.revoked를 실행하여 핸들러가 기능을 비활성화합니다. 나중에 고객이 비용 추심을 통해 복구되면, entitlement_grant.delivered가 이를 복원합니다 — 코드 변경 필요 없음.
안정적인 snake_case 기능 ID를 사용하세요. 애플리케이션 코드가 이 문자열을 확인합니다; 이름 변경은 양쪽에 걸쳐 파괴적인 변경입니다.
기능당 하나의 플래그. 단일 pro_bundle보다는 advanced_reports + api_access을 두 개의 권한으로 사용하는 것이 좋습니다 — 해지 및 계획 혼합이 깨끗하게 유지됩니다.
상태를 웹훅에서 구동하고 API로 확인하세요. 웹훅은 데이터베이스를 최신 상태로 유지하고, 목록 엔드포인트는 조정 작업 및 캐시 누락에 대한 진실의 출처입니다.
revoked를 즉시 처리합니다. 해지된 플래그는 고객이 더 이상 기능에 비용을 지불하지 않음을 의미합니다. 다음 세션이 아닌 다음 요청에서 제한하십시오.
제한을 코드가 아닌 메타데이터에 넣습니다. 할당량을 변경하는 것은 권한을 편집하는 것만 필요합니다 — 새로운 고객은 자동으로 이를 수용하고 기존 권한은 구매한 스냅샷을 유지합니다.
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.