跳过内容

创建 iOS 订阅组

GitHub

iOS应用程序中的订阅组是组织和管理多个订阅级别的关键。了解它们的工作原理对于实现升级、降级和交叉级别功能至关重要。

订阅组是iOS应用程序中组织和管理多个订阅级别的关键。了解它们的工作原理对于实现升级、降级和交叉级别功能至关重要。

为什么订阅组很重要

订阅组的重要性

订阅组功能:

  • 阶梯式定价: 提供基本、优质和极致计划
  • : 月度、年度和终身选项升级/降级逻辑
  • : 自动处理订阅变更简化管理
  • : 将相关订阅组合在一起订阅等级

Why Subscription Groups Matter

订阅等级

在一个组内,每个订阅应该按从最高价值(等级1)到最低价值的顺序排列。这一排序决定了订阅变更的分类:

订阅组层级

等级示例

等级1

(最高价值) 年度高级版($99.99/年)

  • 月度最高版($19.99/月)
  • 等级2

(中等价值) 年度标准版($49.99/年)

  • 等级示例
  • __CAPGO_KEEP_0__

Level 3 (最低价值)

  • __CAPGO_KEEP_1__
  • Standard Monthly ($4.99/month)

__CAPGO_KEEP_2__

订阅变更类型

Apple 根据等级排名自动处理三种订阅变更类型:

1. 升级

升级到

更高等级 Section titled “Subscription Change Types” 降级 (例如,级别 2 → 级别 1).

行为:

  • 立即生效 立即
  • 用户收到 剩余时间的部分退款 新订阅立即开始
  • 示例:

复制到剪贴板

// User currently has: Standard Monthly (Level 2)
// User upgrades to: Premium Annual (Level 1)
// Result: Immediate access to Premium, refund for unused Standard time

标题:2. 降级

__CAPGO_KEEP_0__

将升级到 一个 更低等级的

订阅(例如,级别1→级别2)。

  • 行为: 生效时间点
  • 下一次续订日期
  • 用户保持当前订阅直到期限结束

新订阅将自动开始在过期后

// User currently has: Premium Annual (Level 1)
// User downgrades to: Standard Monthly (Level 2)
// Result: Premium access continues until annual renewal date, then switches

复制到剪贴板

3. 升级到更高级别

切换到另一个订阅 在同一等级.

行为取决于持续时间:

不同持续时间 → 与 降级

  • 下一次续订日期生效
  • 例如:月度高级 (等级 1) → 年度高级 (等级 1)

相同持续时间 → 与 升级

  • 立即生效
  • Example: Premium Monthly (Level 1) → Ultimate Monthly (Level 1)

创建订阅组

创建订阅组
  1. 前往订阅

    在 App Store Connect 中,选择您的应用并转到 营利 > 订阅.

  2. 创建组

    点击 + 订阅组

  3. 为该组命名

    选择一个描述性的名称,反映其中包含的订阅:

    • “高级访问”
    • “云存储计划”
    • “专业功能”
  4. 添加订阅

    创建组后,添加单个订阅到其中。每个订阅将有一个等级排名。

  5. 设置等级排名

    按最高价值(1)到最低价值的顺序排列订阅。考虑到:

    • 年度计划通常比月度计划更高
    • 价格更高的等级排在价格更低的等级之上
    • 最终/高级等级最高

native-purchases插件自动处理订阅组逻辑:

import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
// Fetch all subscriptions in a group
const { products } = await NativePurchases.getProducts({
productIdentifiers: ['premium_monthly', 'premium_annual', 'ultimate_monthly'],
productType: PURCHASE_TYPE.SUBS,
});
// Display current subscription using StoreKit transactions
const { purchases } = await NativePurchases.getPurchases({
productType: PURCHASE_TYPE.SUBS,
});
const activeSubs = purchases.filter((purchase) => purchase.isActive);
// Detect pending downgrade/cancellation (StoreKit sets willCancel === true)
const pendingChange = purchases.find((purchase) => purchase.willCancel === true);
if (pendingChange) {
console.log('Subscription will stop auto-renewing on', pendingChange.expirationDate);
}
// Purchase (StoreKit handles upgrades/downgrades automatically)
await NativePurchases.purchaseProduct({
productIdentifier: 'premium_annual',
productType: PURCHASE_TYPE.SUBS,
});
// Listen for StoreKit updates (fires on upgrades/downgrades/refunds)
NativePurchases.addListener('transactionUpdated', (transaction) => {
console.log('Subscription updated:', transaction);
});

处理订阅变化

标题:处理订阅变化

检测变化类型

标题:检测变化类型
import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
// Get current subscription info
const { purchases } = await NativePurchases.getPurchases({
productType: PURCHASE_TYPE.SUBS,
});
const currentSubscription = purchases.find(
(purchase) => purchase.subscriptionState === 'subscribed',
);
if (currentSubscription) {
// StoreKit reports if user cancelled auto-renew
if (currentSubscription.willCancel) {
console.log(
`User cancelled. Access remains until ${currentSubscription.expirationDate}`,
);
}
if (currentSubscription.isUpgraded) {
console.log('User recently upgraded to this plan.');
}
}
// Listen for automatic upgrades/downgrades
NativePurchases.addListener('transactionUpdated', (transaction) => {
console.log('Subscription changed!', transaction);
if (transaction.subscriptionState === 'revoked') {
revokeAccess();
} else if (transaction.isActive) {
unlockPremiumFeatures();
}
});

始终清晰地说明变化行为:

升级时:

“You’ll get immediate access to Premium features. We’ll prorate your current subscription.”

降级时:

“您将保留Premium访问权直到[续费日期],然后切换到标准版。”

For Crossgrades:

“您的计划将在下一次续费时更改为年度计费,于[date]。”

使用Apple的App Store Server Notifications v2或您的收据验证后端来镜像StoreKit的更改并将其反映在您的数据库中。将服务器通知与监听器配对,以便客户端和后端保持同步。 transactionUpdated 最佳实践

标题:最佳实践

组组织
  • “您将保留Premium访问权直到[续费日期],然后切换到标准版。”
  • 不要混淆不相关的功能(例如,存储和广告移除)
  • 为不同功能集创建单独的组

等级排名策略

等级排名策略
  • 年度计划 → 与月度计划相同的等级,但更高
  • 更高价格等级 → 更高
  • 考虑价值,而不是仅仅价格

用户体验

用户体验
  • 清晰显示当前订阅
  • 在组中显示所有可用选项
  • 指出哪些变化是立即生效的,而哪些是在续订时生效的
  • 轻松切换计划

测试

测试
  • 测试所有升级场景
  • 测试所有降级场景
  • 验证升降级行为
  • 检查 webhook 触发

常见场景

常见场景

场景 1:每月三层计划

场景 1:每月三层计划
Level 1: Ultimate Monthly ($19.99)
Level 2: Premium Monthly ($9.99)
Level 3: Basic Monthly ($4.99)
  • 基本 → 高级:立即升级
  • 高级 → 最终:立即升级
  • 最终 → 高级:下一次续费时降级
  • 基本 → 最终:立即升级

场景 2:混合时长计划

标题:场景 2:混合时长计划
Level 1: Premium Annual ($99.99/year)
Level 2: Premium Monthly ($9.99/month)
  • 月度 → 年度:在续费时进行跨级升级
  • 年度 → 月度:在续费时降级

场景 3:多层级多时长

标题:场景 3:多层级多时长
Level 1: Ultimate Annual ($199/year)
Level 2: Ultimate Monthly ($19.99/month)
Level 3: Premium Annual ($99/year)
Level 4: Premium Monthly ($9.99/month)
Level 5: Basic Annual ($49/year)
Level 6: Basic Monthly ($4.99/month)

此设置提供了最大灵活性,同时保持清晰的升级/降级逻辑。

订阅未在组中显示:

  • 确认它已分配到正确的组
  • 检查它至少处于“准备提交”状态
  • 确保产品 ID 正确

升级/降级行为错误:

  • 检查级别排名(1 = 最高)
  • 确认订阅等级合理
  • 检查级别设置正确

来自不同组的产品:

  • 用户可以同时订阅多个组
  • 这是故意的 - 将相关产品放在同一组

getActiveProducts显示多个订阅:

  • 检查订阅是否在不同的组
  • 验证用户不是通过家庭共享订阅
  • 在App Store Connect中检查订阅状态

欲知更多详细信息,请参阅 苹果官方文档关于订阅组.

从创建iOS订阅组继续

标题:从创建iOS订阅组继续

如果您正在使用 创建iOS订阅组 以规划商店审批和分发,连接它与 使用@capgo/native-purchases 为native能力在使用@capgo/native-purchases中 @capgo/capacitor-in-app-review 为实现细节在@capgo/capacitor-in-app-review中 使用@capgo/capacitor-in-app-review 为native能力在使用@capgo/capacitor-in-app-review中 @capgo/capacitor-native-market 为实现细节在@capgo/capacitor-native-market中,以及 使用@capgo/capacitor-native-market 为capgo/capacitor原生市场使用原生能力。