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

이 문서에서는 일회성 제품 (OTP)을 Play 결제 라이브러리와 통합하는 방법을 자세히 설명합니다. 또한 일회성 제품과 관련된 다양한 구매 옵션과 혜택을 통합하는 방법을 설명합니다.

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

기본 요건

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

제품 세부정보 쿼리

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

결제 흐름 시작

앱에서 구매 요청을 시작하려면 앱의 기본 스레드에서 launchBillingFlow() 메서드를 호출합니다. 이 메서드는 queryProductDetailsAsync() 호출에서 얻은 관련 ProductDetails 객체가 포함된 BillingFlowParams 객체를 참조합니다. 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 &quot;productDetails&quot; 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 결제 라이브러리(버전 7 이하) 흐름에서 사용할 수 있는지 여부를 나타내는 legacyCompatible 필드(선택사항)가 있습니다. 하위 호환성을 위해 하나 이상의 구매 옵션을 기존 버전과 호환 가능한 것으로 표시해야 합니다.

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

대여 구매 옵션

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

PBL과 대여 구매 옵션 통합

이 섹션에서는 대여 구매 옵션을 Play 결제 라이브러리 (PBL)와 통합하는 방법을 설명합니다. 앱에 PBL 종속 항목 추가, BillingClient 초기화, Google Play에 연결과 같은 초기 PBL 통합 단계에 익숙하다고 가정합니다. 이 섹션에서는 대여 구매 옵션과 관련된 PBL 통합 측면을 중점적으로 설명합니다.

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

대여 옵션의 구매 흐름 시작

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

  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() 메서드를 호출합니다. 이 메서드는 queryProductDetailsAsync() 호출에서 얻은 관련 ProductDetails 객체가 포함된 BillingFlowParams 객체를 참조합니다. BillingFlowParams 객체를 만들려면 BillingFlowParams.Builder 클래스를 사용하세요. BillingFlowParams 객체를 만들 때 사용자가 선택한 혜택에 해당하는 혜택 토큰을 설정해야 합니다. 사용자가 대여 구매 옵션을 사용할 수 있는 경우 queryProductDetailsAsync()에 RentalDetails 및 offerId가 포함된 혜택이 제공됩니다.

    다음 샘플은 결제 흐름을 실행하는 방법을 보여줍니다.

    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() 메서드에서 가져올 수 있는 올바른 혜택 토큰으로 결제 흐름 매개변수를 구성해야 합니다.

선주문 혜택

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

이 문서에서는 선주문 구매 혜택을 Play 결제 라이브러리 (PBL)와 통합하는 단계를 설명합니다.

PBL과 선주문 혜택 통합

이 섹션에서는 선주문 혜택을 Play 결제 라이브러리 (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() 메서드를 호출합니다. 이 메서드는 queryProductDetailsAsync() 호출에서 얻은 관련 ProductDetails 객체가 포함된 BillingFlowParams 객체를 참조합니다. BillingFlowParams 객체를 만들려면 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에는 화면 보호기 제품에 대한 2가지 혜택(구매 옵션 화면 보호기 및 할인 화면 보호기)이 있습니다.
    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. 슈퍼 화면 보호기는 최대 허용 수량이 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에는 화면 보호기 제품에 대한 두 가지 혜택인 구매 옵션 화면 보호기와 할인 화면 보호기가 있습니다.

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

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