Highlight
Apple 建议把订阅权限判断收敛到服务端 entitlement engine,用 receipt、server-to-server notifications 和业务上下文计算用户状态,再把简化的 entitlement payload 安全返回客户端。
核心内容
很多订阅系统最早只问一个问题:这个用户现在有没有权限。实现上通常看 product_id 和 expires_date。到期日在未来就解锁,到期日在过去就锁定。
这个模型很快会失效。用户可能取消自动续订,但本期服务还没结束;也可能扣款失败,Apple 仍在 Billing Retry 中继续尝试收费;如果 app 开启 Grace Period,用户在宽限期内仍应获得服务。只看 active 或 inactive,会错过挽留、付款修复和升级提示的时机。
这场 session 给出的答案是服务端 entitlement engine。它把 receipt、server-to-server notifications、订阅商品、业务上下文整理成一份简单结果:用户能不能访问服务,处在什么状态,客户端应该展示什么消息或行动入口。
这样做的好处是职责清楚。客户端负责发起购买、展示权益和接收服务端返回的 entitlement payload;服务端负责验证 receipt、合并通知、维护状态,并在状态变化时重新计算权限。订阅业务以后增加新商品、新优惠或新计费状态,也能先改服务端逻辑,不必等待客户端发版。
详细内容
从订阅旅程建模状态
(01:21)演讲先拆掉 active/inactive 的二分法。一个月订阅在 5 月 1 日购买后,后续可能正常续订,也可能取消自动续订、扣款失败后恢复、进入 Billing Retry,或在 Grace Period 内恢复。每条路径都会改变服务端该保存的状态和客户端该给出的体验。
关键点:
- 初次购买会触发 initial buy 的 server-to-server notification。
- 用户关闭自动续订后,本期仍可使用服务,但后续会通过
expires_date和expiration_intent表现为主动流失。 - Billing Retry 表示 Apple 仍在尝试收款,客户端适合引导用户更新 App Store 付款信息。
- Grace Period 内恢复可以保持原有计费日期连续性,app 应继续提供服务并提示剩余时间。
用 receipt 和通知喂给 entitlement engine
(11:43)Apple 把这套服务端逻辑称作 entitlement engine。输入包括 receipt、server notifications 和 app 自己掌握的用户上下文。输出是一份简化的 JSON payload,用来更新用户数据库,也可以安全返回给设备。
关键点:
- app receipt 是检查交易数据的事实来源,第一步要验证每份 receipt 的真实性。
- 如果起始 receipt 已经过期,服务端应向 App Store 的
verifyReceiptendpoint 请求最新 receipt info。 - 订阅数据分散在
latest_receipt_info、pending_renewal_info等字段中,engine 需要把它们合并成可行动的信息。 - 如果订阅跨多个 app 或平台,服务端还要合并 receipt 之外的状态,避免用户被重复售卖或被错误锁定。
把状态压缩成 cohort 和 entitlement code
(15:35)engine 的中间层先定义 subscriber cohorts,再把一堆 receipt 字段收敛成业务状态。演讲中的示例把状态赋成数值,正值代表可以解锁服务,负值代表不应为该商品提供服务;substate 用小数部分区分免费试用、订阅优惠等商品上下文。
关键点:
- cohort 让服务端把复杂字段组合变成稳定的业务信号。
- entitlement code 可以存到服务端,也可以作为简单信号发给客户端。
- 同一个正值不只表示“解锁”,还可以代表更细的状态,例如免费试用期内已关闭自动续订。
- 这个编码方式只是示例,实际产品可以按自己的订阅分层、优惠策略和计费状态扩展。
为不同状态附加行动
(17:48)当 response object 已经包含 entitlement 信息后,服务端可以按状态附加行动。演讲列了几个典型场景:用户关闭自动续订时给保留 offer;Grace Period 中继续解锁服务并提醒更新付款;Billing Retry 中提供有限访问并引导修复账单;已过期用户收到 win-back offer;连续续订的月付用户看到年付升级建议。
关键点:
- entitlement response 不只是布尔值,还可以携带消息、offer 或下一步行动。
- Grace Period 和 Billing Retry 的目标相近,都是修复付款,但服务权限不同。
- win-back push 仍需要 deep link 到 app 内合适的支付页面。
- 升级建议可以结合续订次数和 subscription group ID,面向忠实月付用户推荐年付商品。
架构从无状态请求迭代到持久化系统
(19:55)Apple 推荐把 entitlement engine 做成高可用服务,让状态变化发生时能立即计算最新权限。最小实现可以先让设备每次请求时把 receipt 发给服务端处理。这个版本能支持不少订阅功能,也能作为存储异常或通知漏处理时的回退路径。
关键点:
- engine 放在服务端后,权限逻辑的错误可以用 receipt 或 mock receipt data 测试,然后直接部署修复。
- 只做无状态请求时,设备必须每次发送 receipt;没有持久化 receipt data,也难以支持 web 或其他平台访问。
- 加入 persistent storage 后,服务端可以保存 receipt data 和 entitlement info,再支持 web 与 off-platform 访问。
- 增加 App Store Server Notifications endpoint 后,服务端能在订阅状态变化时被通知,减少对
verifyReceiptendpoint 的轮询。 - 如果客户端请求 entitlement data,演讲建议考虑用 JSON Web Signature 证明数据来自自己的服务端。
核心启发
- 订阅状态控制台:做什么:为客服、运营和工程团队展示每个用户的 subscription state、substate、最近 receipt 字段和 server notification 时间线。为什么值得做:session 反复强调状态来自多个 receipt 字段和用户行为,控制台能减少“为什么用户被锁住”的排查成本。怎么开始:先按
latest_receipt_info、pending_renewal_info和通知事件生成只读时间线,再把 entitlement code 映射成人能读懂的状态标签。 - 付款修复入口:做什么:在 Billing Retry 和 Grace Period 中展示不同的付款修复提示。为什么值得做:Billing Retry 适合引导更新付款信息,Grace Period 还要显示服务剩余时间。怎么开始:让 entitlement response 携带 billing action、服务是否继续开放、宽限期剩余信息,再由客户端 deep link 到 App Store 账号付款设置。
- 取消续订后的挽留 offer:做什么:识别仍在有效期内但已关闭自动续订的用户,展示保留 offer 或后续订阅优惠。为什么值得做:演讲给出的 retention example 正是利用 auto-renewal status 和当前订阅商品做挽留。怎么开始:在 entitlement engine 中为 auto-renew off 的 active cohort 加上 retention message,并让 paywall 只在该状态下显示。
- 忠实用户年付升级推荐:做什么:把连续续订多期的月付用户引导到年付订阅。为什么值得做:session 建议用续订次数和 subscription group ID 识别忠实用户,再提供折扣升级。怎么开始:在服务端为同一 subscription group 聚合 renewal count,达到阈值后在 entitlement payload 中加入 annual upgrade action。
- 跨平台权限兜底:做什么:让 iOS、web 和其他平台都请求同一个服务端 entitlement endpoint。为什么值得做:演讲指出持久化 receipt data 后才能支持 web 和 off-platform 访问,并能在通知漏处理时用存储数据保持准确。怎么开始:先把设备发送 receipt 的无状态接口落地,再逐步增加 receipt storage、notification endpoint 和数据库同步流程。
关联 Session
- What’s new with in-app purchase — 补充 refunds、App Store server notifications、receipts 和 subscriber status 的 2020 更新。
- Introducing StoreKit Testing in Xcode — 先在本地与 Sandbox 验证 StoreKit、receipt 和订阅场景,再把服务端 entitlement 逻辑接上。
- What’s new in App Store Connect — 了解 App Store Connect 中 in-app purchase、subscriptions 和管理工具的更新。
- Expanding automation with the App Store Connect API — 把 App Store Connect 的管理、报告和分析流程自动化,补足订阅业务后台链路。
评论
GitHub Issues · utterances