콘텐츠로 건너뛰기

iOS 구독 그룹 만들기

구독 그룹은 iOS 앱에서 여러 구독 수준을 구성하고 관리하는 데 필수적입니다. 업그레이드, 다운그레이드 및 크로스그레이드 기능을 구현하려면 작동 방식을 이해하는 것이 중요합니다.

구독 그룹은 사용자가 선택할 수 있는 관련 구독의 모음입니다. 사용자는 그룹 내에서 한 번에 하나의 구독만 구독할 수 있습니다. 구독을 전환하면 Apple이 전환을 자동으로 처리합니다.

구독 그룹을 사용하면 다음이 가능합니다.

  • 계층별 가격: 기본, 프리미엄, 최종 요금제 제공
  • 다양한 기간: 월별, 연간 및 평생 옵션
  • 업그레이드/다운그레이드 로직: 구독 변경 자동 처리
  • 간소화된 관리: 관련 구독을 그룹화합니다.

그룹 내에서 각 구독은 가장 높은 값(수준 1)에서 가장 낮은 값까지 순위가 지정되어야 합니다. 이 순위에 따라 구독 변경 사항이 분류되는 방식이 결정됩니다.

구독 그룹 계층 구조

수준 1(가장 높은 값)

  • 연간 프리미엄 ($99.99/년)
  • Ultimate Monthly ($19.99/월)

레벨 2(중간 값)

  • 표준 연간 ($49.99/년)
  • 월간 프리미엄 ($9.99/월)

레벨 3(가장 낮은 값)

  • 기본 연간 ($29.99/년)
  • 표준 월간 ($4.99/월)

Apple는 레벨 순위에 따라 세 가지 유형의 구독 변경을 자동으로 처리합니다.

상위 등급 구독으로 이동합니다(예: 레벨 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단계)

동일한 기간업그레이드처럼 작동

  • 즉시 적용됩니다.
  • 예: Premium Monthly(레벨 1) → Ultimate Monthly(레벨 1)
  1. 구독으로 이동

    App Store Connect에서 앱을 선택하고 수익 창출 > 구독으로 이동합니다.

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

항상 변경 동작을 명확하게 전달하세요.

업그레이드의 경우:

“프리미엄 기능에 즉시 액세스할 수 있습니다. 현재 구독 금액을 일할 계산해 드립니다.”

다운그레이드의 경우:

“[갱신 날짜]까지 프리미엄 액세스를 유지한 후 스탠다드로 전환하세요.”

크로스그레이드의 경우:

“귀하의 요금제는 [날짜]에 다음 갱신 시 연간 청구로 변경됩니다.”

Apple의 App Store 서버 알림 v2 또는 자체 영수증 확인 백엔드를 사용하여 데이터베이스의 StoreKit 변경 사항을 미러링하세요. 클라이언트와 백엔드가 모두 동기화 상태를 유지할 수 있도록 서버 알림을 transactionUpdated 리스너와 페어링하세요.

  • 관련 구독을 동일한 그룹에 유지
  • 관련 없는 기능(예: 저장 및 광고 제거)을 혼합하지 마십시오.
  • 다양한 기능 세트에 대해 별도의 그룹 생성
  • 연간 요금제 → 월간 요금제 상위(동일 요금제)
  • 고가 등급 → 상위 등급
  • 가격만이 아닌 가치를 고려하라
  • 현재 구독을 명확하게 표시
  • 그룹에서 사용 가능한 모든 옵션을 표시합니다.
  • 어떤 변경 사항이 즉시 적용되는지 아니면 갱신 시 적용되는지 표시
  • 요금제 간 쉽게 전환 가능
  • 모든 업그레이드 시나리오 테스트
  • 모든 다운그레이드 시나리오 테스트
  • 크로스그레이드 동작 확인
  • 웹훅 실행 확인
Level 1: Ultimate Monthly ($19.99)
Level 2: Premium Monthly ($9.99)
Level 3: Basic Monthly ($4.99)
  • 기본 → 프리미엄 : 업그레이드(즉시)
  • 프리미엄 → 얼티밋: 업그레이드(즉시)
  • 얼티밋 → 프리미엄 : 다운그레이드 (갱신시)
  • 기본 → 궁극기 : 업그레이드(즉시)
Level 1: Premium Annual ($99.99/year)
Level 2: Premium Monthly ($9.99/month)
  • 월간 → 연간 : 크로스그레이드 (갱신시)
  • 연간 → 월간 : 다운그레이드 (갱신시)

시나리오 3: 다중 계층 다중 기간

Section titled “시나리오 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에서 구독 상태를 검토하세요.

자세한 내용은 구독 그룹에 대한 공식 Apple 문서를 참조하세요.