跳过内容

创建iOS订阅组

GitHub

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

什么是订阅组?

标题:什么是订阅组?

订阅组是一组相关的订阅,用户可以选择其中一个。用户只能在一个组内订阅一个订阅。他们切换订阅时,苹果会自动处理转换。

为什么订阅组很重要?

标题:为什么订阅组很重要?

订阅组使您能够:

  • 阶梯式定价提供基本、精英和极致计划
  • 不同的持续时间: 每月、年付和终身选项
  • Upgrade/downgrade logic: 订阅变更的自动处理
  • Simplified management: 将相关订阅组合在一起

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

Subscription group hierarchy

Level 1 (最高价值)

  • 年度高级版 ($99.99/年)
  • 月度高级版 ($19.99/月)

Level 2 (中等价值)

  • 年度标准版 ($49.99/年)
  • 月度高级版 ($9.99/月)

Level 3 (最低价值)

  • 年度基础版 ($29.99/年)
  • 月度标准版 ($4.99/月)

订阅变更类型

订阅类型

苹果会根据订阅等级自动处理三种订阅变化类型:

1. 升级

升级

升级到 更高级别 的订阅(例如,从等级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

降级到 较低等级的 订阅(例如,等级 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

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

行为取决于持续时间:

不同持续时间 → 与 降级

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

相同持续时间 → 类似于 升级

  • 立即生效
  • 例如:高级月度(级别1)→ 最终月度(级别1)
  1. 导航到订阅

    在 App Store Connect 中,选择您的应用程序并转到 <i class="fas fa-arrow-right"></i> Monetize > 订阅.

  2. 创建组

    点击 + 点击“订阅组”旁边的下一步按钮创建一个新的组。

  3. 命名组

    为包含的订阅选择一个描述性的名称:

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

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

  5. 设置级别排名

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

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

在您的应用程序中使用

标题:在您的应用程序中使用

原生购买插件自动处理订阅组逻辑:

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();
}
});

用户通信

用户通信

始终清晰地说明更改行为:

升级:

“您将立即获得Premium功能。我们将根据您的当前订阅进行折扣。”

降级:

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

交叉升级:

“您的计划将在下一次续订时更改为年度计费。”

服务器监控

服务器监控

使用Apple的App Store Server Notifications v2或您的自己的收据验证后端来反映StoreKit的更改。将服务器通知与以下内容配对: transactionUpdated listener 使客户端和后端保持同步。

最佳实践

最佳实践

组件组织

组件组织
  • 将相关订阅放在同一个组中
  • 不要混淆不相关的功能(例如,存储和广告移除)
  • 为不同功能集创建单独的组
  • 更高价格的等级 → 更高等级
  • listener 使客户端和后端保持同步。
  • 考虑价值而非仅仅价格

用户体验

用户体验
  • 显式当前订阅
  • 在组中显示所有可用选项
  • 标示哪些变化立即生效,哪些在续订时生效
  • 方便地在计划之间切换
  • 测试所有降级场景
  • 验证跨级别升级行为
  • context
  • 检查 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 在使用@capgo/native-purchases中 使用@capgo/capacitor-in-app-review 在 @capgo/capacitor-in-app-review 中实现详细信息 使用 @capgo/capacitor-in-app-review 在使用 @capgo/capacitor-in-app-review 中实现原生能力 @capgo/capacitor-native-market 在 @capgo/capacitor-native-market 中实现详细信息,并 使用 @capgo/capacitor-native-market 在使用 @capgo/capacitor-native-market 中实现原生能力