2022년 5월 정기 결제 변경 가이드

Google Play 결제 시스템은 Android 앱에서 디지털 제품과 콘텐츠를 판매할 수 있게 해주는 서비스입니다. 2022년 5월 출시를 통해 정기 결제 제품이 정의되는 방식을 변경했으며 이는 앱 내에서 판매되고 백엔드에서 관리되는 방식에 영향을 미칩니다. Google Play 결제와 처음 통합하는 경우 준비하기를 참고하여 통합을 시작할 수 있습니다.

2022년 5월 전에 Google Play 결제로 정기 결제를 판매한 경우 기존 정기 결제를 유지하면서 새로운 기능을 채택하는 방법을 이해하는 것이 중요합니다.

먼저 알아야 할 사항은 2022년 5월 출시 전과 마찬가지로 모든 기존 정기 결제, 앱, 백엔드 통합이 작동한다는 점입니다. 즉시 변경할 필요는 없으며 시간이 지남에 따라 이러한 새 기능을 채택할 수 있습니다. Google Play 결제 라이브러리의 각 주요 출시는 출시 후 2년 동안 지원됩니다. Google Play Developer API와의 기존 통합은 전처럼 계속 작동합니다.

다음은 2022년 5월 업데이트의 개요입니다.

  • 새로운 Google Play Console을 사용하여 정기 결제, 기본 요금제, 혜택을 만들고 관리할 수 있습니다. 여기에는 신규 및 이전된 정기 결제가 모두 포함됩니다.
  • Play Developer API에는 API 형식의 새로운 Google Play Console UI 기능을 지원하는 업데이트가 포함되어 있습니다. 특히 새로운 버전의 Subscription Purchases API가 있습니다. 이 API를 사용하여 정기 결제 상태를 확인하고 정기 결제 구매를 관리합니다.
  • 새로운 Play 결제 라이브러리 버전 5를 사용하면 앱에서 새로운 정기 결제 기능을 모두 활용할 수 있습니다. 버전 5로 업그레이드할 준비가 되면 이전 가이드의 안내를 따르세요.

정기 결제 구성

Google Play Console을 통한 정기 결제 관리

2022년 5월부터 Google Play Console에 몇 가지 차이점이 있습니다.

이제 단일 정기 결제에 여러 기본 요금제와 혜택이 포함될 수 있습니다. 이전에 생성된 정기 결제 SKU는 이제 Play Console에 이러한 새로운 정기 결제, 기본 요금제, 혜택 객체로 표시됩니다. 아직 확인하지 않았다면 Play Console의 최근 정기 결제 변경사항을 참고하여 기능 및 구성을 비롯한 새로운 객체에 관한 설명을 확인하세요. 기존의 모든 정기 결제 제품은 이 새로운 형식으로 Google Play Console에 표시됩니다. 각 SKU는 이제 단일 기본 요금제와 이전 버전과 호환되는 혜택(해당하는 경우)이 포함된 정기 결제 객체로 표시됩니다.

기존 통합에서는 각 정기 결제에 SkuDetails 객체로 표현되는 단일 혜택이 포함되어야 했으므로 각 정기 결제에는 이전 버전과 호환되는 단일 기본 요금제나 혜택이 있을 수 있습니다. 이전 버전과 호환되는 기본 요금제 또는 혜택은 현재 지원 중단된 querySkuDetailsAsync() 메서드를 사용하는 앱의 SKU의 일부로 반환됩니다. 이전 버전과 호환되는 혜택의 구성 및 관리에 관한 자세한 내용은 정기 결제 이해를 참고하세요. 앱이 queryProductDetailsAsync()만 사용하고 아직도 구매를 지원하는 이전 버전의 앱이 없다면 이전 버전과 호환되는 혜택을 더 이상 활용하지 않아도 됩니다.

Subscriptions Publishing API를 통한 정기 결제 관리

Play Developer API에는 정기 결제 구매를 위한 새로운 기능이 포함되어 있습니다. SKU 관리용 inappproducts API는 일회성 구매 제품 및 정기 결제 처리를 비롯하여 전처럼 계속 작동하므로 통합을 유지하기 위해 즉시 변경할 필요가 없습니다.

그러나 Google Play Console은 새 정기 결제 항목만 사용합니다. Console에서 정기 결제를 수정하기 시작하면 inappproducts API를 더 이상 정기 결제에 사용할 수 없습니다.

2022년 5월 이전에 Publishing API를 사용한 경우 문제가 발생하지 않도록 이제 기존 정기 결제가 Google Play Console에 읽기 전용으로 표시됩니다. 변경하려고 하면 이러한 제한사항을 설명하는 경고가 표시될 수 있습니다. Console에서 정기 결제를 추가로 수정하기 전에 백엔드 통합을 업데이트하여 새 정기 결제 게시 엔드포인트를 사용해야 합니다. 새로운 monetization.subscriptions, monetization.subscriptions.baseplans, monetization.subscriptions.offers 엔드포인트를 사용하면 제공되는 모든 기본 요금제 및 혜택을 관리할 수 있습니다. 다음 표에서는 여러 필드가 InAppProduct 항목에서 monetization.subscriptions 아래 새 객체로 매핑되는 방식을 확인할 수 있습니다.

InAppProduct 정기 결제
packageName packageName
sku productId
status basePlans[0].state
prices basePlans[0].regionalConfigs.price
listings 등록정보
defaultPrice 동등하지 않음
subscriptionPeriod basePlans[0].autoRenewingBasePlanType.billingPeriodDuration
trialPeriod basePlans[0].offers[0].phases[0].regionalConfigs[0].free
gracePeriod basePlans[0].autoRenewingBasePlanType.gracePeriodDuration
subscriptionTaxesAndComplianceSettings taxAndComplianceSettings

이 필수 API 업데이트는 Publishing API(SKU 관리)에만 적용됩니다.

Play 결제 라이브러리 변경사항

점진적 이전을 지원하기 위해 Play 결제 라이브러리에는 이전 버전에서 사용할 수 있는 모든 메서드와 객체가 포함되어 있습니다. SkuDetails 객체 및 함수(예:querySkuDetailsAsync())는 계속 있으므로 기존 정기 결제 코드를 즉시 업데이트하지 않고도 새로운 기능을 사용하도록 업그레이드할 수 있습니다. 이전 버전과 호환되는 것으로 표시하여 이러한 메서드를 통해 사용할 수 있는 혜택을 제어할 수도 있습니다.

기존 메서드를 유지하는 것 외에도 이제 Play 결제 라이브러리 5에는 새로운 ProductDetails 객체 및 상응하는 queryProductDetailsAsync() 메서드가 포함되어 새로운 항목과 기능을 처리합니다. 이제 기존 인앱 상품(일회성 구매 및 소모품)도 ProductDetails로 지원됩니다.

정기 결제의 경우 ProductDetails.getSubscriptionOfferDetails()는 사용자가 구매할 수 있는 모든 기본 요금제와 혜택 목록을 반환합니다. 즉, 이전 버전과의 호환성과 관계없이 사용자에게 제공되는 모든 기본 요금제와 혜택에 액세스할 수 있습니다. getSubscriptionOfferDetails()는 비 정기 결제 제품의 경우 null을 반환합니다. 일회성 구매의 경우 getOneTimePurchaseOfferDetails()를 사용하면 됩니다.

Play 결제 라이브러리 5에는 구매 흐름을 시작하는 새로운 메서드와 기존 메서드도 모두 포함되어 있습니다. BillingClient.launchBillingFlow()에 전달된 BillingFlowParams 객체가 SkuDetails 객체를 사용하여 구성된 경우 시스템은 SKU에 상응하는 이전 버전과 호환되는 기본 요금제나 혜택에서 판매할 혜택 정보를 추출합니다. BillingClient.launchBillingFlow()에 전달된 BillingFlowParams 객체가 ProductDetailsParams 객체(구매되는 혜택의 특정 혜택 토큰을 나타내는 ProductDetailsString이 포함되어 있음)를 사용하여 구성된 경우 시스템은 이 정보를 사용하여 사용자가 획득하는 제품을 식별합니다.

queryPurchasesAsync()는 사용자가 소유한 모든 구매를 반환합니다. 요청된 제품 유형을 나타내려면 BillingClient.SkuType 값(이전 버전과 동일)을 전달하거나 새 정기 결제 항목을 나타내는 BillingClient.ProductType 값이 포함된 QueryPurchasesParams 객체를 전달하면 됩니다.

이러한 새로운 정기 결제 기능을 활용할 수 있도록 조만간 라이브러리 버전 5로 앱을 업데이트하는 것이 좋습니다.

정기 결제 상태 관리

이 섹션에서는 버전 5로의 이전을 위해 구현해야 하는 Google Play 결제 시스템 통합의 백엔드 구성요소에 관한 주요 변경사항을 설명합니다.

실시간 개발자 알림

조만간 SubscriptionNotification 객체에 더 이상 subscriptionId가 포함되지 않게 됩니다. 이 필드를 사용하여 정기 결제 제품을 식별한다면 알림을 수신한 후 purchases.subscriptionv2:get을 사용하여 정기 결제 상태에서 이 정보를 가져오도록 업데이트해야 합니다. 구매 상태의 일부로 반환되는 lineItems 컬렉션의 각 SubscriptionPurchaseLineItem 요소는 상응하는 productId를 포함하게 됩니다.

Subscriptions Purchases API: 정기 결제 상태 가져오기

이전 버전의 Subscriptions Purchases API에서는 purchases.subscriptions:get을 사용하여 정기 결제 상태를 쿼리할 수 있었습니다. 이 엔드포인트는 변경되지 않으며 이전 버전과 호환되는 정기 결제 구매에서 계속 작동합니다. 이 엔드포인트는 2022년 5월에 출시된 새로운 기능은 지원하지 않습니다.

새로운 버전의 Subscriptions Purchases API에서는 purchases.subscriptionsv2:get을 사용하여 정기 결제 구매 상태를 가져옵니다. 이 API는 이전된 정기 결제와 새로운 정기 결제(선불 및 자동 갱신), 모든 유형의 구매와 호환됩니다. 알림을 받을 때 이 엔드포인트를 사용하여 정기 결제 상태를 확인할 수 있습니다. 반환된 객체 SubscriptionPurchaseV2에는 새 필드가 포함되어 있지만 기존 정기 결제를 계속 지원하는 데 필요한 기존 데이터도 여전히 포함되어 있습니다.

선불 요금제의 SubscriptionPurchaseV2 필드

자동 갱신되는 대신 사용자가 연장하는 선불 요금제를 지원하기 위해 새 필드가 추가되었습니다. 모든 필드는 자동 갱신 정기 결제와 마찬가지로 선불 요금제에 적용되며 다음과 같은 예외가 있습니다.

  • [New field] lineItems[0].prepaid_plan.allowExtendAfterTime: 사용자가 선불 요금제를 연장하기 위해 다른 충전을 구매할 수 있는 시기를 나타냅니다. 사용자는 미사용 충전을 한 번에 하나만 보유할 수 있기 때문입니다.
  • [New field] SubscriptionState: 정기 결제 객체 상태를 지정합니다. 선불 요금제의 경우 이 값은 항상 ACTIVE 또는 PENDING, CANCELED입니다.
  • lineItems[0].expiryTime: 이 필드는 선불 요금제에 항상 표시됩니다.
  • paused_state_context: 이 필드는 표시되지 않습니다. 선불 요금제는 일시중지할 수 없기 때문입니다.
  • lineItems[0].auto_renewing_plan: 선불 요금제에는 표시되지 않습니다.
  • canceled_state_context: 선불 요금제에는 표시되지 않습니다. 이 필드는 정기 결제를 적극적으로 취소하는 사용자에게만 적용되기 때문입니다.
  • lineItems[0].productId: 이 필드는 이전 버전의 subscriptionId를 대체합니다.

반복 정기 결제의 SubscriptionPurchaseV2 필드

purchases.subscriptionv2에는 새 정기 결제 객체에 관한 세부정보를 제공하는 새 필드가 포함되어 있습니다. 다음 표는 기존 정기 결제 엔드포인트의 필드가 purchases.subscriptionv2의 상응하는 필드에 매핑되는 방식을 보여줍니다.

SubscriptionPurchase SubscriptionPurchaseV2
countryCode regionCode
orderId latestOrderId
(상응하는 필드가 없음) lineItems(SubscriptionPurchaseLineItem 목록). 구매 시 획득한 제품을 나타냅니다.
(상응하는 필드가 없음) lineItems.offerDetails.basePlanId
(상응하는 필드가 없음) lineItems.offerDetails.offerId
(상응하는 필드가 없음) lineItems.offerDetails.offerTags
startTimeMillis startTime
expiryTimeMillis lineItems.expiryTime(구매에서 획득한 정기 결제마다 자체 expiryTime이 있음)
(상응하는 필드가 없음) subscriptionState( 정기 결제 상태를 나타냄)
(상응하는 필드가 없음) pausedStateContext(정기 결제 상태가 SUBSCRIPTION_STATE_PAUSED인 경우에만 표시됨)
autoResumeTimeMillis pausedStateContext.autoResumeTime
(상응하는 필드가 없음) canceledStateContext(정기 결제 상태가 SUBSCRIPTION_STATE_CANCELED인 경우에만 표시됨)
(상응하는 필드가 없음) testPurchase(라이선스 테스터 구매에만 표시됨)
autoRenewing lineItems.autoRenewingPlan.autoRenewEnabled
priceCurrenceCode, priceAmountMicros, introductoryPriceInfo (상응하는 필드가 없음)
이 정보는 구매한 각 정기 결제의 basePlan/offer에서 확인할 수 있습니다.
developerPayload (상응하는 필드가 없음)개발자 페이로드가 지원 중단되었습니다.
paymentState (상응하는 필드 없음)
subscriptionState에서 결제 상태를 추론할 수 있습니다.
  • 결제가 대기 중입니다.
    • SUBSCRIPTION_STATE_PENDING(대기 중인 거래가 있는 새 구매)
    • SUBSCRIPTION_STATE_IN_GRACE_PERIOD
    • SUBSCRIPTION_STATE_ON_HOLD
  • 입금이 완료되었습니다.
    • SUBSCRIPTION_STATE_ACTIVE
  • 무료 체험:
    • (상응하는 필드가 없음)
  • 업그레이드/다운그레이드 지연:
    • SUBSCRIPTION_STATE_PENDING
cancelReason, userCancellationTimeMillis, cancelSurveyResult canceledStateContext
linkedPurchaseToken linkedPurchaseToken(변경사항 없음)
purchaseType 테스트: testPurchase를 통해
프로모션: signupPromotion
priceChange lineItems.autoRenewingPlan.priceChangeDetails
profileName, emailAddress, givenName, familyName, profileId subscribeWithGoogleInfo
acknowledgementState acknowledgementState (no change)
promotionType, promotionCode signupPromotion
externalAccountId, obfuscatedExternalAccountId, obfuscatedExteranlProfileId externalAccountIdentifiers

기타 정기 결제 관리 기능

purchases.subscriptions:getpurchases.subscriptionsv2:get으로 업그레이드되었지만 나머지 개발자 정기 결제 관리 기능은 당분간 purchases.subscriptions 엔드포인트에서 변경되지 않고 유지되므로 purchases.subscriptions:acknowledge, purchases.subscriptions:cancel, purchases.subscriptions:defer, purchases.subscriptions:refund, purchases.subscriptions:revoke를 전처럼 계속 사용할 수 있습니다.

Pricing API

monetization.convertRegionPrices 엔드포인트를 사용하여 Play Console과 마찬가지로 지역별 가격을 계산합니다. 이 메서드는 모든 Play 지원 통화로 된 단일 가격을 수락하고 Google Play에서 구매를 지원하는 모든 지역의 변환된 가격(해당하는 경우 기본 세율 포함)을 반환합니다.