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
객체(구매되는 혜택의 특정 혜택 토큰을 나타내는 ProductDetails
및 String
이 포함되어 있음)를 사용하여 구성된 경우 시스템은 이 정보를 사용하여 사용자가 획득하는 제품을 식별합니다.
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 |
lineItems.autoRenewingPlan.recurringPrice |
introductoryPriceInfo |
(상응하는 필드가 없음) 이 정보는 구매한 각 정기 결제의 offer 에서 확인할 수 있습니다. |
developerPayload | (상응하는 필드가 없음)개발자 페이로드가 지원 중단되었습니다. |
paymentState | (상응하는 필드 없음)subscriptionState 에서 결제 상태를 추론할 수 있습니다.
|
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:get
이 purchases.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에서 구매를 지원하는 모든 지역의 변환된 가격(해당하는 경우 기본 세율 포함)을 반환합니다.