优惠码入口已经显示“兑换成功”,但订阅内容仍未解锁?
先用 Xcode 的 StoreKit Testing 验证购买与权益逻辑,再用 App Store Connect 创建的 Sandbox 优惠码和 Sandbox Apple Account 验收实际兑换;本地通过不等于 Sandbox 兑换通过。

正在为自动续期订阅增加优惠码入口的独立开发者,可用本文区分本地逻辑测试与实际兑换验收。
已配置优惠活动、准备测试 Sandbox 兑换的开发者,可按职责整理步骤和证据。
维护订阅交易及权益服务的小团队,可据此核对 App 与服务端的处理结果。

负责购买逻辑:先划清本地 StoreKit Testing 的边界

Xcode 的 StoreKit Testing 使用项目中的本地或同步 StoreKit 配置,在不连接 App Store 服务器的情况下测试应用内购买。它适合快速检查商品展示、购买流程、交易结果处理和权益发放;同步配置可从 App Store Connect 的购买项目创建,本地配置则可在项目内维护。两者仍属于 Xcode 测试环境,不能证明 Sandbox 优惠码已经成功兑换。Apple 的StoreKit Testing 配置说明列出了这两类配置及其用途。

可观察的重点不是付款表单是否弹出,而是交易是否抵达应用,以及权益逻辑是否据此更新。建议把交易中的商品标识、验证状态和订阅权益状态记入测试记录;本地配置可以复现应用如何处理交易,却不能验证真实优惠码是否可用、Sandbox 账户资格是否符合条件,或 App Store 服务器是否发出相应事件。

负责后台配置:将 Sandbox 测试码与正式活动隔开

在 App Store Connect 中,先确认目标自动续期订阅、订阅组、优惠活动和适用资格符合本次测试目的,再从该优惠活动创建 Sandbox codes。Apple 将 Sandbox codes 定义为测试用途的优惠码;设置说明也区分测试码与提供给顾客的正式优惠码。测试凭据应保存在测试记录或受控凭据库中,不要把它当成正式营销码发放。具体界面和规则以订阅优惠码设置说明为准。

这里容易混淆的是“优惠活动已建好”和“某一张码已完成兑换”:前者是后台配置状态,后者还需要设备上的 Sandbox 兑换和应用对交易的处理。测试阶段不要只因为代码是在同一项优惠活动下生成,就认为它们可以互换;创建前也要确认测试目标对应的订阅商品和优惠资格。

负责设备兑换:留存从入口到权益显示的连续证据

Sandbox Apple Account 是测试账号,不是开发者个人用于日常购买的 Apple Account。账号需在 App Store Connect 中创建,再按设备上的 Sandbox 测试入口登录;Apple 的Sandbox Apple Account 创建指南说明,测试账号用于测试应用内购买。

设备验收时,先核对测试账号所在的 App Store storefront 与测试目标一致,再从 Sandbox Account Settings 发起交易并选择 Offer Codes,输入为该优惠活动创建的 Sandbox 码。操作前确认设备登录状态和测试账号设置,避免把普通购买账户当成 Sandbox 账号。

记录时把三个结果分开:兑换入口接受了代码、系统产生了交易、应用展示并开放了对应权益。它们不是同一个状态。若只截取代码提交成功的画面,后续交易可能仍未到达应用;若应用已收到交易,也仍需核对交易验证和当前权益。

清单:设备端至少留下这些验收记录

  • ✅ 记录设备、系统版本、测试应用构建和 Sandbox Apple Account 所属 storefront。
  • ✅ 记录优惠活动的参考名称、测试码来源及测试时间;不要在共享报告中暴露可重复使用的凭据。
  • ✅ 保存系统兑换入口或应用内兑换入口的操作结果。
  • ✅ 记录 StoreKit 收到的交易及其验证结果,并核对商品标识和优惠信息。
  • ✅ 保存应用内订阅权益状态的前后变化;若测试未通过,注明失败发生在入口、交易接收、验证还是权益发放环节。

负责应用内入口:核对兑换表单之后的 StoreKit 流程

系统兑换入口和 App 内兑换入口应分别验收。应用内方式要求项目实现相应 StoreKit 兑换流程;仅有一个输入框或按钮,不代表应用已接入兑换能力。Apple 的应用内优惠码支持文档列出了兑换接口,并说明应用需要处理兑换后交付的交易。

从 App 内打开兑换表单并提交 Sandbox 码后,应观察交易是否进入应用的处理逻辑,再检查应用是否刷新权益状态。官方文档还提醒,应用需要处理在应用外完成的兑换:启动时检查当前权益和未完成交易,并在应用运行期间监听交易更新。可结合 Apple 的应用外购买测试说明设计系统兑换入口的补测。

如果重用同一测试账号时遇到资格或重复兑换问题,先核对优惠资格、storefront 与 Sandbox 购买历史,而不是立刻改应用代码。必要时按测试计划清理或更换 Sandbox 测试账号,并重新验证;清理操作前,先确认不会影响团队正在使用的测试证据。

负责订阅权益和服务端:让交易、权益与通知能相互印证

客户端验收应检查交易是否已验证、应用是否更新当前权益,以及交易是否在完成交付后正确结束。StoreKit 的 currentEntitlements 用于获取当前可访问的购买项目和有效订阅;updates 可接收交易更新,包括应用外完成的兑换。可对照 Apple 的Transaction 文档检查权益读取方式,并验证应用启动和运行期间的交易处理。

若项目接收 App Store Server Notifications,应单独配置并核对 Sandbox 环境的通知接收路径。测试事件要落入可辨识的 Sandbox 记录,避免被误当作生产订阅事件处理;Apple 的通知配置指南说明了生产与 Sandbox 环境通知地址的配置。

发布验收:用两张表区分环境与通过条件

测试方式 可验证的内容 不能单独证明的内容 适合承担的验收工作
Xcode StoreKit Testing 本地商品配置、购买逻辑、交易处理、权益界面 Sandbox 码真实兑换、App Store 服务器参与的交易链路 先查应用逻辑与权益状态
Sandbox 系统兑换 App Store Connect 配置的 Sandbox 码、设备兑换与交易接收 App 内兑换按钮本身是否已正确接入 验证系统入口及应用外交易处理
Sandbox App 内兑换 应用兑换入口、交易到达应用后的处理 生产营销码可用性或生产用户体验 验证已实现的应用内兑换流程
服务端 Sandbox 通知 Sandbox 事件到达服务端后的处理 客户端权益界面必然正确 检查通知、服务端记录与客户端状态是否一致

验收结论应按已取得的证据落档,不要用一次本地购买成功替代完整链路。Apple 的Sandbox 购买测试说明可用于核对 Sandbox 测试环境与本地测试环境的区别。

判定 最低证据要求 处理建议
通过 Sandbox 码已兑换;应用收到并验证交易;当前订阅权益与预期一致;涉及服务端时,Sandbox 事件也进入对应测试记录 保存构建版本、账号 storefront、交易与权益证据,再进入发布检查
未通过 兑换被拒,或交易缺失、验证失败、权益没有按预期开放 按兑换入口、交易接收、验证、权益更新和服务端处理逐段定位
需补测 只有本地 StoreKit Testing 结果,或只看到代码提交成功,缺少后续交易与权益证据 安排 Sandbox 兑换;如支持 App 内兑换,则另测应用内入口

远程 Mac 的边界也应写进验收记录:远程 Mac 可用于 Xcode 项目构建和本地 StoreKit 测试,但这不等于已经完成 Sandbox 账户兑换、设备端实际验收或服务端通知验证。若团队缺少可用于 Xcode 测试的 Mac,可先查看 RUVCLOUD 的远程 Mac 环境说明,再根据项目需求核对方案与价格信息。远程环境只能承担适合在该环境完成的构建与测试工作;Sandbox 账户、兑换设备和测试会话仍需按实际条件安排。

常见问题:把本地结果和实际兑换分开判断

本地 StoreKit 配置能验证订阅优惠码兑换吗?

本地配置适合验证购买逻辑和权益处理,但其交易来自 Xcode 配置的测试环境,不能代替 App Store 服务器参与的 Sandbox 兑换。要确认优惠码链路,需要另行创建 Sandbox 码并使用 Sandbox Apple Account 测试。

Sandbox 优惠码从哪里创建和兑换?

在 App Store Connect 的订阅优惠活动中创建 Sandbox codes,再到测试设备的 Sandbox Account Settings 发起交易并选择优惠码。正式优惠码供顾客活动使用,测试码应单独管理,不要混入营销分发。

怎么检查 App 内输入优惠码的流程?

先确认应用已实现 StoreKit 兑换 API,再从应用内打开系统兑换表单并使用 Sandbox 码。提交之后还要检查交易是否进入应用的更新监听、是否完成验证,以及订阅权益是否实际刷新。

显示兑换成功后,怎样确认订阅权益已生效?

将已验证的 StoreKit 交易与 currentEntitlements、应用界面和服务端订阅记录逐项核对。只看到兑换提示不足以证明权益已开放;如果启用了 App Store Server Notifications,还应确认对应 Sandbox 事件进入测试记录。

通过条件不是“优惠码输入成功”,而是兑换产生的交易、应用展示的订阅权益,以及适用时的服务端 Sandbox 记录能够相互核对。若现有方案需要长期占用开发者自己的 Mac,或把购买流程与实际兑换都留到发布前集中验证,常见代价是设备与账号难协作、测试环境难复用、故障定位被推迟;远程 Mac 租赁可以作为临时构建和 Xcode 测试环境的选择,但不能替代 Sandbox 兑换设备或真实验收条件。项目只需短期补足 macOS 构建环境时,可进一步查看 RUVCLOUD 的使用方案;若需持续重负载或依赖特定实体接口,则应先评估自购设备是否更合适。