Flutter in_app_purchase如何加载历史购买,restorePurchases该何时调用?
方案对比与推荐做法
先说核心结论:不建议只把订阅状态存在SharedPreference里、仅切换设备时才调用restorePurchases,理由和可选方案如下:
为什么不能纯靠本地缓存?
- 自动续期订阅的状态是动态变化的,和换不换设备没有关系:用户可能在应用外主动取消订阅、续费失败被平台停权、甚至被苹果/谷歌全额退款,这些状态变化你存在本地的缓存完全感知不到,会导致你给已经没有订阅权限的用户开放付费功能,产生损失。
SharedPreference是客户端明文存储,用户只要有root/越狱权限就可以直接修改对应字段的值,不需要任何购买行为就能绕过你的权限校验。- 你没法精准判断用户是否切换了设备,普通用户根本不会主动触发「我换设备了」的操作,真换设备的时候大概率会直接来找客服说自己买的会员找不到了,平白增加售后成本。
每次启动都调用restorePurchases有什么注意事项?
- 这个方案本身是可行的,接口的网络开销极低,对用户启动速度几乎没有影响,唯一要注意的是iOS平台的适配:如果用户没有登录Apple ID,调用
restorePurchases会自动弹出登录弹窗,要是你给从来没买过订阅的用户每次启动都弹这个,会非常影响体验。 - 针对这个问题可以加个简单的逻辑:
- 从未产生过购买行为的用户,启动时不主动调用
restorePurchases,只在用户主动点击页面上的「恢复购买」按钮时才调用 - 只要用户曾经成功完成过一次购买,你就在本地存一个标记,之后每次启动都主动调用
restorePurchases同步最新的订阅状态即可
- 从未产生过购买行为的用户,启动时不主动调用
更稳妥的优化方案
如果你的应用有自己的后端服务,最好把订阅票据传到后端,由后端定期和苹果/谷歌的订阅校验接口同步状态,客户端每次启动直接从后端拿最新的权限状态,比客户端自己调restorePurchases更可靠,也能避免客户端缓存被篡改的问题。
内容的提问来源于stack exchange,提问作者Max Tromp
相关产品推荐
相关产品推荐

