设置 12 个月承诺计划

Important

要提供承诺方案,您需要一个年度 App Store 订阅以及一个流程或自定义付费墙。流程要求 iOS 上的 Adapty SDK v4.3.1 或更高版本、Android 上的 v4.3 或更高版本,以及 React Native 或 Flutter 上的 v4.3.0 或更高版本。自定义付费墙要求 iOS、React Native 或 Flutter 上的 Adapty SDK v4.3 或更高版本。

要让订阅者承诺完整的一年并按月付款,请在 App Store Connect 和 Adapty 中为您的年度产品添加 12 个月承诺方案。

开始之前

在实现承诺方案之前,请确认你已完成以下准备工作:

  • 锁定正确的市场:承诺计划在美国不可用。在德国、以色列、南非和土耳其,订阅者可以通过 Apple Support 立即取消。
  • 锁定正确的操作系统版本:订阅者需要 iOS 26.4 或更高版本,或同等版本的 iPadOS、macOS、tvOS 或 visionOS。请使用 Xcode 26.5 或更高版本构建你的应用。
  • 锁定正确的价格区间:12 次月付款的总金额必须介于年付订阅金额的 1 倍到 1.5 倍之间。
  • 使用受支持的 Adapty SDK 版本:流程需要 iOS 上的 Adapty SDK v4.3.1 或更高版本、Android 上的 v4.3 或更高版本,以及 React Native 或 Flutter 上的 v4.3.0 或更高版本。自定义付费墙需要 iOS、React Native 或 Flutter 上的 Adapty SDK v4.3 或更高版本:在使用较早 SDK 版本的应用版本中,用户只能购买预付方案。
  • 更新读取产品 ID 的代码:Webhook、集成、数据导出和服务端 API 会将承诺计划的购买报告为 <product_id>:monthly。如果你的代码处理产品 ID,请在首次承诺计划购买发生前更新相关逻辑。

1. App Store Connect 配置

  1. 在 App Store Connect 中打开一个年度订阅,或创建一个新订阅,时长设为 1 Year。
  2. 在 Availability 部分,在 1 Year Upfront 和 Monthly with 12-Month Commitment 下添加相同的国家/地区。Apple 仅在提供预付费计费的地区才提供承诺计费。反之则不要求:你可以在没有承诺计划的国家/地区提供预付方案。
  3. 在 Subscription Prices 部分,为你的基础地区设置预付价格(如果订阅尚未设置)。即使你只向用户展示承诺计划,Apple 也要求设置预付价格。
  4. 为你的基础地区设置月价格。月价格必须为预付价格的 1/12 到 1/8。例如,预付价格为 €59.99 时,月价格可设为 €5.00 到 €7.49。

App Store Connect 会根据您的基础地区价格自动计算其他国家/地区的价格。

如需完整操作说明,请参阅 Apple 的指南:提供按月付费的 12 个月承诺订阅。

2. Adapty 配置

要在流程或自定义付费墙中展示承诺计划,需要在 Adapty 中为年付产品启用该选项。如果两者都不使用,可以跳过此步骤。

  1. 打开年付产品。如果该产品尚不存在,请创建并关联你在 App Store Connect 中设置的订阅。不要从 Adapty 推送新产品:这会创建一个不包含承诺计划的独立订阅。

  2. 打开 App Store 选项卡,选择 Offer monthly payments with a 12-month commitment。

    App Store tab of a yearly product with the Offer monthly payments with a 12-month commitment checkbox
  3. 在弹出窗口中,从 Monthly price, USD 列表中选择与 App Store Connect 匹配的分期付款价格。该列表仅包含允许范围内的 App Store 价格点。此价格为参考值:Adapty 不会将其发送至 App Store Connect。

    Monthly with 12-month commitment pop-up with the Monthly price, USD field

3. 设置优惠

在 App Store Connect 中,每个计费方案都有各自的新用户优惠、促销活动、赢回优惠和优惠码。针对预付款方案的优惠不适用于承诺方案。

  • 免费试用及其他新用户优惠:在 App Store Connect 中为承诺方案设置优惠。Adapty 会自动应用新用户优惠。新用户优惠结束后,订阅者的 12 个月承诺期正式开始。
  • 促销活动和赢回优惠:在 App Store Connect 中为承诺方案设置促销活动或赢回优惠。然后将优惠添加到 Adapty,并将其 App Store plan 设置为 Monthly with 12-month commitment。流程或付费墙产品仅列出其自身计费方案对应的优惠。如果你既不使用流程也不使用自定义付费墙,则无需将优惠添加到 Adapty。
  • 兑换码:在 App Store Connect 中为承诺方案设置兑换码。

4. 添加到流程或自定义付费墙

Warning

Apple 要求在购买前同时展示分期付款价格和年度总价。

流程

  1. 在流程编辑工具中,打开 Products 面板,将标记为 Monthly 的年付产品添加到屏幕。如果希望在同一屏幕上同时销售一次性付清方案,也请添加标记为 Upfront 的产品。
    • 如需为购买一次性付清方案的用户提供一次性付清优惠(适用于较早版本的 SDK,或承诺方案不适用的情况),请在 Fallback offer 下选择该优惠。
  2. 将 Monthly 产品分配给产品卡或Purchase 操作。
  3. 要显示分期价格,请插入 prod_billing_price 和 prod_billing_period 变量;要显示年付总价,请插入 prod_price。分期变量需要 iOS 上的 Adapty SDK v4.3.1 或更高版本,或 React Native、Flutter 上的 v4.3.0 或更高版本。
  4. 要预览无法购买承诺方案的用户所看到的屏幕,请在 Products 面板中打开 Monthly 产品的菜单,然后选择 Offer > Monthly plan unavailable。

自定义付费墙

  1. 在自定义付费墙中,添加年度产品,并将其 Billing plan 设置为 Monthly。如需在同一付费墙上同时销售预付方案,请再次添加该年度产品,并选择 Upfront 计费方案。
    • 如需为购买预付方案的用户提供预付优惠(适用于较早版本的 SDK,或承诺方案不适用的情况),请在 Fallback offer 下选择对应优惠。
  2. 在应用中,从 product.subscriptionPricingTerms 读取价格进行展示。对于可以购买承诺方案的用户,Adapty SDK 会返回承诺方案的定价;对于其他用户,SDK 则返回预付方案的定价:
    • 若要判断 SDK 返回的是哪种方案,请检查 product.subscriptionPricingTerms?.billingPlan。承诺方案对应的值为 .monthly,预付方案对应的值为 .upFront。
    • 若要显示分期价格,请使用 subscriptionPricingTerms.localizedBillingPrice 和 subscriptionPricingTerms.billingPeriod。
    • 若要显示年度总价,请使用 subscriptionPricingTerms.commitmentInfo.localizedPrice 和 subscriptionPricingTerms.commitmentInfo.period。对于承诺方案,product.localizedPrice 和 product.subscriptionPeriod 同样会返回年度相关数据。
    • 在 React Native 中,请从 product.subscription?.ios?.pricingTerms 读取定价信息。其中 billingPlan 的值为 'monthly' 对应承诺方案,'up_front' 对应预付方案。分期价格使用 billingPrice.localizedString 和 billingPeriod,年度总价使用 commitmentInfo.price.localizedString 和 commitmentInfo.period。
    • 在 Flutter 中,请从 product.subscription?.pricingTerms 读取定价信息。其中 billingPlan 的值为 AdaptySubscriptionBillingPlan.monthly 对应承诺方案,AdaptySubscriptionBillingPlan.upFront 对应预付方案。分期价格使用 billingPrice.localizedString 和 billingPeriod,年度总价使用 commitmentInfo.price.localizedString 和 commitmentInfo.period。

用户在以下情况下无法购买承诺计划:

  • 不支持的操作系统版本或国家/地区:用户的 Apple 设备系统版本低于 26.4,或该方案在其 App Store 所在国家/地区不可用。Adapty SDK 将返回预付方案的定价。
  • 已有预付订阅:StoreKit 报告用户已订阅。如需切换方案,订阅者可通过 Apple 订阅设置进行操作。
  • App Store 内推广购买:用户在 App Store 中选择产品后,Adapty SDK 在您的应用内发起购买。此类购买仅支持预付方案。

如需停止提供承诺付款计划,请在流程中替换或移除 Monthly 产品;在自定义付费墙中,将年度产品的 Billing plan 设置为 Upfront,或移除 Monthly 行。在 Adapty 中,您无法取消勾选 Offer monthly payments with a 12-month commitment 复选框。现有订阅者每年仍会续订新的承诺计划,除非您在 App Store Connect 中点击年度订阅的 Remove Monthly Billing。已完成承诺的订阅者将继续付款,直至承诺期结束。

5. 在沙盒中测试方案

参照沙盒测试指南,使用两个沙盒账号进行测试:

  • 来自你提供承诺方案的国家的账号:付费墙应显示承诺方案,同时展示月价格和总价。购买后,该沙盒用户的用户画像应具备年度产品的访问等级。
  • 美国账号:付费墙应仅显示预付方案。

如果你的代码需要处理来自 webhook 或服务端 API 的产品 ID,请确认它能正确接收格式为 <product_id>:monthly 的承诺计划购买记录。

如需在本地测试购买逻辑,请使用 Xcode 中的 StoreKit 测试 26.5 或更高版本。通过 StoreKit 测试完成的购买不会上报到 Adapty。

在应用中显示承诺进度

要向订阅用户展示其承诺完成进度,请从用户画像中读取访问等级。其 billingPlan 和 commitmentInfo 属性需要 iOS 上的 Adapty SDK v4.3 或更高版本,或 React Native、Flutter 上的 v4.3.0 或更高版本。

  • 若要判断订阅者是否处于承诺方案,请将 billingPlan 与 monthly 值进行比较。不要检查该属性是否已设置:它也可能持有 upfront 值。
  • 若要显示进度,使用 commitmentInfo.billingPeriodNumber 表示当前付款期数,使用 commitmentInfo.totalBillingPeriods 表示总付款期数。
  • 若要显示承诺结束时间,使用 commitmentInfo.expiresAt,而非访问等级的 expiresAt 属性。

故障排查

  • 月付复选框缺失:Offer monthly payments with a 12-month commitment 复选框仅在具有 App Store 产品 ID 的 Annual 产品上显示,且需设置 Price (USD) 后才会激活。
  • 用户看不到承诺套餐的免费试用或其他优惠:在 App Store Connect 中,每个优惠归属于一个计费方案。请为承诺套餐设置优惠。若为促销活动或赢回优惠,还需在 Adapty 中将优惠的 App Store plan 设置为 Monthly with 12-month commitment。
  • 所有用户都看到预付价格:请确认以下两点:
    • 应用使用 Xcode 26.5 或更高版本构建。若使用更低版本,Adapty SDK 始终返回预付方案的价格。
    • 在流程中,屏幕使用了标记为 Monthly 的年度产品;在自定义付费墙中,年度产品的 Billing plan 为 Monthly。
  • 部分用户看到预付价格:这些用户无法购买承诺套餐。
  • 付费墙显示年度总价而非分期价格:
    • 在流程中,prod_price 返回年度总价。如需显示分期价格,请使用 prod_billing_price。在 Adapty iOS SDK v4.3.0 上,prod_billing_price 同样返回年度总价,请将 SDK 升级至 v4.3.1 或更高版本。
    • 在自定义付费墙中,product.localizedPrice 返回年度总价。如需显示分期价格,请使用 subscriptionPricingTerms.localizedBillingPrice。在 React Native 中,请使用 product.subscription?.ios?.pricingTerms?.billingPrice.localizedString。在 Flutter 中,请使用 product.subscription?.pricingTerms?.billingPrice.localizedString。