Wiele opcji zakupu i ofert dla produktów kupowanych raz

W tym dokumencie opisujemy integrację produktów kupowanych raz z Biblioteką płatności w Play. Wyjaśniamy też, jak zintegrować różne opcje zakupu i oferty związane z produktami kupowanymi raz.

Możesz skonfigurować wiele opcji zakupu i ofert dla produktów kupowanych raz. Możesz na przykład skonfigurować opcję zakupu i ofertę przedsprzedaży dla tego samego produktu kupowanego raz.

Wymagania wstępne

Aby skonfigurować wiele ofert dla produktów kupowanych raz, musisz użyć interfejsu API queryProductDetailsAsync(). Wycofany interfejs querySkuDetailsAsync() API nie jest obsługiwany. Informacje o tym, jak używać funkcji queryProductDetailsAsync(), oraz o wersji funkcji launchBillingFlow(), która przyjmuje jako dane wejściowe funkcję ProductDetailsParams, znajdziesz w instrukcjach migracji.

Wysyłanie zapytania dotyczącego szczegółów produktu

Jeśli masz skonfigurowanych wiele ofert lub opcji zakupu dla produktu kupowanego raz, obiekt ProductDetails zwracany przez metodę queryProductDetailsAsync() może mieć więcej niż 1 dostępną opcję zakupu lub wypożyczenia produktu kupowanego raz. Aby uzyskać listę wszystkich kwalifikujących się ofert dla każdego obiektu ProductDetails, użyj metody getOneTimePurchaseOfferDetailsList(). Na tej liście będą zwracane tylko oferty i opcje zakupu, do których użytkownik ma uprawnienia. Kod w metodzie onProductDetailsResponse() powinien obsługiwać zwrócone oferty.

Uruchamianie procesu płatności

Aby rozpocząć żądanie zakupu z poziomu aplikacji, wywołaj metodę launchBillingFlow() w głównym wątku aplikacji. Ta metoda przyjmuje odwołanie do obiektu BillingFlowParams, który zawiera odpowiedni obiekt ProductDetails uzyskany przez wywołanie metody queryProductDetailsAsync(). Aby utworzyć obiekt BillingFlowParams, użyj klasy BillingFlowParams.Builder. Pamiętaj, że podczas tworzenia obiektu BillingFlowParams musisz ustawić token oferty odpowiadający ofercie wybranej przez użytkownika.

Poniższy przykład pokazuje, jak uruchomić proces zakupu produktu kupowanego raz z wieloma ofertami:

Java

    
// 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);
    
    

offerToken znajdziesz w OneTimePurchaseOfferDetails. Gdy wyświetlasz ofertę użytkownikowi, skonfiguruj parametry procesu płatności za pomocą prawidłowego tokena oferty, który możesz uzyskać za pomocą metody oneTimePurchaseOfferDetails.getOfferToken().

Opcje zakupu i oferty

Opcja zakupu pozwala określić, w jaki sposób uprawnienie jest przyznawane użytkownikowi. Zawiera też informacje o jego cenie i regionie, w którym będzie dostępny. W przypadku jednego produktu może być dostępnych kilka opcji zakupu, które mogą reprezentować miejsce i sposób sprzedaży produktu.

Google Play obsługuje te opcje zakupu produktów kupowanych raz:

  • Opcja zakupu
  • Opcja wypożyczenia

Oferty to schemat cenowy, który możesz utworzyć dla produktów kupowanych raz. Możesz na przykład utworzyć ofertę rabatową dla produktu kupowanego raz.

Google Play obsługuje te oferty zakupu produktów kupowanych raz:

  • Oferta przedsprzedaży (obsługiwana tylko w przypadku opcji zakupu)
  • Oferta rabatowa (obsługiwana w przypadku opcji zakupu i wypożyczenia)

Opcja zakupu

Opcja zakupu „Kup” oznacza standardowy, bezpośredni zakup produktu kupowanego raz. Zawiera opcjonalne pole legacyCompatible, które wskazuje, czy ta opcja zakupu będzie dostępna w starszych procesach Biblioteki płatności w Play (wersja 7 lub starsza), które nie obsługują nowego modelu. Aby zapewnić zgodność wsteczną, co najmniej jedna opcja zakupu powinna być oznaczona jako zgodna ze starszymi wersjami.

Kroki integracji opcji zakupu i wypożyczenia z PBL są takie same. Aby dowiedzieć się, jak zintegrować opcję zakupu z Biblioteką płatności w Play, zapoznaj się z artykułem Integracja opcji wypożyczenia z Biblioteką płatności w Play.

Opcja wypożyczenia

Opcja zakupu wypożyczenia umożliwia użytkownikom dostęp do produktów kupowanych raz przez określony czas. Możesz określić okres wypożyczenia i jego datę wygaśnięcia. W tym dokumencie opisujemy czynności, które musisz wykonać, aby zintegrować opcję zakupu wypożyczenia z Biblioteką płatności w Play.

Integracja opcji wypożyczenia z Biblioteką płatności w Play

W tej sekcji opisano, jak zintegrować opcję zakupu wypożyczenia z Biblioteką płatności w Play. Zakładamy, że znasz początkowe kroki integracji PBL, takie jak dodanie zależności PBL do aplikacji, zainicjowanie BillingClientpołączenie z Google Play. Ta sekcja dotyczy aspektów integracji Biblioteki płatności w Play, które są specyficzne dla opcji wypożyczenia lub zakupu.

Aby skonfigurować produkty dostępne do wypożyczenia, musisz użyć nowej usługi monetization.onetimeproducts interfejsu Play Developer API lub interfejsu Konsoli Play Developer. Aby korzystać z usługi, możesz wywoływać bezpośrednio interfejs API REST lub używać biblioteki klienta Java.

Uruchamianie procesu zakupu opcji wypożyczenia

Aby uruchomić proces zakupu oferty wypożyczenia, wykonaj te czynności:

  1. Pobierz metadane opcji wypożyczenia za pomocą metody ProductDetails.oneTimePurchaseOfferDetails.getRentalDetails().

    Poniższy przykład pokazuje, jak uzyskać metadane zakupu wypożyczenia:

    Java

    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. Uruchom proces płatności.

    Aby rozpocząć żądanie zakupu z poziomu aplikacji, wywołaj metodę launchBillingFlow() z głównego wątku aplikacji. Ta metoda przyjmuje odwołanie do obiektu BillingFlowParams, który zawiera odpowiedni obiekt ProductDetails uzyskany przez wywołanie queryProductDetailsAsync(). Aby utworzyć obiekt BillingFlowParams, użyj klasy BillingFlowParams.Builder. Pamiętaj, że podczas tworzenia obiektu BillingFlowParams musisz ustawić token oferty odpowiadający ofercie wybranej przez użytkownika. Jeśli użytkownik kwalifikuje się do opcji zakupu wypożyczenia, otrzyma ofertę z parametrami RentalDetails i offerId w queryProductDetailsAsync().

    Poniższy przykład pokazuje, jak uruchomić proces płatności:

    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)

    Java

    // 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);

    offerToken znajdziesz w OneTimePurchaseOfferDetails. Gdy wyświetlasz ofertę użytkownikowi, skonfiguruj parametry procesu płatności, używając prawidłowego tokena oferty, który możesz uzyskać za pomocą metody oneTimePurchaseOfferDetails.getOfferToken().

Zamów w przedsprzedaży

Przedsprzedaż umożliwia skonfigurowanie produktów kupowanych raz, tak aby można było je kupić przed premierą. Gdy użytkownik zamówi produkt w przedsprzedaży, zgadza się zapłacić za niego w dniu premiery, chyba że anuluje zamówienie przed tą datą. W dniu premiery kupujący zostanie obciążony opłatą, a Google Play wyśle mu e-maila z powiadomieniem o premierze produktu.

W tym dokumencie opisujemy czynności, które musisz wykonać, aby zintegrować ofertę zakupu w przedsprzedaży z Biblioteką płatności w Play.

Integracja oferty przedsprzedaży z PBL

W tej sekcji opisujemy, jak zintegrować ofertę przedsprzedaży z biblioteką płatności w Google Play (PBL). Zakładamy, że znasz początkowe kroki integracji PBL, takie jak dodanie zależności PBL do aplikacji, zainicjowanie BillingClientpołączenie z Google Play. Ta sekcja dotyczy aspektów integracji PBL, które są specyficzne dla oferty przedsprzedaży.

Uruchamianie procesu zakupu w przypadku oferty przedsprzedaży

Aby uruchomić proces zakupu w przypadku oferty dotyczącej zamówienia w przedsprzedaży:

  1. Pobierz metadane oferty w przedsprzedaży za pomocą metody ProductDetails.oneTimePurchaseOfferDetails.getPreorderDetails(). Poniższy przykład pokazuje, jak uzyskać metadane oferty przedsprzedaży:

    Java

    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. Uruchom proces płatności.

    Aby rozpocząć żądanie zakupu z poziomu aplikacji, wywołaj metodę launchBillingFlow() w głównym wątku aplikacji. Ta metoda przyjmuje odwołanie do obiektu BillingFlowParams, który zawiera odpowiedni obiekt ProductDetails uzyskany przez wywołanie queryProductDetailsAsync(). Aby utworzyć obiekt BillingFlowParams, użyj BillingFlowParams.Builder class. Pamiętaj, że podczas tworzenia obiektu BillingFlowParams musisz ustawić token oferty odpowiadający ofercie wybranej przez użytkownika. Jeśli użytkownik kwalifikuje się do skorzystania z oferty przedsprzedaży, otrzyma ofertę z informacjami PreorderDetails i identyfikatorem offerId w metodzie queryProductDetailsAsync().

    Poniższy przykład pokazuje, jak uruchomić proces płatności:

    Java

    // 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);

    offerToken znajdziesz w OneTimePurchaseOfferDetails. Gdy wyświetlasz ofertę użytkownikowi, skonfiguruj parametry procesu płatności, używając prawidłowego tokena oferty, który możesz uzyskać za pomocą metody oneTimePurchaseOfferDetails.getOfferToken().

Rabaty

W tej sekcji opisujemy, jak skonfigurować oferty rabatowe dla produktów kupowanych jednorazowo.

W ofercie rabatowej na produkt kupowany raz możesz skonfigurować 4 różne parametry:

  • Cena promocyjna: określa szczegóły dotyczące rabatu procentowego lub rabatu w postaci konkretnej kwoty od pierwotnej ceny.

  • Kraje lub regiony, w których można korzystać z oferty: określa dostępność ofert produktów kupowanych raz w danym kraju lub regionie.

  • Limit zakupu (opcjonalnie): pozwala określić, ile razy użytkownik może wykorzystać tę samą ofertę. Jeśli użytkownik przekroczy limit zakupów, nie będzie mógł skorzystać z oferty.

  • Ograniczony czas (opcjonalny): określa okres, w którym oferta jest dostępna. Po upływie tego okresu oferta nie będzie dostępna.

Pobieranie informacji o cenie oferty z rabatem

W przypadku oferty z rabatem możesz pobrać procent rabatu lub oferowany rabat bezwzględny.

Przykład 1. Pobieranie rabatu procentowego z oferty z rabatem

Poniższy przykład pokazuje, jak uzyskać pierwotną pełną cenę oferty po rabacie i jej rabat procentowy. Pamiętaj, że informacje o rabacie procentowym są zwracane tylko w przypadku ofert z rabatem.

Java

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();
            }
            // …
          }
        }
      }
    });
    
Przykład 2. Pobieranie rabatu bezwarunkowego z oferty z rabatem

Poniższy przykład pokazuje, jak uzyskać pierwotną pełną cenę oferty z rabatem i jej bezwzględny rabat w mikrach. Pamiętaj, że informacje o rabacie bezwzględnym w mikrojednostkach są zwracane tylko w przypadku ofert z rabatem. W przypadku oferty rabatowej należy podać rabat bezwzględny lub procentowy.

Java

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();
            }
            // …
          }
        }
      }
    });
    

Pobieranie prawidłowego przedziału czasu oferty

Możesz użyć metody OneTimePurchaseOfferDetails.getValidTimeWindow(), aby uzyskać prawidłowe okno czasowe oferty. Ten obiekt zawiera czas rozpoczęcia i zakończenia przedziału czasu w milisekundach.

Poniższy przykład pokazuje, jak uzyskać prawidłowe okno czasowe oferty:

Java

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();
              // …
            }
          }
        }
      }
    });
    

Ograniczona liczba na poziomie oferty rabatowej

Maksymalny limit ilości możesz określić na poziomie oferty rabatowej, czyli jest on stosowany tylko na poziomie oferty. Oto przykład:

  1. Super screensavers ma 2 oferty wygaszacza ekranu: wygaszacz ekranu z opcją zakupu i wygaszacz ekranu ze zniżką.
    1. Wygaszacz ekranu z opcją zakupu nie ma skonfigurowanego limitu ilości.
    2. W wygaszaczu ekranu z rabatem maksymalna dozwolona liczba ofert jest ustawiona na 3.
  2. Wygaszacz ekranu nie ma maksymalnej dopuszczalnej liczby na poziomie produktu, więc użytkownicy mogą kupować nieograniczoną liczbę tego produktu.
  3. Użytkownik ma 1 wygaszacz ekranu z rabatem i planuje kupić kolejny z jego użyciem.
  4. Podczas pobierania dostępnych ofert wartość LimitedQuantityInfo dla wygaszacza ekranu z opcją zakupu jest równa null, a wartość pozostałej liczby dla wygaszacza ekranu z rabatem wynosi 2.

Poniższy przykład pokazuje, jak uzyskać ograniczoną ilość na poziomie oferty rabatowej:

Java

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();
              // …
            }
          }
        }
      }
    });
    

Gdy użytkownicy wykorzystają maksymalną liczbę wykorzystań oferty, metoda getOneTimePurchaseOfferDetailsList() nie zwróci tej oferty.

Obliczanie limitu wykorzystania

Poniższy przykład pokazuje, jak uzyskać informacje o ograniczonej ilości w przypadku określonej oferty rabatowej. Możesz uzyskać maksymalną dozwoloną liczbę i pozostałą liczbę dla bieżącego użytkownika. Pamiętaj, że funkcja ograniczonej ilości dotyczy zarówno ofert produktów jednorazowych konsumpcyjnych, jak i niekonsumpcyjnych. Ta funkcja jest obsługiwana tylko na poziomie oferty.

Google Play oblicza pozostałą liczbę, odejmując liczbę posiadanych przez użytkownika produktów od maksymalnej dozwolonej liczby, którą ustawisz. Podczas zliczania liczby posiadanych przez użytkownika produktów Google Play uwzględnia zrealizowane zakupy lub zakupy oczekujące. Zakupy, które zostały anulowane, zwrócone lub obciążone zwrotem środków, nie są wliczane do liczby posiadanych przez użytkownika produktów. Na przykład:

  1. Superwygaszacze ekranu oferują zniżkę na maksymalną dozwoloną liczbę, czyli 1 wygaszacz ekranu, więc użytkownicy mogą kupić maksymalnie 1 wygaszacz ekranu ze zniżką.

  2. Użytkownik kupuje jeden z wygaszaczy ekranu w promocyjnej cenie. Jeśli użytkownik spróbuje kupić drugi wygaszacz ekranu z rabatem, pojawi się błąd, a PurchasesUpdatedListener otrzyma kod odpowiedzi ITEM_UNAVAILABLE.

  3. Użytkownik prosi o zwrot środków za pierwotnie zakupiony wygaszacz ekranu w cenie promocyjnej i otrzymuje zwrot środków. Użytkownik próbuje kupić jeden z wygaszaczy ekranu w obniżonej cenie i zakup się powiedzie.

Kwalifikujące się kraje i regiony

Możesz wybrać kraje lub regiony, w których oferta opcji zakupu lub oferta rabatu będzie dostępna dla użytkowników. Google Play oceni, czy użytkownik kwalifikuje się do programu, na podstawie kraju w Google Play. Jeśli skonfigurujesz dostępność regionalną oferty, będzie ona zwracana w ramach parametru getOneTimePurchaseOfferDetailsList() tylko wtedy, gdy użytkownik znajduje się w kraju lub regionie objętym kierowaniem. W przeciwnym razie nie będzie ona częścią listy ofert zwracanych podczas wywoływania parametru queryProductDetailsAsync().

Tagi oferty

Poniższy przykład pokazuje, jak pobrać tagi oferty powiązane z ofertą.

Java

    
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();
            // …
          }
        }
      }
    });
    
    

Dziedziczenie tagów oferty

Tagi ofert możesz ustawić dla produktu, opcji zakupu lub oferty rabatowej. Oferty rabatowe dziedziczą tagi ofert z oferty opcji zakupu. Podobnie, jeśli tagi oferty są określone na poziomie produktu, zarówno oferta opcji zakupu, jak i oferta rabatu dziedziczą tagi oferty produktu.

Na przykład Super screensavers ma 2 oferty wygaszacza ekranu: wygaszacz ekranu z opcją zakupu i wygaszacz ekranu ze zniżką.

  • Wygaszacz ekranu Super ma tag oferty produktu SSProductTag.
  • Wygaszacz ekranu opcji zakupu zawiera tag oferty SSPurchaseOptionTag.
  • Wygaszacz ekranu z rabatem ma tag oferty SSDiscountOfferTag.

W tym przykładzie metoda oneTimePurchaseOfferDetails.getOfferTagsList() dla oferty opcji zakupu zwraca SSProductTagSSPurchaseOptionTag. W przypadku oferty rabatowej metoda zwraca wartości SSProductTag, SSPurchaseOptionTagSSDiscountOfferTag.