You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何正确验证iOS自动续期内购(IAP)的过期日期?

嘿,关于iOS自动续期内购的收据验证与过期判断,我来给你捋捋靠谱的实践方案~

iOS自动续期内购的订阅状态管理指南

一、先说说「本地存收据+启动对比过期日」的潜在坑

  • 本地时间可篡改:用户手动修改设备时间,会直接导致你用本地时间对比expires_date_ms的逻辑完全失效,误判订阅状态。
  • 收据不是实时更新:自动续期成功后,苹果不会主动推送新收据给App(除非你配置了服务器通知),本地存的还是旧收据,会漏判续期情况。
  • 本地数据易丢失:用户卸载重装App后,本地收据直接清空,得重新走验证流程,体验很不顺畅。

二、更稳妥的流程建议

1. 服务器端持久化存储订阅核心信息

每次完成收据验证后,把expires_date_ms、订阅ID、用户唯一标识、最新收据等关键数据存在你的服务器数据库里,不要只依赖本地存储。这样不管用户换设备还是重装App,都能从服务器拉取到最新的订阅状态。

2. App启动时优先从服务器获取状态

  • App启动后,第一时间向你的服务器请求当前用户的订阅状态(包括过期时间、是否有效),而不是先查本地收据。
  • 拿到服务器返回的结果后,再做对应的权限控制(比如解锁会员功能、隐藏付费内容)。

3. 结合主动验证+苹果官方通知

  • 定期主动验证:可以设置每隔24小时(或更合理的间隔),App把本地收据(如果存在)传给服务器,服务器再去苹果服务器做验证,同步更新数据库里的订阅状态。
  • 开启App Store Server Notifications:这是必须要做的!苹果会在订阅续期、过期、退款、价格调整等关键事件发生时,主动推送通知给你的服务器。这样你能实时更新用户的订阅状态,不用等App主动发起请求。

4. 本地仅做临时 fallback 判断

如果服务器请求失败(比如网络差),可以临时用本地存储的expires_date_ms做判断,但要加个限制:比如对比本地时间和服务器上次返回的时间戳,如果间隔超过1小时,就提示用户检查网络,重新同步状态,避免长期依赖不可靠的本地数据。

三、Swift代码小示例(App端状态判断)

假设从服务器拿到了过期时间戳,判断逻辑可以这样写:

// 从服务器获取的订阅过期时间(毫秒级时间戳)
let expiresDateMs: Int64 = 1716883200000
// 当前时间转毫秒级时间戳
let currentTimeMs = Date().timeIntervalSince1970 * 1000

if currentTimeMs < Double(expiresDateMs) {
    // 订阅未过期,解锁会员功能
    unlockPremiumFeatures()
} else {
    // 订阅已过期,引导用户重新购买
    showSubscriptionPurchasePrompt()
}

四、关键注意事项

  • 永远信任服务器返回的状态:本地数据是用户可篡改、可丢失的,完全不可控,不能作为唯一判断依据。
  • 验证收据时要取latest_receipt_info:苹果返回的收据里,这个字段包含了最新的续期记录,不要只看第一条购买信息。
  • 及时处理退款通知:用户申请退款后,苹果会推送通知,服务器要立刻更新用户订阅状态,取消对应的权限。

内容的提问来源于stack exchange,提问作者Johnny

火山引擎 最新活动