Saltar al contenido principal
Un derecho de bandera de función convierte a Dodo Payments en un almacén de banderas de función consciente de la facturación. Adjunta una bandera como advanced_reports a un producto, y cada cliente de pago recibe una concesión que tu aplicación puede verificar vía API o mantener sincronizada con webhooks. Sin plataforma externa, sin OAuth, sin paso de entrega: la concesión en sí es la capacidad.

Qué se entrega

Nada sale de Dodo Payments — la concesión es el entregable:
  • En la compra, se crea la concesión y pasa directamente a delivered. No hay fase de pending, no hay acción del cliente, y no hay forma de que la entrega falle.
  • La concesión lleva una carga útil tipificada feature: { "feature_type": "boolean", "feature_id": "advanced_reports" }. Tu aplicación lee feature_id para decidir qué desbloquear.
  • La cancelación, reembolso o revocación manual mueven la concesión a revoked, y tu aplicación ve desaparecer la bandera.
Usos comunes incluyen la restricción de funciones basadas en planes (Pro desbloquea analíticas), capacidades adicionales (una mejora de “acceso API”), y programas de acceso temprano vendidos como compras únicas.
feature_id es un identificador elegido por el comerciante, no único en todos los derechos. Dos derechos pueden conferir el mismo feature_id — por ejemplo, un plan Pro mensual y uno anual ambos otorgando advanced_reports.

Crear una bandera de función

1

Open Entitlements

En tu panel de Dodo Payments, ve a Derechos y haz clic en + para iniciar un nuevo derecho, luego elige Banderas de Función.
2

Name the flag

Dale a la bandera un Nombre de Presentación para tu panel, un ID de Función que verificará tu aplicación (el panel sugiere uno a partir del nombre), y una Descripción para que tu equipo sepa qué controla.
Formulario de Nueva Bandera de Función con nombre de presentación, ID de función, descripción y entradas de metadatos clave-valor
3

Optionally add metadata

Activa Metadatos para adjuntar configuración clave-valor — límites, nombres de niveles, cuotas — que se entrega a tu aplicación junto con la bandera. Consulta Adjuntar límites con metadatos.
4

Confirm

Haz clic en Confirmar. La bandera aparece en tu lista de derechos, lista para adjuntar a productos.
Panel de derechos mostrando la bandera de función de Informes Avanzados con su panel de actividad de concesión

Adjuntar a un producto

Abre un producto (o crea uno), encuentra la tarjeta Derechos, y haz clic en + para adjuntar derechos existentes. Selecciona tu bandera de función y haz clic en Hecho.
Panel de adjuntos de derechos con la bandera de función de Informes Avanzados seleccionada
La bandera adjunta se muestra en el formulario del producto, y la vista previa del pago la lista bajo Incluye.
Formulario de producto con la bandera de función de Informes Avanzados adjunta en la tarjeta de Derechos

Configuración requerida

CampoRequeridoDescripción
feature_idIdentificador que verifica tu aplicación, por ejemplo, advanced_reports. No único entre derechos.
feature_typeTipo de capacidad conferida. Solo boolean es soportado hoy.

Crear vía 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"),
    },
  ),
})

Adjuntar límites con metadatos

Una bandera booleana responde “¿tiene este cliente la función?”. Los metadatos responden “¿con qué configuración?”. Los metadatos de derechos aceptan valores de cadena, entero, número y booleano, y cada concesión toma una instantánea congelada de los metadatos del derecho en el momento en que se crea. Ese comportamiento de instantánea es lo que hace que los metadatos sean seguros para usar en los límites del plan:
  • Editar los metadatos del derecho más tarde solo afecta a las futuras concesiones. Los clientes mantienen los límites bajo los que compraron.
  • La instantánea se devuelve en cada concesión como su campo metadata, por lo que una llamada API te da tanto la bandera como su configuración.
Por ejemplo, una bandera advanced_reports con { "tier": "pro", "monthly_report_limit": 100 } permite a tu aplicación desbloquear el panel y hacer cumplir la cuota de 100 informes sin una segunda consulta. Si más tarde aumentas el límite a 250, los clientes existentes se mantendrán en 100 hasta que reciban una nueva concesión (por ejemplo, después de un cambio de plan).
Usa metadatos para límites y configuración; usa feature_id solo para identidad. Codificar límites en el id (advanced_reports_100) fuerza una nueva bandera para cada cambio de límite y rompe las comprobaciones de tu aplicación.

Comprobar las características de un cliente

Lista las concesiones de bandera de función entregadas a un cliente y construye el conjunto de características habilitadas. El endpoint devuelve una fila por concesión en todos los derechos, filtrable por integration_type y 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
  }
}
La carga útil feature se povis posts tarjetas feature_flag concesiones; es null para cada otro tipo de integración. Consulta la referencia de la API Listar Concesiones de Cliente para la forma completa de respuesta.
Consultar la API en cada solicitud agrega latencia a tu ruta crítica. Cachea el conjunto de características por cliente con un TTL corto (minutos, no horas), e invalida la caché desde tu manejador de webhooks cuando una concesión cambia de estado: esa combinación mantiene rápidas las comprobaciones y revocaciones casi instantáneas.

Ciclo de vida

Las concesiones de bandera de función siguen el estándar ciclo de vida de concesión con una simplificación: no hay paso de entrega, por lo que las concesiones nunca se sitúan en pending y nunca pasan a failed.
DisparadorEfecto
El pago único tiene éxito / suscripción se activaConcesión creada con status: delivered e delivered_at establecido.
Suscripción suspendida, cancelada o caducadaConcesión revocada con la revocation_reason coincidente.
Reembolso en un pago únicoConcesión revocada con revocation_reason: refund.
Suscripción se recupera (por ejemplo, cobro exitoso)La concesión revocada se restaura a delivered — mismo id de concesión, campos de revocación despejados.
Revocación manual de APIConcesión revocada con revocation_reason: manual. No se restaura automáticamente en la renovación.
Las concesiones son idempotentes por derecho y cliente: mientras un cliente tenga una concesión no revocada para una bandera, las compras y renoves repetidas no crean duplicados.

Webhooks

Suscríbete a los eventos entitlement_grant.* para reflejar las banderas en tu propia base de datos en lugar de sondear:
  • entitlement_grant.created — llega ya delivered con la carga útil feature. Activa la función.
  • entitlement_grant.delivered — se activa cuando una concesión previamente revocada se restaura. Re-activa la función.
  • entitlement_grant.revoked — acceso retirado. Desactiva la función y verifica revocation_reason para decidir tu mensajería.
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);
});
No hay entitlement_grant.failed para banderas de función — la entrega ocurre completamente dentro de Dodo Payments y no puede fallar.

Ejemplo: El plan Pro desbloquea informes avanzados

  1. Crea la bandera. feature_id: advanced_reports con metadatos { "tier": "pro", "monthly_report_limit": 100 }.
  2. Adjúntala a tu producto de suscripción del Plan Pro.
  3. Un cliente se suscribe. Dodo Payments crea una concesión delivered y dispara entitlement_grant.created; tu manejador de webhooks habilita advanced_reports para el cliente con un límite de 100.
  4. Tu aplicación restringe la función. Al cargar el panel, verifica el conjunto de características en caché (o llama listEntitlementGrants) y renderiza la pestaña de informes solo cuando advanced_reports está presente.
  5. El cliente cancela. Dodo Payments revoca la concesión y dispara entitlement_grant.revoked; tu manejador desactiva la función. Si el cliente luego se recupera a través de cobro, entitlement_grant.delivered la restaura — no se necesitan cambios de código.

Mejores prácticas

  • Usa ids de función estables y en snake_case. Tu código de aplicación verifica estas cadenas; renombrar una es un cambio de ruptura en ambos lados.
  • Una bandera por capacidad. Prefiere advanced_reports + api_access como dos derechos sobre un solo pro_bundle — la revocación y las mezclas de plan se mantienen limpias.
  • Impulsa el estado desde webhooks, verifica con la API. Los webhooks mantienen tu base de datos actualizada; el punto de lista es la fuente de verdad para trabajos de reconciliación y pérdidas de caché.
  • Trata revoked como inmediato. Una bandera revocada significa que el cliente ya no está pagando por la función. Verifica en la siguiente solicitud, no en la siguiente sesión.
  • Pon límites en metadatos, no en el código. Cambiar una cuota luego solo requiere editar el derecho — los nuevos clientes la adoptan automáticamente mientras que las concesiones existentes mantienen su instantánea comprada.
Última modificación el 9 de julio de 2026