Skip to main content

Eventos de Webhook para Concesión de Derechos

Estos eventos se activan cada vez que cambia el estado de la concesión de derechos de un cliente, por ejemplo, cuando se genera una clave de licencia, se asigna un rol de Discord, se proporciona un enlace de descarga, o se revoca el acceso. Suscríbase a estos eventos para mantener su aplicación sincronizada con lo que cada cliente puede acceder. Los cuatro eventos comparten la misma carga útil EntitlementGrantResponse documentada en el esquema a continuación.

Desencadenantes de Eventos

entitlement_grant.created

Se insertó una fila de grant. A partir de este momento, el grant siempre tiene un id estable, incluso si su estado cambia. Usa este evento para registrar que la cumplimentación está en curso. Para license keys cumplimentadas automáticamente y feature flags, la fila se inserta directamente con status: "Delivered" y delivered_at rellenados, por lo que a un único evento created no le siguen más cambios de estado, a menos que el grant se revoque posteriormente. Para las license keys fulfilladas manualmente (entitlements con fulfillment_mode: manual), la fila llega con status: "Pending" y sin el objeto license_key: todavía no hay ninguna key. Este evento indica que hay una key pendiente de fulfillment; proporciónala mediante POST /grants/{grant_id}/license-key, lo que activa entitlement_grant.delivered. Consulta Manual Fulfillment. Para cualquier otra integración, la fila llega con status: "Pending". Una vez completada la entrega, le sigue un evento delivered o failed:
  • Integraciones basadas en OAuth (Discord, GitHub, Notion) utilizan oauth_url que el cliente debe visitar para completar el consentimiento. Dodo Payments intenta crearlo cuando se crea el grant, por lo que entitlement_grant.created puede incluirlo; si es null, se completa cuando el cliente inicia el flujo de aceptación desde el Customer Portal. El grant permanece Pending hasta que el cliente autoriza.
  • Integraciones directas con la plataforma (Telegram, Framer, Digital Files) permanecen en Pending solo brevemente mientras se ejecuta la llamada de la plataforma; después pasan a Delivered.
La concesión pasó de pending a delivered. El cliente ahora tiene el acceso descrito por el derecho. Use este evento para desbloquear funciones dependientes en sus propios sistemas, por ejemplo, para proporcionar un espacio de trabajo, enviar un correo electrónico de bienvenida personalizado o marcar una bandera de “cumplido”. El grant pasó al estado Delivered, normalmente desde Pending. El cliente ahora tiene el acceso descrito por la entitlement. Usa este evento para desbloquear funcionalidades dependientes en tus propios sistemas, por ejemplo, para aprovisionar un workspace, enviar un correo electrónico de bienvenida personalizado o marcar un indicador de “fulfilled”. El campo delivered_at del payload registra cuándo se completó la entrega. delivered se activa cada vez que el estado de un grant existente cambia a Delivered: desde Pending, cuando un grant de OAuth fallido se completa posteriormente, o cuando se restaura un grant revocado. Un grant que llega a Delivered al crearse, como una license key cumplimentada automáticamente, solo activa created. Se intentó la entrega y falló con un error no recuperable. Los campos error_code e error_message explican la falla. Las causas comunes incluyen un token OAuth revocado, un permiso de plataforma denegado, o un destino faltante (por ejemplo, una guild de Discord eliminada).
Trate entitlement_grant.failed como accionable. El cliente pagó pero no obtuvo acceso. Haga visibles las fallas a su equipo de soporte o inicie una nueva concesión una vez que se resuelva el problema subyacente.

entitlement_grant.revoked

Se retiró el acceso a nivel de plataforma: se eliminó el rol de Discord, se eliminó el colaborador de GitHub, se desactivó la clave de licencia, las URL de descarga de archivos ya no se emiten. El campo revocation_reason registra el desencadenante.

Variantes de Carga Útil

El campo data siempre es un objeto EntitlementGrantResponse. Dos tipos de integraciones incluyen objetos anidados adicionales: El campo data siempre es un objeto EntitlementGrantResponse. El payload incluye un campo integration_type (por ejemplo, license_key, digital_files, discord) para que puedas reconocer directamente el tipo de grant. Tres tipos de integración también adjuntan objetos anidados adicionales:
  • license_key se incluye cuando integration_type es license_key y se ha emitido una key. Contiene la key generada, la fecha de expiración y el uso de activación. En un grant fulfillado manualmente que aún está en Pending, este objeto es null hasta que completes el fulfillment del grant.
  • digital_product_delivery se incluye cuando integration_type es digital_files. Contiene URLs de descarga presignadas, el instructions opcional y el external_url opcional.
  • feature se incluye cuando integration_type es feature_flag. Contiene el feature_type y el feature_id de la capacidad otorgada por el grant.
Para todos los demás tipos de integración (Discord, GitHub, Telegram, Figma, Framer, Notion), estos campos anidados son null; la configuración relevante se registra en el entitlement, no en el grant.

Ejemplos de Carga Útil

Clave de licencia entregada (entitlement_grant.delivered)

License Key Delivered (entitlement_grant.delivered)

License Key Pending Manual Fulfillment (entitlement_grant.created)

Se activa cuando un cliente compra un producto cuyo entitlement de License Key utiliza fulfillment_mode: manual. El grant está en Pending y todavía no tiene un objeto license_key; el merchant debe proporcionar la key.

Digital Files Delivered (entitlement_grant.delivered)

Discord Role Created and Pending (entitlement_grant.created)

Grant Revoked on Subscription Cancellation (entitlement_grant.revoked)

Delivery Failed (entitlement_grant.failed)


Consejos de Integración

  • Desbloquea las funciones dependientes cuando un grant alcanza Delivered. Un evento payment.succeeded te indica que el dinero se liquidó; no te indica que el cliente ya tenga el repositorio de GitHub o el rol de Discord. Gestiona entitlement_grant.delivered y también entitlement_grant.created con status: "Delivered", porque un grant que se entrega al crearse no genera ningún evento delivered.
  • Asocia revocation_reason con los flujos de retención. Un revoke subscription_on_hold normalmente significa que la tarjeta del cliente falló y que el próximo renewal volverá a otorgar el acceso. Un revoke manual o subscription_cancelled es intencional. Trátalos de forma diferente en los mensajes al cliente.
  • Detecta duplicados con el header webhook-id, no con el id del grant. Un grant emite created una sola vez, pero delivered y revoked pueden activarse más de una vez, porque un grant revocado puede restaurarse y revocarse nuevamente. failed tampoco es siempre definitivo: un grant de OAuth fallido aún puede entregarse. Las reentregas del sistema de webhook también pueden repetir un evento. Omite las repeticiones mediante webhook-id y usa el id del grant como clave para tus propios registros de grants.
  • Lee integration_type para identificar el tipo de grant. El payload incluye integration_type directamente (por ejemplo, license_key, digital_files, discord). Los objetos anidados license_key y digital_product_delivery se completan una vez entregados sus respectivos grants; un grant de license-key cumplido manualmente permanece Pending con integration_type: "license_key" y un null license_key hasta que lo cumplas.
  • Para los grants basados en OAuth, muestra oauth_url al cliente. El evento entitlement_grant.created para los flujos de suscriptores de Discord, GitHub o Notion puede incluir un oauth_url y oauth_expires_at. Si es null, espera un evento posterior o dirige al cliente al Customer Portal. Envía la URL por correo electrónico al cliente o muéstrala en tu aplicación para desbloquear la entrega.

Detailed view of a single entitlement grant: who it's for, its lifecycle state, and any integration-specific delivery payload.

brand_id
string
requerido

Brand id this grant belongs to.

business_id
string
requerido

Identifier of the business that owns the grant.

created_at
string<date-time>
requerido

Timestamp when the grant was created.

customer_id
string
requerido

Identifier of the customer the grant was issued to.

entitlement_id
string
requerido

Identifier of the entitlement this grant was issued from.

id
string
requerido

Unique identifier of the grant.

integration_type
enum<string>
requerido

The integration type of the grant's entitlement (e.g. license_key).

Opciones disponibles:
discord,
telegram,
github,
figma,
framer,
notion,
digital_files,
license_key,
feature_flag
metadata
Metadata · object
requerido

Arbitrary key-value metadata recorded on the grant.

status
enum<string>
requerido

Lifecycle status of the grant.

Opciones disponibles:
Pending,
Delivered,
Failed,
Revoked
updated_at
string<date-time>
requerido

Timestamp when the grant was last modified.

delivered_at
string<date-time> | null

Timestamp when the grant transitioned to delivered, when applicable.

digital_product_delivery
null | Digital Product Delivery · object

Digital-product-delivery payload, present when the entitlement integration is digital_files.

error_code
string | null

Machine-readable code reported when delivery failed, when applicable.

error_message
string | null

Human-readable message reported when delivery failed, when applicable.

feature
null | object

Typed feature payload, present only when the entitlement integration is feature_flag; null for every other integration type.

license_key
null | object

License-key delivery payload, present when the entitlement integration is license_key.

oauth_expires_at
string<date-time> | null

Timestamp when oauth_url stops being valid, when applicable.

oauth_url
string | null

Customer-facing OAuth URL for OAuth-style integrations. Populated during the customer-portal accept flow; null until the customer completes that step, and on grants for non-OAuth integrations.

payment_id
string | null

Identifier of the payment that triggered this grant, when applicable.

revocation_reason
string | null

Reason recorded when the grant was revoked, when applicable.

revoked_at
string<date-time> | null

Timestamp when the grant transitioned to revoked, when applicable.

subscription_id
string | null

Identifier of the subscription that triggered this grant, when applicable.

Última modificación el 26 de septiembre de 2026