Skip to main content

权限授予 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.failed 视为可操作的。顾客付款但未获得访问。向支持团队报告失败或在解决根本问题后触发重授权。

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。
对于其他所有集成类型(Discord、GitHub、Telegram、Figma、Framer、Notion),这些嵌套字段均为 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_hold revoke 通常表示客户的卡片支付失败,下一次续订时将再次授予访问权限。manual 或 subscription_cancelled revoke 则是有意执行的。请在客户消息中区别对待它们。
  • 使用 webhook-id header 检测重复事件,而不是使用 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" 和 null license_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
string
必填

Brand id this grant belongs to.

business_id
string
必填

Identifier of the business that owns the grant.

created_at
string<date-time>
必填

Timestamp when the grant was created.

customer_id
string
必填

Identifier of the customer the grant was issued to.

entitlement_id
string
必填

Identifier of the entitlement this grant was issued from.

id
string
必填

Unique identifier of the grant.

integration_type
enum<string>
必填

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

可用选项:
discord,
telegram,
github,
figma,
framer,
notion,
digital_files,
license_key,
feature_flag
metadata
Metadata · object
必填

Arbitrary key-value metadata recorded on the grant.

status
enum<string>
必填

Lifecycle status of the grant.

可用选项:
Pending,
Delivered,
Failed,
Revoked
updated_at
string<date-time>
必填

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.

最后修改于 2026年9月26日