权限授予
在创建、交付、失败或撤销权限授予时发送到您的 webhook 端点的负载。
权限授予 Webhook 事件
每当客户的权限授予状态发生变化时,这些事件将触发,例如生成许可证密钥、分配 Discord 角色、提供下载链接或撤销访问。订阅这些事件以保持您的应用程序与每个客户的可访问性同步。EntitlementGrantResponse 负载,如下模式所述。
事件触发器
entitlement_grant.created
已插入 grant 行。从此时起,该 grant 始终具有稳定的id,即使其状态发生变化也是如此。使用此事件记录履行流程已开始。
对于自动履行的 license key和feature flag,系统会直接插入该行,并填充 status: "Delivered" 和 delivered_at,因此单个 created 事件之后不会再有状态变化,除非该 grant 后续被撤销。
对于手动履行的 License Key(包含 fulfillment_mode: manual 的 entitlement),该行到达时会包含 status: "Pending",但不包含 license_key 对象——此时还没有 License Key。此事件表示有一个 License Key 正在等待履行;请通过 POST /grants/{grant_id}/license-key 提供 License Key,随后系统会触发 entitlement_grant.delivered。请参阅手动履行。
对于其他所有集成,该行到达时会包含 status: "Pending"。交付完成后会触发 delivered 或 failed 事件:
- 基于 OAuth 的集成(Discord、GitHub、Notion)使用
oauth_url,客户必须访问该链接才能完成授权同意。Dodo Payments 会在创建 grant 时尝试创建该链接,因此entitlement_grant.created可能包含该链接;如果其值为null,则会在客户从 Customer Portal 启动接受流程时填充。客户完成授权之前,grant 会保持为Pending。 - 平台直连集成(Telegram、Framer、Digital Files)仅在平台调用运行期间短暂处于
Pending,随后转为Delivered。
entitlement_grant.delivered
grant 已转换为Delivered,通常是从 Pending 转换而来。客户现在可以访问 entitlement 所描述的内容。使用此事件在您自己的系统中解锁依赖功能,例如配置工作区、发送自定义欢迎邮件或将 “fulfilled” 标记为已完成。
payload 的 delivered_at 字段记录了交付完成的时间。每当现有 grant 的状态变为 Delivered 时,delivered 都会触发:包括从 Pending 转换而来、失败的 OAuth grant 后续成功,或已撤销的 grant 被恢复。创建时就处于 Delivered 的 grant(例如自动履行的 license key)只会触发 created。
entitlement_grant.failed
交付尝试失败且出现不可重试的错误。error_code 和 error_message 字段解释了失败原因。常见原因包括撤销 OAuth 令牌、被拒绝的平台权限或缺少的目标(例如,已删除的 Discord 公会)。
entitlement_grant.revoked
访问在平台层面被撤销:Discord 角色被移除,GitHub 协作者被移除,许可证密钥被禁用,不再提供文件下载网址。revocation_reason 字段记录触发。
负载变体
data 字段始终是一个 EntitlementGrantResponse 对象。payload 包含一个 integration_type 字段(例如 license_key、digital_files、discord),因此您可以直接识别 grant 类型。三种集成类型还会附加额外的嵌套对象:
- 当
integration_type为license_key且已签发 License Key 时,会包含license_key。其中包含生成的 License Key、到期时间和激活使用情况。对于仍处于Pending的手动履行 grant,在您履行该 grant 之前,此对象为null。 - 当
integration_type为digital_files时,会包含digital_product_delivery。其中包含预签名下载 URL、可选的instructions以及可选的external_url。 - 当
integration_type为feature_flag时,会包含feature。其中包含 grant 所授予能力的feature_type和feature_id。
null;相关配置记录在 entitlement 本身中,而不是 grant 中。
示例负载
License Key 已交付(entitlement_grant.delivered)
License Key 等待手动履行(entitlement_grant.created)
当客户购买的产品包含使用 fulfillment_mode: manual 的 License Key entitlement 时触发。此时 grant 为 Pending,尚无 license_key 对象——商户必须提供 License Key。
数字文件已交付(entitlement_grant.delivered)
Discord 角色已创建并处于等待状态(entitlement_grant.created)
订阅取消后 Grant 已撤销(entitlement_grant.revoked)
交付失败(entitlement_grant.failed)
集成提示
- 当 grant 达到
Delivered时,解锁依赖功能。payment.succeeded事件表示款项已完成清算;它并不表示客户已经拥有 GitHub 仓库或 Discord 角色。请处理entitlement_grant.delivered,也要处理带有status: "Delivered"的entitlement_grant.created,因为在创建时交付的 grant 不会触发delivered事件。 - 将
revocation_reason映射到留存流程。subscription_on_holdrevoke 通常表示客户的卡片支付失败,下一次续订时将再次授予访问权限。manual或subscription_cancelledrevoke 则是有意执行的。请在客户消息中区别对待它们。 - 使用
webhook-idheader 检测重复事件,而不是使用 grant 的id。 grant 只会发出一次created,但delivered和revoked都可能触发多次,因为被 revoke 的 grant 可以恢复,也可以再次被 revoke。failed也不一定是最终状态:失败的 OAuth grant 仍可能被交付。Webhook 系统的重新交付也可能重复发送事件。请根据webhook-id跳过重复事件,并以 grant 的id作为自有 grant 记录的键。 - 读取
integration_type以识别 grant 类型。 Payload 会直接携带integration_type(例如license_key、digital_files、discord)。相应 grant 交付后,license_key和digital_product_delivery嵌套对象会被填充;手动履行的 license-key grant 会保持为Pending,并带有integration_type: "license_key"和nulllicense_key,直到你履行该 grant。 - 对于基于 OAuth 的 grant,请向客户展示
oauth_url。 Discord、GitHub 或 Notion 订阅者流程中的entitlement_grant.created事件可能包含oauth_url和oauth_expires_at。如果其值为null,请等待后续事件,或引导客户前往 Customer Portal。将该 URL 通过电子邮件发送给客户,或在你的应用中显示该 URL,以解除交付阻塞。
Detailed view of a single entitlement grant: who it's for, its lifecycle state, and any integration-specific delivery payload.
Brand id this grant belongs to.
Identifier of the business that owns the grant.
Timestamp when the grant was created.
Identifier of the customer the grant was issued to.
Identifier of the entitlement this grant was issued from.
Unique identifier of the grant.
The integration type of the grant's entitlement (e.g. license_key).
discord, telegram, github, figma, framer, notion, digital_files, license_key, feature_flag Arbitrary key-value metadata recorded on the grant.
Lifecycle status of the grant.
Pending, Delivered, Failed, Revoked Timestamp when the grant was last modified.
Timestamp when the grant transitioned to delivered, when applicable.
Digital-product-delivery payload, present when the entitlement
integration is digital_files.
Machine-readable code reported when delivery failed, when applicable.
Human-readable message reported when delivery failed, when applicable.
Typed feature payload, present only when the entitlement integration is
feature_flag; null for every other integration type.
License-key delivery payload, present when the entitlement integration
is license_key.
Timestamp when oauth_url stops being valid, when applicable.
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.
Identifier of the payment that triggered this grant, when applicable.
Reason recorded when the grant was revoked, when applicable.
Timestamp when the grant transitioned to revoked, when applicable.
Identifier of the subscription that triggered this grant, when applicable.