알림: 2022년 8월 2일부터 모든 신규 앱은 결제 라이브러리 버전 4 이상을 사용해야 합니다. 2022년 11월 1일부터는 기존 앱의 모든 업데이트에도 결제 라이브러리 버전 4 이상이 요구됩니다. 자세히 알아보기

Google Play 결제 라이브러리 4에서 5로의 이전 가이드

이 주제에서는 Google Play 결제 라이브러리 4에서 Google Play 결제 라이브러리 5로 이전하는 방법과 새로운 정기 결제 기능을 사용하는 방법을 설명합니다.

개요

Google Play 결제 라이브러리 5에서는 정기 결제 기본 요금제와 정기 결제 혜택을 도입했습니다. 이러한 기능을 통해 정기 결제를 판매하는 방식이 확장되고 이전 버전에 비해 통합 복잡성이 줄어듭니다.

Play Console 또는 Play Developer API를 사용하면 여러 기본 요금제(각각 여러 혜택 포함)가 있는 단일 정기 결제를 구성할 수 있습니다. 정기 결제 혜택에는 유연한 가격 모델과 지원 옵션이 있습니다. 다양한 자동 갱신 및 선불 요금제를 사용하여 정기 결제 수명 주기 동안 혜택을 만들 수 있습니다. 자세한 내용은 통합 가이드를 참고하세요.

이전 단계

Google Play 결제 라이브러리 업데이트

기존 Play 결제 라이브러리 종속 항목을 앱 build.gradle 파일의 업데이트된 버전으로 바꿉니다.

dependencies {
    def billingVersion = "5.0.0"

    implementation "com.android.billingclient:billing:$billingVersion"
}

메서드 호출을 수정하지 않았더라도 프로젝트가 즉시 빌드됩니다. Play 결제 라이브러리 5는 이전 버전과 호환되기 때문입니다. 하지만 SKU 개념은 지원 중단된 것으로 간주합니다.

결제 클라이언트 초기화 및 Google Play 연결 설정

Android 앱에서 구매를 시작하는 첫 번째 단계는 동일하게 유지됩니다.

구매 가능한 제품 표시

사용자가 구매할 수 있는 모든 혜택을 획득하려면 다음 단계를 따르세요.

  • SkuDetailsParamsQueryProductDetailsParams로 바꿉니다.
  • BillingClient.queryProductDetailsAsync()를 사용하도록 BillingClient.querySkuDetailsAsync() 호출을 전환합니다.

이제 쿼리 결과는 SkuDetails가 아닌 ProductDetails입니다. 각 ProductDetails 항목에는 제품(ID, 제품명, 유형 등)에 관한 정보가 포함되어 있습니다. 정기 결제 제품의 경우 ProductDetails에는 정기 결제 혜택 세부정보 목록인 List<ProductDetails.SubscriptionOfferDetails>가 포함되어 있습니다. 일회성 구매 제품의 경우 ProductDetails에는 ProductDetails.OneTimePurchaseOfferDetails가 포함되어 있습니다. 이를 통해 사용자에게 표시할 혜택을 결정할 수 있습니다.

다음 예는 이러한 변경사항을 적용하기 전과 후의 앱 모습을 보여줍니다.

Kotlin

val skuList = ArrayList<String>()

skuList.add("up_basic_sub")

val params = SkuDetailsParams.newBuilder()

params.setSkusList(skuList).setType(BillingClient.SkuType.SUBS)

billingClient.querySkuDetailsAsync(params.build()) {
    billingResult,
    skuDetailsList ->
    // Process the result
}

자바

List<String> skuList = new ArrayList<>();

skuList.add("up_basic_sub");

SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();

params.setSkusList(skuList).setType(SkuType.SUBS);

billingClient.querySkuDetailsAsync(params.build(),
    new SkuDetailsResponseListener() {
        @Override
        public void onSkuDetailsResponse(BillingResult billingResult,
                List<SkuDetails> skuDetailsList) {
            // Process the result.
        }
    }
);

Kotlin

val productList =
    listOf(
        QueryProductDetailsParams.Product.newBuilder()
            .setProductId("up_basic_sub")
            .setProductType(BillingClient.ProductType.SUBS)
            .build()
    )

val params = QueryProductDetailsParams.newBuilder().setProductList(productList)

billingClient.queryProductDetailsAsync(params.build()) {
    billingResult,
    productDetailsList ->
    // Process the result
}

자바

ImmutableList<Product> productList = ImmutableList.of(Product.newBuilder()
                                            .setProductId("up_basic_sub")
                                            .setProductType(ProductType.SUBS)
                                            .build());

QueryProductDetailsParams params = QueryProductDetailsParams.newBuilder()
    .setProductList(productList)
    .build();

billingClient.queryProductDetailsAsync(
        params,
        new ProductDetailsResponseListener() {
                public void onProductDetailsResponse(BillingResult billingResult, List<ProductDetails> productDetailsList) {
                    // Process the result
                }
        }
);

queryProductDetailsAsync의 콜백은 List<ProductDetails>를 반환합니다. 각 ProductDetails 항목에는 제품(ID, 제품명, 유형 등)에 관한 정보가 포함되어 있습니다. 주요 차이점은 이제 정기 결제 제품에도 사용자에게 제공되는 모든 혜택이 포함된 List<ProductDetails.SubscriptionOfferDetails>가 포함된다는 것입니다.

이전 버전의 Play 결제 라이브러리는 새 객체(정기 결제, 기본 요금제, 혜택 등)를 지원하지 않으므로 새 시스템은 각 정기 결제 SKU를 이전 버전과 호환되는 단일 기본 요금제 및 혜택으로 변환합니다. 사용 가능한 일회성 구매 제품도 ProductDetails 객체로 포팅됩니다. 일회성 구매 제품의 혜택 세부정보는 getOneTimePurchaseOfferDetails() 메서드로 액세스할 수 있습니다.

혜택 구매 흐름 시작

혜택의 구매 흐름을 시작하는 것은 SKU의 흐름을 시작하는 것과 매우 유사합니다. 버전 5를 사용하여 구매 요청을 시작하려면 다음을 실행하세요.

  • BillingFlowParamsSkuDetails를 사용하는 대신 ProductDetailsParams를 사용합니다.
  • 혜택 세부정보는 SubscriptionOfferDetails 객체를 사용하여 가져올 수 있습니다.

사용자가 선택한 혜택으로 제품을 구매하려면 선택한 혜택의 offerToken을 가져와서 ProductDetailsParams 객체에 전달합니다.

BillingFlowParams 객체를 만든 후 BillingClient를 사용하여 결제 흐름을 시작하는 것은 동일하게 유지됩니다.

다음 예는 이러한 변경사항을 적용하기 전과 후의 앱 모습을 보여줍니다.

Kotlin

// An activity reference from which the billing flow will be launched.
val activity : Activity = ...;
// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
val billingFlowParams = BillingFlowParams.newBuilder()
                            .setSkuDetails(skuDetails)
                            .build()

val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

자바

// An activity reference from which the billing flow will be launched.
Activity activity = ...;
// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
        .setSkuDetails(skuDetails)
        .build();

BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

Kotlin

// An activity reference from which the billing flow will be launched.
val activity : Activity = ...;
// Retrieve a value for "productDetails" by calling queryProductDetailsAsync()
// Get the offerToken of the selected offer
val offerToken = productDetails.subscriptionOfferDetails?.get(selectedOfferIndex)?.offerToken

val productDetailsParamsList =
    listOf(
        BillingFlowParams.ProductDetailsParams.newBuilder()
            .setProductDetails(productDetails)
            .setOfferToken(offerToken)
            .build()
    )
val billingFlowParams =
    BillingFlowParams.newBuilder()
        .setProductDetailsParamsList(productDetailsParamsList)
        .build()

// Launch the billing flow
val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

자바

// Retrieve a value for "productDetails" by calling queryProductDetailsAsync()
// Get the offerToken of the selected offer
String offerToken = productDetails
                     .getSubscriptionOfferDetails()
                     .get(selectedOfferIndex)
                     .getOfferToken();
// Set the parameters for the offer that will be presented
// in the billing flow creating separate productDetailsParamsList variable
ImmutableList<ProductDetailsParams> productDetailsParamsList =
        ImmutableList.of(
                 ProductDetailsParams.newBuilder()
                     .setProductDetails(productDetails)
                     .setOfferToken(offerToken)
                     .build()
        );

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
            .setProductDetailsParamsList(productDetailsParamsList)
            .build();

// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

구매 처리

Google Play 결제 라이브러리 5로 구매를 처리하는 것은 이전 버전과 유사합니다.

사용자가 소유한 모든 활성 구매를 가져오고 새 구매를 쿼리하려면 다음을 실행하세요.

  • BillingClient.SkuType 값을 queryPurchasesAsync()에 전달하는 대신 BillingClient.ProductType 값이 포함된 QueryPurchasesParams 객체를 전달합니다.

다음 예는 이러한 변경사항을 적용하기 전과 후의 앱 모습을 보여줍니다.

Kotlin

billingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS) {
    billingResult,
    purchaseList -> {
        // Process the result
    }
}

자바


billingClient.queryPurchasesAsync(
    BillingClient.SkuType.SUBS,
    new PurchasesResponseListener() {
        public void onQueryPurchasesResponse(
                BillingResult billingResult,
                List&lt;Purchase> purchases) {
            // process the result
        }
    }
);

Kotlin

billingClient.queryPurchasesAsync(
    QueryPurchasesParams.newBuilder()
        .setProductType(BillingClient.ProductType.SUBS)
        .build()
) { billingResult, purchaseList ->
    // Process the result
}

자바

billingClient.queryPurchasesAsync(
    QueryPurchasesParams.newBuilder().setProductType(ProductType.SUBS).build(),
    new PurchasesResponseListener() {
        public void onQueryPurchasesResponse(
                BillingResult billingResult,
                List<Purchase> purchases) {
            // Process the result
        }
    }
);

앱 외부 구매대기 중인 거래를 관리하는 단계는 변경되지 않았습니다.

정기 결제 상태 관리

상태를 확인하고 정기 결제 구매를 관리하는 정기 결제 상태 관리 구성요소가 백엔드에 있는 경우 Subscription Purchases API를 사용해야 합니다. 이전 버전의 변경사항에 관한 자세한 내용은 2022년 5월 새로운 정기 결제 기능 가이드를 참고하세요.