Create iOS Subscription Group
Subscription groups are essential for organizing and managing multiple subscription levels in your iOS app. Understanding how they work is crucial for implementing upgrade, downgrade, and crossgrade functionality.
What is a Subscription Group?
Section titled âWhat is a Subscription Group?âA subscription group is a collection of related subscriptions that users can choose between. Users can only subscribe to one subscription within a group at a time. When they switch subscriptions, Apple handles the transition automatically.
Why Subscription Groups Matter
Section titled âWhy Subscription Groups MatterâSubscription groups enable:
- Tiered pricing: Offer basic, premium, and ultimate plans
- Different durations: Monthly, yearly, and lifetime options
- Upgrade/downgrade logic: Automatic handling of subscription changes
- Simplified management: Group related subscriptions together
Subscription Levels
Section titled âSubscription LevelsâWithin a group, each subscription should be ranked from highest value (level 1) to lowest value. This ranking determines how subscription changes are classified:

Level Examples
Section titled âLevel ExamplesâLevel 1 (Highest Value)
- Premium Annual ($99.99/year)
- Ultimate Monthly ($19.99/month)
Level 2 (Medium Value)
- Standard Annual ($49.99/year)
- Premium Monthly ($9.99/month)
Level 3 (Lowest Value)
- Basic Annual ($29.99/year)
- Standard Monthly ($4.99/month)
Subscription Change Types
Section titled âSubscription Change TypesâApple automatically handles three types of subscription changes based on the level ranking:
1. Upgrade
Section titled â1. UpgradeâMoving to a higher-tier subscription (e.g., level 2 â level 1).
Behavior:
- Takes effect immediately
- User receives prorated refund for remaining time
- New subscription starts right away
Example:
// User currently has: Standard Monthly (Level 2)// User upgrades to: Premium Annual (Level 1)// Result: Immediate access to Premium, refund for unused Standard time2. Downgrade
Section titled â2. DowngradeâMoving to a lower-tier subscription (e.g., level 1 â level 2).
Behavior:
- Takes effect at next renewal date
- User keeps current subscription until period ends
- New subscription starts automatically after expiration
Example:
// User currently has: Premium Annual (Level 1)// User downgrades to: Standard Monthly (Level 2)// Result: Premium access continues until annual renewal date, then switches3. Crossgrade
Section titled â3. CrossgradeâSwitching to another subscription at the same tier level.
Behavior depends on duration:
Different Duration â Behaves like downgrade
- Takes effect at next renewal date
- Example: Monthly Premium (Level 1) â Annual Premium (Level 1)
Same Duration â Behaves like upgrade
- Takes effect immediately
- Example: Premium Monthly (Level 1) â Ultimate Monthly (Level 1)
Creating a Subscription Group
Section titled âCreating a Subscription Groupâ-
Navigate to Subscriptions
In App Store Connect, select your app and go to Monetize > Subscriptions.
-
Create Group
Click + next to âSubscription Groupsâ to create a new group.
-
Name the Group
Choose a descriptive name that reflects the subscriptions it contains:
- âPremium Accessâ
- âCloud Storage Plansâ
- âPro Featuresâ
-
Add Subscriptions
After creating the group, add individual subscriptions to it. Each subscription will have a level ranking.
-
Set Level Rankings
Arrange subscriptions from highest value (1) to lowest value. Consider:
- Annual plans typically rank higher than monthly
- Higher-priced tiers rank above lower-priced ones
- Ultimate/premium tiers rank highest
Using in Your App
Section titled âUsing in Your AppâThe native-purchases plugin automatically handles subscription group logic:
import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
// Fetch all subscriptions in a groupconst { products } = await NativePurchases.getProducts({ productIdentifiers: ['premium_monthly', 'premium_annual', 'ultimate_monthly'], productType: PURCHASE_TYPE.SUBS,});
// Display current subscription using StoreKit transactionsconst { 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);});Handling Subscription Changes
Section titled âHandling Subscription ChangesâDetecting Change Type
Section titled âDetecting Change Typeâimport { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
// Get current subscription infoconst { 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/downgradesNativePurchases.addListener('transactionUpdated', (transaction) => { console.log('Subscription changed!', transaction); if (transaction.subscriptionState === 'revoked') { revokeAccess(); } else if (transaction.isActive) { unlockPremiumFeatures(); }});User Communication
Section titled âUser CommunicationâAlways communicate the change behavior clearly:
For Upgrades:
âYouâll get immediate access to Premium features. Weâll prorate your current subscription.â
For Downgrades:
âYouâll keep Premium access until [renewal date], then switch to Standard.â
For Crossgrades:
âYour plan will change to Annual billing at the next renewal on [date].â
Server monitoring
Section titled âServer monitoringâUse Appleâs App Store Server Notifications v2 or your own receipt-validation backend to mirror StoreKit changes in your database. Pair server notifications with the transactionUpdated listener so both client and backend stay in sync.
Best Practices
Section titled âBest PracticesâGroup Organization
Section titled âGroup Organizationâ- Keep related subscriptions in the same group
- Donât mix unrelated features (e.g., storage and ad removal)
- Create separate groups for different feature sets
Level Ranking Strategy
Section titled âLevel Ranking Strategyâ- Annual plans â Higher level than monthly (for same tier)
- Higher-priced tiers â Higher level
- Consider value, not just price
User Experience
Section titled âUser Experienceâ- Show current subscription clearly
- Display all available options in the group
- Indicate which changes are immediate vs. at renewal
- Allow easy switching between plans
Testing
Section titled âTestingâ- Test all upgrade scenarios
- Test all downgrade scenarios
- Verify crossgrade behavior
- Check webhook firing
Common Scenarios
Section titled âCommon ScenariosâScenario 1: Three-Tier Monthly Plans
Section titled âScenario 1: Three-Tier Monthly PlansâLevel 1: Ultimate Monthly ($19.99)Level 2: Premium Monthly ($9.99)Level 3: Basic Monthly ($4.99)- Basic â Premium: Upgrade (immediate)
- Premium â Ultimate: Upgrade (immediate)
- Ultimate â Premium: Downgrade (at renewal)
- Basic â Ultimate: Upgrade (immediate)
Scenario 2: Mixed Duration Plans
Section titled âScenario 2: Mixed Duration PlansâLevel 1: Premium Annual ($99.99/year)Level 2: Premium Monthly ($9.99/month)- Monthly â Annual: Crossgrade (at renewal)
- Annual â Monthly: Downgrade (at renewal)
Scenario 3: Multi-Tier Multi-Duration
Section titled âScenario 3: Multi-Tier Multi-Durationâ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)This setup provides maximum flexibility while maintaining clear upgrade/downgrade logic.
Troubleshooting
Section titled âTroubleshootingâSubscription not appearing in group:
- Verify itâs assigned to the correct group
- Check that itâs in at least âReady to Submitâ status
- Ensure product ID is correct
Wrong upgrade/downgrade behavior:
- Review level rankings (1 = highest)
- Verify subscription tiers make sense
- Check that levels are set correctly
Products from different groups:
- Users can subscribe to multiple groups simultaneously
- This is intentional - keep related products in same group
getActiveProducts showing multiple subscriptions:
- Check if subscriptions are in different groups
- Verify user isnât subscribed via Family Sharing
- Review subscription status in App Store Connect
Additional Resources
Section titled âAdditional ResourcesâFor more details, refer to the official Apple documentation on subscription groups.