跳到正文

事件目录 ​

本文列出 GoodVision 事件类型、触发时机和字段说明。事件使用带版本的名称,通过已批准且已启用的 Webhook 订阅投递。

接收端的签名验证、Token 校验、去重和应答方式,请参见接收 Webhook。实际字段、枚举和权限以当前应用 API 产品提供的事件 Schema 为准。

订阅事件结构 ​

下面是订阅激活的完整业务事件,包含全部必需字段。HTTP 明文投递还会增加顶层 verification_token,校验并移除后才得到这里的信封;加密投递先验签、解密和核验 Token。

json
{
  "event_id": "evt_demo_activated",
  "event_type": "oem.subscription.activated.v1",
  "schema_version": "1",
  "occurred_at": "2026-10-06T00:00:00Z",
  "producer": "opaque",
  "tenant_id": "org_customer_demo",
  "resource_id": "sub_demo_cancel",
  "resource_version": 2,
  "correlation_id": "req_demo_activation",
  "data": {
    "id": "sub_demo_cancel",
    "organization_id": "org_customer_demo",
    "open_platform_application_id": "app_demo_saas",
    "environment": "sandbox",
    "product_tenant_id": "tenant_demo_cancel",
    "party_id": "party_customer_demo",
    "order_id": "order_demo_initial",
    "product_code": "relaydesk",
    "plan_code": "basic_monthly_demo",
    "plan_version": 1,
    "status": "active",
    "current_period_start": "2026-10-06T00:00:00Z",
    "current_period_end": "2026-11-06T00:00:00Z",
    "status_effective_at": "2026-10-06T00:00:00Z",
    "payment_reference": "payment_demo_initial",
    "operation_id": "op_demo_activation",
    "reason_code": "example_activation",
    "resource_version": 2,
    "created_at": "2026-10-05T23:55:00Z",
    "updated_at": "2026-10-06T00:00:00Z"
  }
}

所有 ID、套餐和原因码都是合成值,producer: "opaque" 是不透明来源的展示占位,实际来源枚举以已签发 Schema 为准。不要按占位来源或示例原因码硬编码。可下载 JSON,或查看含 Header、Token 和可复算签名的完整 HTTP 请求。

以下顶层字段在订阅事件中全部必需:

字段类型含义与校验
event_idstring稳定业务事件 ID,用于持久化和去重
event_typestring下表列出的完整、带版本事件名;与 Header 一致
schema_versionstring当前为 "1",不是整数 1
occurred_atRFC3339 string事件发生时间;不是用于验签的投递时间戳
producerstring不透明来源,按已签发 Schema 校验
tenant_idstring购买方客户 Organization,等于 data.organization_id;不是应用所属企业
resource_idstringSaaS 订阅 ID,等于 data.id
resource_versioninteger ≥ 1订阅版本,与 data.resource_version 一致
correlation_idstring关联排障,不用作去重键
dataobject当前订阅摘要,见下面的字段定义

按当前事件 Schema 验证字段。开放对象可忽略受支持主版本内新增的字段;设置 additionalProperties: false 的封闭对象需拒绝或隔离未知字段。不支持的主版本也需拒绝或隔离,避免按旧格式解析。

订阅 data 的必需字段 ​

所有 19 种订阅事件共用此摘要;不能只发送或只按 {id, status} 处理。字段组合需与事件及当前状态一致。

字段类型含义
idstring订阅 ID,与顶层 resource_id 一致
organization_idstring购买方客户 Organization,与顶层 tenant_id 一致
party_idstring商业客户档案标识,不是用户或 Membership ID
product_codestring已批准的产品编码
plan_codestring当前套餐编码;预约套餐变更时仍指当前套餐
plan_versioninteger ≥ 1不可变套餐定义版本,不是订阅版本
statusstring当前商业状态,必须符合事件表中的允许值
current_period_startRFC3339 string当前周期开始时间
current_period_endRFC3339 string当前周期结束时间,必须晚于开始
status_effective_atRFC3339 string当前 status 开始生效的时间
operation_idstring关联商业异步操作的标识,不是支付凭证
reason_codestring变更原因,按当前事件 Schema 解释
resource_versioninteger ≥ 1同一订阅单调递增的版本
created_atRFC3339 string订阅创建时间
updated_atRFC3339 string摘要最近更新时间

接入范围与状态相关字段 ​

这些字段在通用摘要中为可选,以实际事件和 Schema 为准。字段缺失时保持缺失,不转换为 null。

第三方投递需明确绑定应用和环境。缺少绑定时拒绝处理,不能使用客户企业或应用 slug 替代。

字段类型用途
open_platform_application_id / environmentstring / sandbox 或 production成对核对当前第三方 Application 与环境;不接受其他应用或环境的数据
application_slug / brand_profile_codestring应用与品牌展示标识,不代替 Application ID 作授权判断
product_tenant_idstring客户在产品中的租户标识,不代替 Organization
order_idstring原商业订单引用;付款结果独立查询
billing_modefree / paid商业计费方式;免费激活不制造付款证据
upgrade_from_subscription_idstring付费升级前的免费订阅 ID;两份订阅分别按自身版本更新
price_version_refstring不可变价格引用,不允许消费者覆盖金额
trial_ending_at / trial_endRFC3339 string试用结束提醒与试用结束时间
renewal_window_start / grace_deadlineRFC3339 string续费窗口开始与宽限截止时间
pause_end / resume_statusRFC3339 string / 状态 string暂停结束与恢复状态,按事件实际值处理
cancel_at / cancel_at_period_endRFC3339 string / boolean取消生效时间与是否周期末取消
pending_plan_code / pending_plan_version / pending_plan_effective_atstring / integer ≥ 1 / RFC3339 string预约套餐及其生效时间,不代表当前权益已改变
ended_atRFC3339 string订阅结束时间;与取消、到期或终止状态一致

订阅摘要不提供金额、币种、old_plan、new_plan、Role 或 Entitlement。需要付款信息或成员权限时,使用各自已授权的查询接口。

完整订阅事件表 ​

事件名与 data.status 不总是一一对应,例如支付失败可进入不同状态,支付方式更新不会改变状态。下面列出当前 v1 的全部 20 种订阅事件。相关字段描述场景,不代替正式 Schema 的 required 定义。

完整事件名触发时机允许的 data.status重点处理
oem.subscription.created.v1商业订阅创建trialing / pending_payment / active根据实际状态展示,不假设创建即付费成功
oem.subscription.updated.v1订阅记录修订,例如受理取消或恢复请求active / trialing / trial_ending / renewal_pending / plan_change_pending / pause_pending / paused / cancellation_pending / past_due / grace_period / suspended保存连续版本和真实当前状态;等待后续确认事件,不表示取消或恢复已完成
oem.subscription.trial_started.v1试用开始trialing读取周期和 trial_end,不自行延长试用
oem.subscription.trial_ending.v1进入试用结束提醒阶段trial_ending读取 trial_ending_at、trial_end,提示转付费
oem.subscription.activated.v1商业订阅激活active更新订阅记录,单独核对成员权限;完整请求
oem.subscription.renewal_upcoming.v1进入续费窗口renewal_pending读取 renewal_window_start,提醒不表示续费成功
oem.subscription.renewed.v1续费完成active应用新周期边界,不能自行按月/年加时间
oem.subscription.payment_failed.v1订阅支付失败payment_failed / past_due / grace_period按实际状态及宽限截止处理,等待恢复或到期
oem.subscription.past_due.v1订阅进入逾期/宽限处理past_due / grace_period读取 grace_deadline,不推断固定宽限时长
oem.subscription.payment_method_updated.v1支付方式更新保持当前订阅状态更新关联提示,不当作支付或续费成功
oem.subscription.pause_scheduled.v1暂停已预约pause_pending区分预约与生效,不自行推断暂停时间
oem.subscription.paused.v1暂停已生效paused按 pause_end / resume_status 和访问回查处理
oem.subscription.resumed.v1恢复操作生效active / trialing / trial_ending / renewal_pending / plan_change_pending / cancellation_pending / paused读取实际恢复状态,不能固定写成 active
oem.subscription.cancellation_scheduled.v1取消已预约cancellation_pending读取 cancel_at / cancel_at_period_end;完整场景
oem.subscription.cancelled.v1取消已生效cancelled记录 ended_at、收紧访问并回查,不推断退款
oem.subscription.plan_change_scheduled.v1套餐变更已预约plan_change_pending读取 pending_plan_*,不提前启用新权益
oem.subscription.plan_changed.v1套餐变更已生效active / trialing / trial_ending当前 plan_code / plan_version 更新;完整场景
oem.subscription.suspended.v1商业订阅被限制suspended收紧访问,按获批恢复流程处理
oem.subscription.expired.v1周期或宽限结束、订阅到期expired读取 ended_at,引导重新订阅;完整场景
oem.subscription.terminated.v1商业订阅被终止terminated立即停止访问,保留历史和审计

事件分类 ​

分类代表性事件
身份与访问identity.registration.completed.v1、oem.product.activated.v1、oem.access_context.changed.v1
订阅全部完整名称与状态映射见订阅事件表,包含记录修订、支付方式更新、暂停、取消、套餐变更、到期等 20 种事件
套餐变更oem.subscription.plan_changed.v1
支付结果payment.order.created.v1、payment.intent.created.v1、payment.requires_action.v1、payment.pending.v1、payment.succeeded.v1、payment.failed.v1、payment.cancelled.v1、payment.unknown.v1
退款结果payment.refund.pending.v1、payment.refund.unknown.v1、payment.refund.succeeded.v1、payment.refund.failed.v1
账务状态billing.statement.published.v1
Supportoem.support.request_received.v1、reply_created、status_changed

只有当前 API 调用授权明确列出的事件会被投递。不要假设相似名称或未发布事件可用。

接收端要求 ​

  1. 使用 event_id 去重。
  2. 使用单调递增的 resource_version 更新状态。
  3. 保存 correlation_id,用于跨系统诊断。
  4. 发现版本缺口后通过授权的状态 API 对账。
  5. 日志中不记录 Secret、Token 或不必要的业务敏感数据。

有效权限变更 ​

oem.access_context.changed.v1 表示某个主体在指定 Organization 和 Product 下的有效访问上下文已经失效。它不是 Role、Entitlement 或 Capability 快照。

json
{
  "event_id": "evt_opaque",
  "event_type": "oem.access_context.changed.v1",
  "schema_version": "1",
  "producer": "opaque",
  "occurred_at": "2026-09-17T03:00:00Z",
  "tenant_id": "org_opaque",
  "resource_id": "membership_opaque",
  "resource_version": 42,
  "correlation_id": "req_opaque",
  "data": {
    "subject_type": "membership",
    "subject_id": "membership_opaque",
    "organization_id": "org_opaque",
    "open_platform_application_id": "app_opaque",
    "environment": "sandbox",
    "product_code": "relaydesk",
    "access_revision": 42
  }
}

接收权限变更事件后:

  1. 按当前事件 Schema 校验 producer,示例占位值不可用于实际判断。
  2. 核对 tenant_id/organization_id 对应购买方客户企业。将 open_platform_application_id 和 environment 与接收端服务端配置精确匹配,不能用企业或应用 slug 替代。
  3. 确认 resource_version 等于 data.access_revision,完成验签并按 event_id 去重。
  4. 使用当前应用的服务身份及 openplatform.api.invoke 调用 POST /open-platform/v1/applications/{id}/events/{event_id}/access-snapshot,正文为 {}。平台从原事件选定唯一客户和 Membership,返回当前 roles、entitlements、capabilities 和 access_revision;当前登录用户上下文不能代替目标成员。请求与失败处理见产品权限快照回查。
  5. 使用接口定义的 Entitlement 判断付费等级,而不是检查名为 VIP 的 Role。版本不确定或查询失败时继续限制访问。

成员快照需包含布尔字段 product_access_allowed:

返回情况处理方式
true,且身份、Membership、ProductAccess 均有效应用当前角色、权益和能力
false清除本地有效权限,限制该成员使用产品
字段缺失或不是布尔值按响应格式错误处理,继续限制访问

企业购买、角色名称和 active Membership 不能单独证明成员已分配。采用此版本前,升级接收程序并清理旧权限记录,避免旧程序忽略该字段后继续放行。

产品访问已开通 ​

oem.product.activated.v1 只表示指定 Organization 的 ProductAccess 已进入 trial 或 active,不能单独给某个成员开放功能。

json
{
  "event_id": "evt_product_access_opaque",
  "event_type": "oem.product.activated.v1",
  "schema_version": "1",
  "producer": "opaque",
  "occurred_at": "2026-09-17T03:00:00Z",
  "tenant_id": "org_opaque",
  "resource_id": "product_access_opaque",
  "resource_version": 3,
  "correlation_id": "req_opaque",
  "data": {
    "organization_id": "org_opaque",
    "product_access_id": "product_access_opaque",
    "product_code": "relaydesk",
    "product_tenant_id": "tenant_opaque",
    "open_platform_application_id": "app_opaque",
    "environment": "sandbox",
    "status": "active",
    "version": 3
  }
}

核对 Application、环境、Organization、ProductAccess ID 和版本,按 event_id 去重,使用版本防止旧事件覆盖本地脱敏状态。成员权限需另行通过 oem.access_context.changed.v1 和已授权查询确认。

支付与退款事件当前使用 USD。payment.succeeded.v1 表示付款成功,payment.refund.succeeded.v1 表示退款成功。

pending、requires_action、unknown 和失败状态需等待后续 Webhook 或服务端查询确认。确认前不能激活订阅或使用权限。

权限快照接口尚未向标准应用开放。接入前请查看产品权限快照回查,并通过支持渠道确认客户范围的读取权限。

用户与事件的关联键 ​

订阅归属于客户空间;自动续费没有“当前登录用户”前置。成员 subject 与公开用户上下文的 membership_id 关联,公开别名不合并空间或订阅;完整规则见多应用、用户与事件接入。

开发者文档。第三方接入不需要内部运营平台权限。