事件流
在 Adapty 中,您将在客户使用应用的整个过程中收到各种订阅事件。以下订阅流程概述了常见场景,帮助您了解 Adapty 在用户订阅、取消或重新激活订阅时生成的事件。
请注意,Apple 会在订阅实际开始/续期时间的数小时前处理付款。为保持图表清晰,以下流程图将订阅开始/续期与扣款显示为同时发生。 此外,与同一操作相关的事件会同时发生,在你的 Event Feed 中可能以任意顺序出现,与我们图表中展示的顺序可能不同。
订阅生命周期
首次购买流程
当用户首次购买订阅(无试用期)时,会触发以下事件:
- Subscription started
- Access level updated(授予用户访问权限)
当订阅到期续费时,系统会自动续订,并触发以下事件:
- Subscription renewal(开始新一期订阅)
- Access level updated(更新订阅到期日期,将访问权限延长一个周期) 支付失败或用户取消续订的情况分别在账单问题处理流程和订阅取消流程中描述。
订阅取消流程
当用户取消订阅时,系统会创建以下事件:
- Subscription renewal canceled:表示订阅在当前周期结束前仍保持有效,此后用户将失去访问权限
- Access level updated:用于为该访问等级禁用自动续订
订阅结束后,系统会触发 Subscription expired (churned) 事件,标记订阅的终止。
如果退款获批,以下事件将替代 Subscription expired (churned):
- Subscription refunded:终止订阅并提供退款详情
对于 Stripe,订阅可以立即取消,跳过剩余周期。在这种情况下,所有事件会同时创建:
- Subscription renewal cancelled
- Subscription expired (churned)
- Access Level updated(移除用户的访问等级) 如果退款申请获批,还会同步触发 Subscription refunded 事件。
订阅恢复流程
如果用户取消订阅、订阅到期后再次购买同一订阅,系统将生成一个 Subscription renewed 事件。即使中间存在访问中断,Adapty 也会通过 vendor_original_transaction_id 将其视为同一交易链,因此再次购买被视为续订。
Access level updated 事件将被创建两次:
- 订阅结束时,撤销用户的访问等级
- 用户重新购买订阅时,重新授予访问等级
订阅暂停流程(仅限 Android)
此流程适用于用户在 Android 上暂停订阅并在之后恢复订阅的情况。
暂停订阅的效果是延迟生效的。如果用户在订阅即将续订之前将其暂停,订阅仍保持活跃状态,用户在当前计费周期的剩余时间内继续享有付费访问权限。
-
当用户暂停订阅时,会触发 Subscription paused (Android only) 事件。
-
订阅周期结束时,Adapty 会触发 Access level updated 事件,撤销用户的访问等级。
-
当用户恢复订阅时,将依次触发以下事件:
- Subscription renewed
- Access level updated(恢复用户的访问等级)
这些订阅属于同一交易链,通过相同的 vendor_original_transaction_id 关联。
试用流程
如果您在应用中使用试用期,您将收到额外的试用相关事件。
试用期成功转化流程
最常见的场景是:用户开启试用期,绑定信用卡,并在试用期结束后成功转化为标准订阅。在这种情况下,试用期开始时会生成以下事件:
- Trial started:标记试用期开始
- Access level updated:授予访问权限
当标准订阅正式开始时,会生成 Trial converted 事件。
试用期取消转化流程
如果用户在试用期转为订阅之前取消了试用,系统将在取消时创建以下事件:
- Trial renewal cancelled:禁止试用期自动转换为订阅
- Access level updated:禁止访问权限续期
用户在试用期结束前仍可正常使用,试用期到期时系统将创建 Trial expired 事件,标志着试用期的终结。
试用期过期后的订阅重新激活流程
如果试用期因账单问题或用户主动取消而过期,且用户后来购买了订阅,系统将创建以下事件:
- Access level updated,向用户授予访问权限
- Trial converted
即使试用期与订阅之间存在时间间隔,Adapty 也会通过 vendor_original_transaction_id 将两者关联起来。这次转化被视为一条连续交易链的一部分,该链从零价格的试用期开始。这就是为什么系统创建的是 Trial converted 事件,而非 Subscription started 事件。
产品变更
本节涵盖对有效订阅所做的各类调整,例如升级、降级或购买其他组的产品。
立即生效的产品变更流程
用户变更产品后,系统可能会在订阅到期前立即完成切换(主要发生在升级或替换产品的场景下)。在产品变更的那一刻:
- 访问等级发生变更,系统创建两个 Access level updated 事件:
- 移除第一个产品的访问权限。
- 授予第二个产品的访问权限。
- 旧订阅结束,并退款(系统创建 Subscription refunded 事件,其中
cancellation_reason=upgraded)。请注意,此时不会创建 Subscription expired (churned) 事件;Subscription refunded 事件将替代它。 - 新订阅开始(系统为新产品创建 Subscription started 事件)。
如果用户降级订阅,第一个订阅将持续到已付费周期结束,届时将被新的低级别订阅所替代。在这种情况下,系统会立即创建 Access level updated 事件以禁用访问等级的自动续订。所有其他事件将在订阅实际替换时创建:
- 另一个 Access level updated 事件被创建,以授予对第二个产品的访问权限。
- Subscription expired (churned) 事件被创建,以结束第一个产品的订阅。
- Subscription started 事件被创建,以为新产品开始新的订阅。
延迟产品变更流程
还有一种情况:用户在订阅续费时变更产品。这种情况与前一种非常相似:系统会立即创建一个 Access level updated 事件,用于禁用旧产品的自动续费权限。其余所有事件将在用户完成订阅变更且系统更新后创建:
- 另一个 Access level updated 事件被创建,以授予对第二个产品的访问权限。
- Subscription expired (churned) 事件被创建,以终止第一个产品的订阅。
- Subscription started 事件被创建,以开始新产品的新订阅。
账单问题结果流程
如果试用转化或订阅续费因账单问题失败,后续流程取决于是否启用了宽限期。
启用宽限期时,若付款成功,试用将完成转化或订阅将完成续费。若付款失败,应用商店将继续尝试向用户收取订阅费用,若仍然失败,应用商店将终止该试用或订阅。
因此,在发生账单问题时,Adapty 中会创建以下事件:
- 检测到账单问题
- 进入宽限期(如已启用宽限期)
- 访问等级已更新,授权延续至宽限期结束
如果后续付款成功,Adapty 会记录 试用已转化 或 订阅已续费 事件,用户不会失去访问权限。
如果付款最终失败,应用商店取消订阅,Adapty 将生成以下事件:
- 试用已到期 或 订阅已到期(已流失),附带
cancellation_reason: billing_error - 访问等级已更新,撤销用户的访问权限
如果没有宽限期,账单重试期(应用商店持续尝试向用户扣款的时段)将立即开始。 如果在宽限期结束前付款始终未能成功,流程相同:当应用商店自动终止订阅时,系统会创建相同的事件:
-
Trial expired 或 Subscription expired (churned) 事件,其
cancellation_reason为billing_error -
Access level updated 事件,用于撤销用户的访问等级
跨用户账户共享购买记录的流程
当一个 Customer User ID iOS、Android、React Native、Flutter 和 Unity 尝试恢复或续期已绑定到另一个 Customer User ID iOS、Android、React Native、Flutter 和 Unity 的订阅时,Adapty 的 Sharing paid access between user accounts 设置将决定访问权限的处理方式。具体流程会因所选选项而有所不同。
对于 Apple 家庭共享交易(in_app_ownership_type=FAMILY_SHARED),仅会触发 Access level updated 事件——下方的各产品订阅事件不会触发。完整事件矩阵请参阅 Apple 家庭共享。
将访问等级转移给新用户的流程
推荐的方式是将访问等级转移给新用户。这样可以保留原始用户的交易记录,确保分析数据的一致性。整个过程只会产生 2 个 Access level updated 事件:
- 撤销第一个用户的访问等级
- 授予第二个用户访问等级
以下是此场景中生成的事件里,与访问等级分配和转移相关字段的详细说明:
- 用户 A:访问等级已更新(当用户 A 在应用内购买订阅时发送)
{
"profile_id": "00000000-0000-0000-0000-000000000000",
"customer_user_id": UserA,
"event_properties": {
"profile_has_access_level": true,
},
"profiles_sharing_access_level": null
}
- 用户 A:访问等级已更新(当应用重装并用户 B 登录后,用户 A 的访问权限被撤销时发送)
{
"profile_id": "00000000-0000-0000-0000-000000000000",
"customer_user_id": UserA,
"event_properties": {
"profile_has_access_level": false,
},
"profiles_sharing_access_level": null
}
-
用户 B:访问等级已更新(当用户 B 登录并授予访问权限时发送)
{ "profile_id": "00000000-0000-0000-0000-000000000001", "customer_user_id": UserB, "event_properties": { "profile_has_access_level": true, }, "profiles_sharing_access_level": null }
用户间共享访问流程
此选项允许多个用户共享同一访问等级,前提是他们的设备使用同一个 Apple/Google ID 登录。当用户重新安装应用并以不同的邮箱登录时,依然可以访问之前的购买内容,此选项非常适合这种场景。启用后,多个已识别用户可以共享同一访问等级。在共享访问等级期间,所有交易记录均归属于原始 Customer User ID iOS、Android、React Native、Flutter 和 Unity ,以确保完整的交易历史记录和数据分析。 因此,只会创建 1 个事件:Access level updated,用于向第二位用户授予访问权限。
以下是该场景中生成的事件里,与访问等级分配和共享相关字段的说明:
用户 B:Access level updated(当用户 B 登录并获得访问权限时发送)
{
"profile_id": "00000000-0000-0000-0000-000000000000",
"customer_user_id": UserA,
"event_properties": {
"profile_has_access_level": true,
},
"profiles_sharing_access_level": [
{
"profile_id": "00000000-0000-0000-0000-000000000001,
"customer_user_id": UserB
}
]
}
访问权限不在用户间共享的流程
使用此选项时,只有第一个获得访问等级的用户画像才能永久保留它。如果购买需要绑定到单一的 Customer User ID iOS、Android、React Native、Flutter 和 Unity ,此选项非常适用。