일회성 제품의 여러 구매 옵션 및 혜택

이 문서에서는 일회성 제품 (OTP)과 Play Billing Library의 통합에 관해 자세히 설명합니다. 또한 일회성 제품과 관련된 다양한 구매 옵션 및 혜택을 통합하는 방법을 설명합니다.

일회성 제품에 여러 구매 옵션과 혜택을 구성할 수 있습니다. 예를 들어 동일한 일회성 제품에 구입 구매 옵션과 선주문 혜택을 구성할 수 있습니다.

기본 요건

일회성 제품에 여러 혜택을 구성하려면 queryProductDetailsAsync() API를 사용해야 합니다. 지원 중단된 querySkuDetailsAsync() API는 지원되지 않습니다. queryProductDetailsAsync()launchBillingFlow() 를 입력으로 사용하는 ProductDetailsParams 버전을 사용하는 방법에 관한 자세한 내용은 이전 단계를 참고하세요.

제품 세부정보 쿼리

일회성 제품에 여러 혜택 또는 구매 옵션을 구성한 경우 ProductDetails 객체는 queryProductDetailsAsync() 메서드에서 반환된 일회성 제품당 두 개 이상의 사용 가능한 구입 및 (또는) 대여 구매 옵션을 포함할 수 있습니다. 각 ProductDetails 객체의 모든 대상 혜택 목록을 가져오려면 getOneTimePurchaseOfferDetailsList() 메서드를 사용합니다. 사용자가 대상인 혜택 및 구매 옵션만 이 목록의 일부로 반환됩니다. Your code onProductDetailsResponse() 메서드의 코드는 반환된 혜택을 처리해야 합니다.

결제 절차 시작

앱에서 구매 요청을 시작하려면 앱의 기본 스레드에서 launchBillingFlow() 메서드를 호출합니다. 이 메서드는 BillingFlowParams 호출에서 가져온 관련 ProductDetails 객체를 포함하는 queryProductDetailsAsync() 객체에 대한 참조를 가져옵니다. BillingFlowParams 객체를 만들려면 BillingFlowParams.Builder 클래스를 사용합니다. `BillingFlowParams` 객체를 만들 때 사용자가 선택한 혜택 에 해당하는 혜택 토큰을 설정해야 합니다.

다음 샘플은 여러 혜택이 있는 일회성 제품의 구매 흐름을 시작하는 방법을 보여줍니다.

자바

    
// An activity reference from which the billing flow will launch.
Activity activity = ...;
ImmutableList<ProductDetailsParams> productDetailsParamsList =
    ImmutableList.of(
        ProductDetailsParams.newBuilder()
             // retrieve a value for productDetails by calling queryProductDetailsAsync()
            .setProductDetails(productDetails)
            // to get an offer token, call
            // ProductDetails.getOneTimePurchaseOfferDetailsList() for a list of offers
            // that are available to the user
            .setOfferToken(selectedOfferToken)
            .build()
    );
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build();
// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
    
    

offerTokenOneTimePurchaseOfferDetails의 일부로 찾을 수 있습니다. 사용자에게 혜택을 표시할 때 oneTimePurchaseOfferDetails.getOfferToken() 메서드에서 가져올 수 있는 올바른 혜택 토큰으로 결제 절차 매개변수를 구성해야 합니다.

구매 옵션 및 혜택

구매 옵션을 사용하면 사용자에게 사용 권한이 부여되는 방식과 가격, 제품이 제공되는 리전을 정의할 수 있습니다. 하나의 제품에 여러 구매 옵션이 있을 수 있으며, 이는 제품을 판매하는 위치와 방법을 나타낼 수 있습니다.

Google Play는 일회성 제품에 다음 구매 옵션을 지원합니다.

  • 구입 구매 옵션
  • 대여 구매 옵션

혜택은 일회성 제품에 만들 수 있는 가격 책정 체계를 나타냅니다. 예를 들어 일회성 제품에 할인 혜택을 만들 수 있습니다.

Google Play는 일회성 제품에 다음 구매 혜택을 지원합니다.

  • 선주문 혜택 (구입 구매 옵션에서만 지원됨)
  • 할인 혜택 (구입 및 대여 구매 옵션 모두에서 지원됨)

구입 구매 옵션

구입 구매 옵션은 일회성 제품의 표준, 완전 구매를 나타냅니다. 새 모델을 지원하지 않는 이전 Play Billing Library (버전 7 이하) 흐름에서 이 구매 옵션을 사용할 수 있는지 나타내는 선택적 legacyCompatible 필드가 있습니다. 하위 호환성을 위해 하나 이상의 구입 구매 옵션을 기존 버전과 호환 가능한 것으로 표시해야 합니다.

구입 및 대여 구매 옵션을 모두 PBL과 통합하는 단계는 동일합니다. 구입 구매 옵션을 PBL과 통합하는 방법을 알아보려면 대여 구매 옵션을 PBL과 통합을 참고하세요.

대여 구매 옵션

대여 구매 옵션을 사용하면 사용자가 지정된 기간 동안 일회성 제품에 액세스할 수 있습니다. 대여 기간과 만료일을 지정할 수 있습니다. 이 문서에서는 대여 구매 옵션을 Play Billing Library (PBL)와 통합하는 단계를 설명합니다.

대여 구매 옵션을 PBL과 통합

이 섹션에서는 대여 구매 옵션을 Play Billing Library (PBL)와 통합하는 방법을 설명합니다. 이 섹션에서는 앱에 PBL 종속 항목 추가, BillingClient 초기화, Google Play 연결과 같은 초기 PBL 통합 단계를 잘 알고 있다고 가정합니다. 이 섹션에서는 대여 구매 옵션과 관련된 PBL 통합 측면에 중점을 둡니다.

대여 가능한 제품을 구성하려면 Play Developer API의 새 monetization.onetimeproducts 서비스 또는 Play Developer Console UI를 사용해야 합니다. 서비스를 사용하려면 REST API를 직접 호출하거나 자바 클라이언트 라이브러리를 사용하면 됩니다.

대여 옵션의 구매 흐름 시작

대여 혜택의 구매 흐름을 시작하려면 다음 단계를 따르세요.

  1. ProductDetails.oneTimePurchaseOfferDetails.getRentalDetails() 메서드를 사용하여 대여 구매 옵션 메타데이터를 가져옵니다.

    다음 샘플은 대여 구매 메타데이터를 가져오는 방법을 보여줍니다.

    자바

    billingClient.queryProductDetailsAsync(
    queryProductDetailsParams,
    new ProductDetailsResponseListener() {
      public void onProductDetailsResponse(
          BillingResult billingResult, QueryProductDetailsResult productDetailsResult) {
        // check billingResult
        // …
        // process productDetailsList returned by QueryProductDetailsResult
        for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) {
          for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails :
              productDetails.getOneTimePurchaseOfferDetailsList()) {
            // Checks if the offer is a rent purchase option.
            if (oneTimePurchaseOfferDetails.getRentalDetails() != null) {
              // process the returned RentalDetails
              OneTimePurchaseOfferDetails.RentalDetails rentalDetails =
                  oneTimePurchaseOfferDetails.getRentalDetails();
              // Get rental period in ISO 8601 format.
              String rentalPeriod = rentalDetails.getRentalPeriod();
              // Get rental expiration period in ISO 8601 format, if present.
              if (rentalDetails.getRentalExpirationPeriod() != null) {
                String rentalExpirationPeriod = rentalDetails.getRentalExpirationPeriod();
              }
              // Get offer token
                String offerToken = oneTimePurchaseOfferDetails.getOfferToken();
              // Get the associated purchase option ID
              if (oneTimePurchaseOfferDetails.getPurchaseOptionId() != null) {
                String purchaseOptionId = oneTimePurchaseOfferDetails.getPurchaseOptionId();
              }
            }
          }
        }
      }
    });
  2. 결제 절차를 시작합니다.

    앱에서 구매 요청을 시작하려면 앱의 기본 스레드에서 launchBillingFlow() 메서드를 호출합니다. 이 메서드는 BillingFlowParams 호출에서 가져온 관련 ProductDetails 객체를 포함하는 queryProductDetailsAsync() 객체에 대한 참조를 가져옵니다. BillingFlowParams 객체를 만들려면 BillingFlowParams.Builder 클래스를 사용합니다. `BillingFlowParams` 객체를 만들 때 사용자가 선택한 혜택에 해당하는 혜택 토큰을 설정해야 합니다. 사용자가 대여 구매 옵션을 사용할 수 있는 경우 RentalDetails 및 offerId가 포함된 혜택을 queryProductDetailsAsync()에서 받게 됩니다.

    다음 샘플은 결제 절차를 시작하는 방법을 보여줍니다.

    Kotlin

    // An activity reference from which the billing flow will be launched.
    val activity : Activity = ...;
    
    val productDetailsParamsList = listOf(
        BillingFlowParams.ProductDetailsParams.newBuilder()
            // retrieve a value for productDetails by calling queryProductDetailsAsync()
            .setProductDetails(productDetails)
            // Get the offer token:
            // a. For one-time products, call ProductDetails.getOneTimePurchaseOfferDetailsList()
            // for a list of offers that are available to the user.
            // b. For subscriptions, call ProductDetails.subscriptionOfferDetails()
            // for a list of offers that are available to the user.
            .setOfferToken(selectedOfferToken)
            .build()
    )
    
    val billingFlowParams = BillingFlowParams.newBuilder()
        .setProductDetailsParamsList(productDetailsParamsList)
        .build()
    
    // Launch the billing flow
    val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

    자바

    // An activity reference from which the billing flow will be launched.
    Activity activity = ...;
    
    ImmutableList<ProductDetailsParams> productDetailsParamsList =
        ImmutableList.of(
            ProductDetailsParams.newBuilder()
                 // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
                .setProductDetails(productDetails)
                // Get the offer token:
                // a. For one-time products, call ProductDetails.getOneTimePurchaseOfferDetailsList()
                // for a list of offers that are available to the user.
                // b. For subscriptions, call ProductDetails.subscriptionOfferDetails()
                // for a list of offers that are available to the user.
                .setOfferToken(selectedOfferToken)
                .build()
        );
    
    BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
        .setProductDetailsParamsList(productDetailsParamsList)
        .build();
    
    // Launch the billing flow
    BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

    offerTokenOneTimePurchaseOfferDetails의 일부로 찾을 수 있습니다. 사용자에게 혜택을 표시할 때 oneTimePurchaseOfferDetails.getOfferToken() 메서드에서 가져올 수 있는 올바른 혜택 토큰으로 결제 흐름 매개변수를 구성해야 합니다.

선주문 혜택

선주문을 사용하면 제품이 출시되기 전에 구매할 수 있도록 일회성 제품을 설정할 수 있습니다. 사용자가 제품을 선주문하면 출시일 전에 사용자가 선주문을 취소하지 않는 한 제품이 출시될 때 상품을 결제하는 데 동의하는 것으로 간주됩니다. 출시일에 구매자에게 요금이 청구되고 Google Play에서 상품이 출시되었다는 이메일 알림을 전송합니다.

이 문서에서는 선주문 구매 혜택을 Play Billing Library (PBL)와 통합하는 단계를 설명합니다.

선주문 혜택을 PBL과 통합

이 섹션에서는 선주문 혜택을 Play Billing Library (PBL)와 통합하는 방법을 설명합니다. 이 섹션에서는 앱에 PBL 종속 항목 추가, BillingClient 초기화, Google Play 연결과 같은 초기 PBL 통합 단계를 잘 알고 있다고 가정합니다. 이 섹션에서는 선주문 혜택과 관련된 PBL 통합 측면에 중점을 둡니다.

선주문 혜택의 구매 흐름 시작

선주문 혜택의 구매 흐름을 시작하려면 다음 단계를 따르세요.

  1. ProductDetails.oneTimePurchaseOfferDetails.getPreorderDetails() 메서드를 사용하여 선주문 혜택 메타데이터를 가져옵니다. 다음 샘플은 선주문 혜택 메타데이터를 가져오는 방법을 보여줍니다.

    자바

    billingClient.queryProductDetailsAsync(
    queryProductDetailsParams,
    new ProductDetailsResponseListener() {
      public void onProductDetailsResponse(
          BillingResult billingResult, QueryProductDetailsResult productDetailsResult) {
        // check billingResult
        // …
        // process productDetailsList returned by QueryProductDetailsResult
        for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) {
          for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails :
              productDetails.getOneTimePurchaseOfferDetailsList()) {
            // Checks if the offer is a preorder offer.
            if (oneTimePurchaseOfferDetails.getPreorderDetails() != null) {
              // process the returned PreorderDetails
              OneTimePurchaseOfferDetails.PreorderDetails preorderDetails =
                  oneTimePurchaseOfferDetails.getPreorderDetails();
              // Get preorder release time in millis.
              long preorderReleaseTimeMillis = preorderDetails.getPreorderReleaseTimeMillis();
              // Get preorder presale end time in millis.
              long preorderPresaleEndTimeMillis = preorderDetails.getPreorderPresaleEndTimeMillis();
              // Get offer ID
                String offerId = oneTimePurchaseOfferDetails.getOfferId();
              // Get the associated purchase option ID
              if (oneTimePurchaseOfferDetails.getPurchaseOptionId() != null) {
                String purchaseOptionId = oneTimePurchaseOfferDetails.getPurchaseOptionId();
              }
            }
          }
        }
      }
    });

  2. 결제 절차를 시작합니다.

    앱에서 구매 요청을 시작하려면 앱의 기본 스레드에서 launchBillingFlow() 메서드를 호출합니다. 이 메서드는 BillingFlowParams 호출에서 가져온 관련 ProductDetails 객체를 포함하는 queryProductDetailsAsync() 객체에 대한 참조를 가져옵니다. BillingFlowParams 객체를 만들려면 the BillingFlowParams.Builder class를 사용합니다. `BillingFlowParams` 객체를 만들 때 사용자가 선택한 혜택에 해당하는 혜택 토큰을 설정해야 합니다. 사용자가 선주문 혜택을 사용할 수 있는 경우 queryProductDetailsAsync() 메서드에서 PreorderDetails 및 offerId가 포함된 혜택을 받게 됩니다.

    다음 샘플은 결제 절차를 시작하는 방법을 보여줍니다.

    자바

    // An activity reference from which the billing flow will launch.
    Activity activity = ...;
    ImmutableList productDetailsParamsList =
        ImmutableList.of(
        ProductDetailsParams.newBuilder()
             // retrieve a value for productDetails by calling queryProductDetailsAsync()
            .setProductDetails(productDetails)
            // to get an offer token, call
            // ProductDetails.getOneTimePurchaseOfferDetailsList() for a list of offers
            // that are available to the user
            .setOfferToken(selectedOfferToken)
            .build()
    );
    BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build();
    // Launch the billing flow
    BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

    offerTokenOneTimePurchaseOfferDetails의 일부로 찾을 수 있습니다. 사용자에게 혜택을 표시할 때 oneTimePurchaseOfferDetails.getOfferToken() 메서드에서 가져올 수 있는 올바른 혜택 토큰으로 결제 흐름 매개변수를 구성해야 합니다.

할인 혜택

이 섹션에서는 일회성 제품에 할인 혜택을 구성하는 방법을 설명합니다.

일회성 제품 할인 혜택에서 구성할 수 있는 매개변수는 네 가지입니다.

  • 할인된 혜택 가격: 원래 가격에서 할인된 비율 또는 절대 가격에 관한 세부정보를 지정합니다.

  • 국가 또는 지역 대상: 국가 또는 지역에서 일회성 제품 혜택의 사용 가능 여부를 지정합니다.

  • 구매 한도 (선택사항): 사용자가 동일한 혜택을 사용할 수 있는 횟수를 결정할 수 있습니다. 사용자가 구매 한도를 초과하면 혜택을 사용할 수 없습니다.

  • 기간 한정 (선택사항): 혜택을 사용할 수 있는 기간을 지정합니다. 이 기간 외에는 혜택을 구매할 수 없습니다.

할인된 혜택 가격 정보 가져오기

할인된 혜택의 경우 제공되는 할인율 또는 정액 할인을 가져올 수 있습니다.

예 1: 할인된 혜택의 할인율 가져오기

다음 샘플은 할인된 혜택의 원래 정가와 할인율을 가져오는 방법을 보여줍니다. 할인율 정보는 할인된 혜택에만 반환됩니다.

자바

billingClient.queryProductDetailsAsync(
    queryProductDetailsParams,
    new ProductDetailsResponseListener() {
      public void onProductDetailsResponse(
          BillingResult billingResult, QueryProductDetailsResult productDetailsResult){
        // check billingResult
        // …
        // process productDetailsList returned by QueryProductDetailsResult
        for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) {
          for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails :
              productDetails.getOneTimePurchaseOfferDetailsList()) {
            long discountedOfferPriceMicros =
                oneTimePurchaseOfferDetails.getPriceAmountMicros();
            // process the returned fullPriceMicros and percentageDiscount.
            if (oneTimePurchaseOfferDetails.getFullPriceMicros() != null) {
              long fullPriceMicros = oneTimePurchaseOfferDetails.getFullPriceMicros();
            }
            if (oneTimePurchaseOfferDetails.getDiscountDisplayInfo() != null) {
              long percentageDiscount =
                  oneTimePurchaseOfferDetails
                      .getDiscountDisplayInfo()
                      .getPercentageDiscount();
            }
            // …
          }
        }
      }
    });
    
예 2: 할인된 혜택의 정액 할인 가져오기

다음 예는 할인된 혜택의 원래 정가와 정액 할인을 마이크로 단위로 가져오는 방법을 보여줍니다. 마이크로 단위의 정액 할인 정보는 할인된 혜택에만 반환됩니다. 할인 혜택에는 절대 할인 또는 할인율을 지정해야 합니다.

자바

billingClient.queryProductDetailsAsync(
    queryProductDetailsParams,
    new ProductDetailsResponseListener() {
      public void onProductDetailsResponse(
          BillingResult billingResult, QueryProductDetailsResult productDetailsResult) {
        // check billingResult
        // …
        // process productDetailsList returned by QueryProductDetailsResult
        for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) {
          for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails :
              productDetails.getOneTimePurchaseOfferDetailsList()) {
            long discountedOfferPriceMicros =
                oneTimePurchaseOfferDetails.getPriceAmountMicros();
            // process the returned fullPriceMicros and absolute DiscountAmountMicros.
            if (oneTimePurchaseOfferDetails.getFullPriceMicros() != null) {
              long fullPriceMicros = oneTimePurchaseOfferDetails.getFullPriceMicros();
            }
            if (oneTimePurchaseOfferDetails.getDiscountDisplayInfo() != null) {
              long discountAmountMicros =
                  oneTimePurchaseOfferDetails
                      .getDiscountDisplayInfo()
                      .getDiscountAmount()
                      .getDiscountAmountMicros();
            }
            // …
          }
        }
      }
    });
    

혜택의 유효 기간 가져오기

OneTimePurchaseOfferDetails.getValidTimeWindow() 메서드를 사용하여 혜택의 유효 기간을 가져올 수 있습니다. 이 객체에는 기간 시작 및 종료 시간이 밀리초 단위로 포함되어 있습니다.

다음 샘플은 혜택의 유효 기간을 가져오는 방법을 보여줍니다.

자바

billingClient.queryProductDetailsAsync(
    queryProductDetailsParams,
    new ProductDetailsResponseListener() {
      public void onProductDetailsResponse(
          BillingResult billingResult, QueryProductDetailsResult productDetailsResult) {
        // check billingResult
        // …
        // process productDetailsList returned by QueryProductDetailsResult
        for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) {
          for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails :
              productDetails.getOneTimePurchaseOfferDetailsList()) {
            if (oneTimePurchaseOfferDetails.getValidTimeWindow() != null) {
              // process the returned startTimeMillis and endTimeMillis.
              ValidTimeWindow validTimeWindow =
                  oneTimePurchaseOfferDetails.getValidTimeWindow();
              long startTimeMillis = validTimeWindow.getStartTimeMillis();
              long endTimeMillis = validTimeWindow.getEndTimeMillis();
              // …
            }
          }
        }
      }
    });
    

할인 혜택 수준에서 수량 제한

할인 혜택 수준에서 최대 수량 한도를 지정할 수 있으며, 이는 혜택 수준에서만 적용됩니다. 다음은 이를 설명하는 예입니다.

  1. Super screensavers에는 화면 보호기 제품에 대한 두 가지 혜택이 있습니다. 구매 옵션 화면 보호기와 할인 화면 보호기입니다.
    1. 구매 옵션 화면 보호기에는 수량 제한이 설정되어 있지 않습니다.
    2. 할인 화면 보호기의 혜택 수준 최대 허용 수량은 3으로 설정되어 있습니다.
  2. 화면 보호기 제품에는 제품 수준 최대 허용 수량이 없으므로 사용자는 이 제품을 무제한으로 구매할 수 있습니다.
  3. 사용자는 할인 화면 보호기를 1개 보유하고 있으며 할인 화면 보호기를 하나 더 구매할 계획입니다.
  4. 사용 가능한 혜택을 가져올 때 구매 옵션 화면 보호기의 LimitedQuantityInfo는 null이고 할인 화면 보호기의 남은 수량 값은 2입니다.

다음 샘플은 할인 혜택 수준에서 수량 제한을 가져오는 방법을 보여줍니다.

자바

billingClient.queryProductDetailsAsync(
    queryProductDetailsParams,
    new ProductDetailsResponseListener() {
      public void onProductDetailsResponse(
          BillingResult billingResult, QueryProductDetailsResult productDetailsResult) {
        // check billingResult
        // …
        // process productDetailsList returned by QueryProductDetailsResult
        for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) {
          for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails :
              productDetails.getOneTimePurchaseOfferDetailsList()) {
            if (oneTimePurchaseOfferDetails.getLimitedQuantityInfo() != null) {
              // process the returned maximumQuantity and remainingQuantity.
              LimitedQuantityInfo limitedQuantityInfo =
                  oneTimePurchaseOfferDetails.getLimitedQuantityInfo();
              int maximumQuantity = limitedQuantityInfo.getMaximumQuantity();
              int remainingQuantity = limitedQuantityInfo.getRemainingQuantity();
              // …
            }
          }
        }
      }
    });
    

사용자가 혜택의 최대 수량 사용을 모두 사용하면 getOneTimePurchaseOfferDetailsList() 메서드에서 혜택이 반환되지 않습니다.

사용 한도 계산

다음 예는 특정 할인 혜택의 수량 제한 정보를 가져오는 방법을 보여줍니다. 현재 사용자의 최대 허용 수량과 남은 수량을 가져올 수 있습니다. 수량 제한 기능은 소모성 및 비소모성 일회성 제품 혜택 모두에 적용됩니다. 이 기능은 혜택 수준에서만 지원됩니다.

Google Play는 설정한 최대 허용 수량에서 사용자가 보유한 수량을 빼서 남은 수량을 계산합니다. 사용자가 보유한 수량을 계산할 때 Google Play는 사용된 구매 또는 보류 중인 구매를 고려합니다. 취소, 환불 또는 지급 거부된 구매는 사용자가 보유한 수량에 포함되지 않습니다. 예:

  1. Super screensavers는 최대 허용 수량이 1인 할인 혜택을 설정하므로 사용자는 할인된 화면 보호기를 최대 1개까지 구매할 수 있습니다.

  2. 사용자가 할인된 화면 보호기 중 하나를 구매합니다. 그런 다음 사용자가 두 번째 할인된 화면 보호기를 구매하려고 하면 오류가 발생하고 PurchasesUpdatedListener가 ITEM_UNAVAILABLE 응답 코드를 가져옵니다.

  3. 사용자가 원래 구매한 할인된 화면 보호기의 환불을 요청하고 환불을 받습니다. 사용자가 할인된 화면 보호기 중 하나를 구매하려고 하면 구매가 완료됩니다.

국가 및 리전 대상

구매 옵션 혜택 또는 할인 혜택을 사용자에게 제공할 국가 또는 지역을 선택할 수 있습니다. Google Play는 Play 국가를 기준으로 사용자 대상 여부를 평가합니다. 혜택의 지역별 사용 가능 여부를 구성하면 사용자가 타겟팅된 국가 또는 지역에 있는 경우에만 getOneTimePurchaseOfferDetailsList()의 일부로 반환됩니다. 그렇지 않으면 queryProductDetailsAsync()를 호출할 때 반환되는 혜택 목록에 포함되지 않습니다.

혜택 태그

다음 샘플은 혜택과 연결된 혜택 태그를 가져오는 방법을 보여줍니다.

자바

    
billingClient.queryProductDetailsAsync(
    queryProductDetailsParams,
    new ProductDetailsResponseListener() {
      public void onProductDetailsResponse(
          BillingResult billingResult, QueryProductDetailsResult productDetailsResult) {
        // check billingResult
        // …
        // process productDetailsList returned by QueryProductDetailsResult
        for (ProductDetails productDetails : productDetailsResult.getProductDetailsList()) {
          for (OneTimePurchaseOfferDetails oneTimePurchaseOfferDetails :
              productDetails.getOneTimePurchaseOfferDetailsList()) {
            // process the returned offer tags.
            ImmutableList<String> offerTags =
                oneTimePurchaseOfferDetails.getOfferTagsList();
            // …
          }
        }
      }
    });
    
    

혜택 태그 상속

제품, 구매 옵션 또는 할인 혜택에 혜택 태그를 설정할 수 있습니다. 할인 혜택은 구매 옵션 혜택에서 혜택 태그를 상속합니다. 마찬가지로 제품 수준에서 혜택 태그가 지정된 경우 구매 옵션 혜택과 할인 혜택 모두 제품 혜택 태그를 상속합니다.

예를 들어 Super screensavers에는 화면 보호기 제품에 대한 두 가지 혜택이 있습니다. 구매 옵션 화면 보호기와 할인 화면 보호기입니다.

  • Super screensaver에는 제품 혜택 태그 SSProductTag가 있습니다.
  • 구매 옵션 화면 보호기에는 혜택 태그 SSPurchaseOptionTag가 있습니다.
  • 할인 화면 보호기에는 혜택 태그 SSDiscountOfferTag가 있습니다.

이 예에서 구매 옵션 혜택의 oneTimePurchaseOfferDetails.getOfferTagsList() 메서드는 SSProductTagSSPurchaseOptionTag를 반환합니다. 할인 혜택의 경우 메서드는 SSProductTag, SSPurchaseOptionTag, SSDiscountOfferTag를 반환합니다.