1.Xcode本地测试(StoreKit Configuration)适用场景:开发初期,快速验证UI和基础逻辑
从 Xcode 12 开始,苹果终于大发慈悲,推出了本地 StoreKit 测试。这是最高效的测试方式,完全不需要联网,也不需要在 App Store Connect 后台建品!
实操步骤:
在 Xcode 中新建一个StoreKit Configuration File(.storekit 文件)。
在该文件中配置你的订阅群组(Subscription Group)和具体的订阅项(产品ID、价格、时长)。
在Edit Scheme→Options中,将StoreKit Configuration设置为你刚建的文件。
杀手锏功能:
打开 Xcode 菜单栏的 Debug → StoreKit → Manage Transactions。
然后你可以模拟:
2.沙盒环境测试(Sandbox Testing)适用场景:联调服务端(S2S),验证真实苹果服务器交互
本地测试再爽,最终也要和苹果真实的服务器打交道。这就必须用到经典的Sandbox沙盒环境。
沙盒时间压缩机制(必须牢记):
在沙盒里,你不需要真的等一个月看它是否续费。苹果做了时间压缩机制:
注意:沙盒环境下的自动续期最多只会续 6 次,之后会自动停止。
实操步骤:
登录 App Store Connect,在“用户和访问”中添加沙盒测试账号(Sandbox Testers)。
退出你手机上的真实 Apple ID(在系统设置 → App Store → 沙盒账户中登录)。
后端联调必备:
对于后端同学来说,必须处理 App Store Server Notifications (V2)。在 App Store Connect 后台配置好测试回调URL,当沙盒账号发生订阅、取消、续费时,苹果会向你的服务器发送 JSON 数据。现在苹果甚至提供了 App Store Server API,可以在后台主动请求测试通知!
适用场景:上线前最后的灰度测试、产品验收
TestFlight 的环境最接近真实生产环境。
支付环境: 它是生产环境的“镜像”,使用的是真实的 App Store 账号,但不会真实扣款。
时间流速:TestFlight 中的订阅没有时间压缩! 买一个月的订阅,就是真正的一个月。
主要目的:验证整套流程对普通用户是否顺畅,UI 表现是否正常,以及验证收据验证(Receipt Validation)是否完美切到了生产环境。
测试订阅,千万别只测“买一次能不能成功”。以下这些核心场景,漏掉一个都可能引发线上客诉:
基础订阅与恢复
卸载重装 App,点击“恢复购买(Restore)”能否恢复权益?
跨设备登录同一个 Apple ID 能否共享订阅权益?
升级、降级与跨级 (Upgrade / Downgrade / Crossgrade)
升级(如月度换年度):应当立即生效,苹果会按比例退还上一个订阅剩余的钱。
降级(如年度换月度):应当下个周期生效,当前周期权益不变。
特殊状态模拟
取消订阅(Cancel):用户在系统设置里取消订阅,当前周期内权益应保留,下个周期失效。
退款(Refund):用户向苹果客服申请退款成功,后端收到REFUND通知,App 立即撤销用户权益。
账单重试(Billing Retry):用户绑定的信用卡扣款失败,进入宽限期,恢复支付后权益是否自动恢复?
促销优惠(Offers)
推介期优惠(免费试用 3 天 / 首月半价):只对新用户生效,老用户是否能钻空子?
促销代码(Promo Codes):输入兑换码后权益能否正常解锁?
1.测试账号混乱
很多时候沙盒报错,是因为你手机的 App Store 登着真实账号,沙盒登着测试账号,缓存串了。
解决办法:专门备一台测试机,只登沙盒账号。
2.凭证校验(Receipt Validation)地址固定
苹果有沙盒和生产两个校验地址。
正确做法:后端先请求生产地址,如果返回状态码21007,则自动重试沙盒地址。这样同一个后端代码就能兼容 TF 和正式服。
3.忽略了 StoreKit 2
如果你还在用老掉牙的 StoreKit 1 处理复杂的收据,赶紧升级到 StoreKit 2 吧!全 Swift 异步 API,自带 JWS 签名验证,简直不要太香。
3.家人共享(Family Sharing)
如果你的订阅开启了家人共享,一定要测试家庭成员账号的权益同步情况,这也是客诉的重灾区。
iOS 订阅测试是一个漫长且需要多端(客户端、服务端、App Store)配合的过程。
建立一套标准的测试 SOP,充分利用 Xcode 本地测试提高效率,用沙盒环境兜底边缘情况,你的 App 商业化之路才能走得稳健。
互动话题:
在测苹果内购的时候,你遇到过什么让人崩溃的 Bug 吗?欢迎在评论区和大家一起吐槽交流~