Integrowanie Biblioteki płatności w Google Play z aplikacją

Z tego tematu dowiesz się, jak zintegrować Bibliotekę płatności w Google Play z aplikacją, aby zacząć sprzedawać produkty.

Cykl życia zakupu

Oto typowy proces zakupu w przypadku produktu kupowanego raz lub subskrypcji.

  1. Pokaż użytkownikowi, co może kupić.
  2. Uruchom proces zakupu, aby użytkownik mógł zaakceptować zakup.
  3. Potwierdź zakup na serwerze.
  4. Przekazać użytkownikowi treści.
  5. potwierdzenie dostarczenia treści. W przypadku produktów konsumpcyjnych zużyj zakup, aby użytkownik mógł kupić produkt ponownie.

Subskrypcje są automatycznie odnawiane do momentu anulowania. Subskrypcja może przechodzić przez te stany:

  • Aktywna: użytkownik ma dostęp do subskrypcji.
  • Anulowano: użytkownik anulował subskrypcję, ale nadal ma dostęp do treści do daty wygaśnięcia.
  • W okresie prolongaty: użytkownik miał problem z płatnością, ale nadal ma dostęp, ponieważ Google próbuje ponownie obciążyć kartę.
  • W pauzie: użytkownik napotkał problem z płatnością i utracił dostęp, a Google próbuje ponownie obciążyć kartę.
  • Wstrzymana: użytkownik wstrzymał dostęp i nie ma do niego dostępu, dopóki nie wznowi dostępu.
  • Wygasła: użytkownik anulował subskrypcję i utracił do niej dostęp. Po upływie terminu ważności użytkownik jest uważany za utraconego.

Inicjowanie połączenia z Google Play

Pierwszym krokiem do integracji z systemem rozliczeniowym Google Play jest dodanie do aplikacji biblioteki Płatności w Google Play i inicjalizacja połączenia.

Dodawanie zależności Biblioteki płatności w Google Play

Dodaj zależność Biblioteki płatności w Google Play do pliku build.gradleaplikacji w ten sposób:

Odlotowe

dependencies {
    def billing_version = "7.0.0"

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

Kotlin

dependencies {
    val billing_version = "7.0.0"

    implementation("com.android.billingclient:billing:$billing_version")
}

Jeśli używasz Kotlina, moduł KTX Biblioteki płatności w Google Play zawiera rozszerzenia Kotlina i obsługę coroutine, które umożliwiają tworzenie kodu w języku Kotlin w odpowiednich miejscach w Bibliotece płatności w Google Play. Aby uwzględnić te rozszerzenia w projekcie, dodaj do pliku build.gradle aplikacji tę zależność:

Groovy

dependencies {
    def billing_version = "7.1.1"

    implementation "com.android.billingclient:billing-ktx:$billing_version"
}

Kotlin

dependencies {
    val billing_version = "7.1.1"

    implementation("com.android.billingclient:billing-ktx:$billing_version")
}

Inicjalizacja BillingClient

Po dodaniu zależności od Biblioteki płatności w Google Play musisz zainicjować wystąpienie BillingClient. BillingClient to główny interfejs do komunikacji między Biblioteką płatności w Google Play a resztą aplikacji. BillingClient udostępnia wygodne metody – zarówno synchroniczne, jak i asynchroniczne – do wielu typowych operacji związanych z płatnościami. Pamiętaj o tych kwestiach:

  • Zalecamy, aby w danym momencie mieć otwarte tylko jedno aktywne połączenie BillingClient, aby uniknąć wielokrotnego wywołania funkcji PurchasesUpdatedListener w przypadku jednego zdarzenia.
  • Zalecamy inicjowanie połączenia z BillingClient, gdy aplikacja jest uruchamiana lub przenoszona na pierwszy plan, aby mieć pewność, że zakupy są przetwarzane w odpowiedni sposób. Można to osiągnąć, używając ActivityLifecycleCallbacks zarejestrowanego przez registerActivityLifecycleCallbacks i nasłuchując na zdarzenie onActivityResumed, aby zainicjować połączenie, gdy po raz pierwszy wykryjesz wznowienie aktywności. Aby dowiedzieć się więcej o tym, dlaczego warto stosować tę sprawdzoną metodę, zapoznaj się z sekcją przetwarzanie zakupów. Pamiętaj też, aby zakończyć połączenie po zamknięciu aplikacji.

Aby utworzyć BillingClient, użyj newBuilder. Do funkcji newBuilder() możesz przekazać dowolny kontekst, a funkcja BillingClient użyje go do uzyskania kontekstu aplikacji. Oznacza to, że nie musisz się martwić wyciekami pamięci. Aby otrzymywać informacje o zakupach, musisz też zadzwonić na numer setListener, podając numer referencyjny PurchasesUpdatedListener. Ten odbiornik otrzymuje informacje o wszystkich zakupach w aplikacji.

Kotlin

private val purchasesUpdatedListener =
   PurchasesUpdatedListener { billingResult, purchases ->
       // To be implemented in a later section.
   }

private var billingClient = BillingClient.newBuilder(context)
   .setListener(purchasesUpdatedListener)
   // Configure other settings.
   .build()

Java

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // To be implemented in a later section.
    }
};

private BillingClient billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    // Configure other settings.
    .build();
.

Łączenie z Google Play

Po utworzeniu BillingClient musisz nawiązać połączenie z Google Play.

Aby połączyć się z Google Play, zadzwoń pod numer startConnection. Proces połączenia jest asynchroniczny, dlatego musisz zaimplementować BillingClientStateListener, aby otrzymywać połączenia zwrotne po zakończeniu konfiguracji klienta i jego gotowości do wysyłania kolejnych żądań.

Musisz też zaimplementować logikę ponownych prób, aby obsługiwać utracone połączenia z Google Play. Aby zaimplementować logikę ponownego próbowania, zastąpij metodę wywołania onBillingServiceDisconnected() i upewnij się, że metoda BillingClient wywołuje metodę startConnection(), aby ponownie połączyć się z Google Play, zanim prześle kolejne żądania.

Ten przykład pokazuje, jak utworzyć połączenie i sprawdzić, czy jest ono gotowe do użycia:

Kotlin

billingClient.startConnection(object : BillingClientStateListener {
    override fun onBillingSetupFinished(billingResult: BillingResult) {
        if (billingResult.responseCode ==  BillingResponseCode.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    override fun onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
})

Java

billingClient.startConnection(new BillingClientStateListener() {
    @Override
    public void onBillingSetupFinished(BillingResult billingResult) {
        if (billingResult.getResponseCode() ==  BillingResponseCode.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    @Override
    public void onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
});

wyświetlać produkty dostępne do kupienia;

Po nawiązaniu połączenia z Google Play możesz wysyłać zapytania dotyczące dostępnych produktów i wyświetlać je użytkownikom.

Wysyłanie zapytania o szczegóły produktów jest ważnym krokiem przed wyświetleniem produktów użytkownikom, ponieważ zwraca ono zlokalizowane informacje o produktach. W przypadku subskrypcji upewnij się, że wyświetlanie produktu przestrzega wszystkich zasad Google Play.

Aby zapytać o szczegóły usługi w aplikacji, zadzwoń pod numer queryProductDetailsAsync.

Aby obsłużyć wynik operacji asynchronicznej, musisz też określić listenera, który implementuje interfejs ProductDetailsResponseListener. Następnie możesz zastąpić parametr onProductDetailsResponse, który powiadamia listenera o zakończeniu zapytania, jak w tym przykładzie:

Kotlin

val queryProductDetailsParams =
    QueryProductDetailsParams.newBuilder()
        .setProductList(
            ImmutableList.of(
                Product.newBuilder()
                    .setProductId("product_id_example")
                    .setProductType(ProductType.SUBS)
                    .build()))
        .build()

billingClient.queryProductDetailsAsync(queryProductDetailsParams) {
    billingResult,
    productDetailsList ->
      // check billingResult
      // process returned productDetailsList
}

Java

QueryProductDetailsParams queryProductDetailsParams =
    QueryProductDetailsParams.newBuilder()
        .setProductList(
            ImmutableList.of(
                Product.newBuilder()
                    .setProductId("product_id_example")
                    .setProductType(ProductType.SUBS)
                    .build()))
        .build();

billingClient.queryProductDetailsAsync(
    queryProductDetailsParams,
    new ProductDetailsResponseListener() {
        public void onProductDetailsResponse(BillingResult billingResult,
                List<ProductDetails> productDetailsList) {
            // check billingResult
            // process returned productDetailsList
        }
    }
)

Podczas wysyłania zapytania o szczegóły produktu prześlij instancję QueryProductDetailsParams, która określa listę ciągów znaków identyfikatorów produktów utworzonych w Konsoli Google Play, wraz z wartością ProductType. ProductType może być równe ProductType.INAPP w przypadku produktów jednorazowych lub ProductType.SUBS w przypadku subskrypcji.

Zapytania z użyciem rozszerzeń Kotlin

Jeśli używasz rozszerzeń Kotlina, możesz wysłać zapytanie o szczegóły produktu w aplikacji, wywołując funkcję rozszerzenia queryProductDetails().

queryProductDetails() korzysta z korobon Kotlina, dzięki czemu nie musisz definiować osobnego odbiornika. Zamiast tego funkcja jest zawieszona do czasu zakończenia wykonywania zapytania, po czym możesz przetworzyć wynik:

suspend fun processPurchases() {
    val productList = listOf(
        QueryProductDetailsParams.Product.newBuilder()
            .setProductId("product_id_example")
            .setProductType(BillingClient.ProductType.SUBS)
            .build()
    )
    val params = QueryProductDetailsParams.newBuilder()
    params.setProductList(productList)

    // leverage queryProductDetails Kotlin extension function
    val productDetailsResult = withContext(Dispatchers.IO) {
        billingClient.queryProductDetails(params.build())
    }

    // Process the result.
}

W niektórych przypadkach niektóre urządzenia nie obsługują funkcji ProductDetailsqueryProductDetailsAsync(), zwykle z powodu przestarzałych wersji Usług Google Play. Aby zapewnić prawidłowe działanie w tym scenariuszu, dowiedz się, jak korzystać z funkcji zgodności wstecznej w przewodniku po migracji do Biblioteki płatności w Play 5.

Przetwarzanie wyniku

Biblioteka płatności w Google Play przechowuje wyniki zapytania w List obiektów ProductDetails. Następnie możesz wywoływać różne metody na każdym obiekcie ProductDetails na liście, aby wyświetlać odpowiednie informacje o produkcie w aplikacji, takie jak cena lub opis. Aby wyświetlić dostępne informacje o szczegółach produktu, zapoznaj się z listą metod w klasie ProductDetails.

Zanim zaoferujesz produkt do sprzedaży, sprawdź, czy użytkownik nie jest już jego właścicielem. Jeśli użytkownik ma produkt jednorazowy, który nadal znajduje się w bibliotece, musi go wykorzystać, zanim będzie mógł go ponownie kupić.

Zanim zaoferujesz subskrypcję, sprawdź, czy użytkownik nie ma już subskrypcji. Pamiętaj też o tym:

  • queryProductDetailsAsync() zwraca szczegóły subskrypcji i maksymalnie 50 ofert na subskrypcję.
  • queryProductDetailsAsync() zwraca tylko oferty, które są dostępne dla użytkownika. Jeśli użytkownik spróbuje kupić ofertę, do której nie kwalifikuje się (np. aplikacja wyświetla nieaktualną listę ofert), Google Play informuje go, że nie kwalifikuje się do skorzystania z oferty, i może zamiast tego kupić abonament podstawowy.
.

Uruchamianie procesu zakupu

Aby rozpocząć żądanie zakupu z 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.

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)
        // For One-time products, "setOfferToken" method shouldn't be called.
        // For subscriptions, to get an offer token, 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)
            // For one-time products, "setOfferToken" method shouldn't be called.
            // For subscriptions, to get an offer token, 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);

Metoda launchBillingFlow() zwraca jeden z kilku kodów odpowiedzi wymienionych w BillingClient.BillingResponseCode. Sprawdź ten wynik, aby upewnić się, że podczas uruchamiania procesu zakupu nie wystąpiły żadne błędy. Wartość BillingResponseCodeOK wskazuje, że uruchomienie było udane.

Po pomyślnym wywołaniu launchBillingFlow() system wyświetli ekran zakupu w Google Play. Rysunek 1 przedstawia ekran zakupu subskrypcji:

Ekran zakupu w Google Play zawiera subskrypcję, którą można kupić
Rysunek 1. Na ekranie zakupów w Google Play wyświetla się subskrypcja, którą można kupić.

Google Play wywołuje onPurchasesUpdated(), aby przekazać wynik operacji zakupu do detektorów, które implementują interfejs PurchasesUpdatedListener. Słuchacz jest określany za pomocą metody setListener() podczas inicjowania klienta.

Aby obsługiwać możliwe kody odpowiedzi, musisz zaimplementować onPurchasesUpdated(). Poniższy przykład pokazuje, jak zastąpić onPurchasesUpdated():

Kotlin

override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List<Purchase>?) {
   if (billingResult.responseCode == BillingResponseCode.OK && purchases != null) {
       for (purchase in purchases) {
           // Process the purchase as described in the next section.
       }
   } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) {
       // Handle an error caused by a user canceling the purchase flow.
   } else {
       // Handle any other error codes.
   }
}

Java

@Override
void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
    if (billingResult.getResponseCode() == BillingResponseCode.OK
        && purchases != null) {
        for (Purchase purchase : purchases) {
            // Process the purchase as described in the next section.
        }
    } else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) {
        // Handle an error caused by a user canceling the purchase flow.
    } else {
        // Handle any other error codes.
    }
}

Po pomyślnym zakupie wyświetla się ekran potwierdzenia zakupu w Google Play podobny do tego na rysunku 2.

Ekran potwierdzający zakup w Google Play
Rysunek 2. Ekran potwierdzenia zakupu w Google Play.

Po pomyślnym zakupie generowany jest też token zakupu, czyli unikalny identyfikator reprezentujący użytkownika i identyfikator produktu kupionego w aplikacji. Aplikacje mogą przechowywać token zakupu lokalnie, ale zdecydowanie zalecamy przekazanie go na bezpieczny serwer backendu, na którym możesz zweryfikować zakup i zabezpieczyć się przed oszustwem. Więcej informacji o tym procesie znajdziesz w artykule Wykrywanie i przetwarzanie zakupów.

Użytkownik otrzymuje też e-maila z potwierdzeniem transakcji zawierającym identyfikator zamówienia lub unikalny identyfikator transakcji. Użytkownicy otrzymują e-maila z unikalnym identyfikatorem zamówienia w przypadku każdego jednorazowego zakupu produktu, a także w przypadku początkowego zakupu subskrypcji i kolejnych automatycznych odnowień. Za pomocą identyfikatora zamówienia możesz zarządzać zwrotami środków w Konsoli Google Play.

Wskazać cenę indywidualną

Jeśli Twoja aplikacja może być rozpowszechniana w Unii Europejskiej, podczas wywoływania metody launchBillingFlow użyj metody setIsOfferPersonalized(), aby poinformować użytkowników, że cena produktu została spersonalizowana za pomocą automatycznego podejmowania decyzji.

Ekran zakupu w Google Play wskazujący, że cena została dostosowana do użytkownika.
Rysunek 3. Ekran zakupu w Google Play wskazujący, że cena została dostosowana do użytkownika.

Musisz zapoznać się z art. 6 (1) (ea) dyrektywy w sprawie praw konsumentów 2011/83/UE, aby określić, czy cena oferowana użytkownikom jest spersonalizowana.

setIsOfferPersonalized() przyjmuje dane wejściowe typu logicznego. Gdy true, interfejs Google Play zawiera informacje. Gdy false, interfejs pomija informacje. Wartością domyślną jest false.

Więcej informacji znajdziesz w Centrum pomocy dla konsumentów.

Dołączanie identyfikatorów użytkowników

Gdy uruchomisz proces zakupu, Twoja aplikacja może dołączyć dowolne identyfikatory użytkownika, które masz dla kupującego, za pomocą obfuscatedAccountId lub obfuscatedProfileId. Przykładem identyfikatora może być zaciemniona wersja loginu użytkownika w Twoim systemie. Ustawienie tych parametrów może pomóc Google wykrywać oszustwa. Dodatkowo może Ci pomóc w zapewnieniu, że zakupy są przypisywane do właściwego użytkownika, zgodnie z informacjami zawartymi w artykule Przekażanie uprawnień użytkownikom.

Wykrywanie i przetwarzanie zakupów

Wykrywanie i przetwarzanie zakupu opisane w tej sekcji dotyczy wszystkich rodzajów zakupów, w tym zakupów poza aplikacją, np. realizacji promocji.

Aplikacja wykrywa nowe zakupy i ukończone zakupy oczekujące na realizację w jeden z tych sposobów:

  1. Gdy funkcja onPurchasesUpdated jest wywoływana w wyniku wywołania funkcji launchBillingFlow przez Twoją aplikację (jak opisano w poprzedniej sekcji) lub gdy aplikacja jest uruchomiona z aktywnym połączeniem z biblioteką płatności, a dochodzi do zakupu poza aplikacją lub do ukończenia oczekującego zakupu. Na przykład członek rodziny zatwierdza oczekujący zakup na innym urządzeniu.
  2. Gdy aplikacja wywołuje metodę queryPurchasesAsync, aby zapytać o zakupy użytkownika.

W przypadku 1 funkcja onPurchasesUpdated będzie wywoływana automatycznie w przypadku nowych lub ukończonych zakupów, o ile aplikacja jest uruchomiona i ma aktywne połączenie z biblioteką Google Play Billing. Jeśli aplikacja nie działa lub nie ma aktywnego połączenia z Biblioteką płatności w Google Play, funkcja onPurchasesUpdated nie zostanie wywołana. Pamiętaj, że zalecamy, aby aplikacja starała się utrzymać aktywne połączenie tak długo, jak jest na pierwszym planie. Dzięki temu będzie otrzymywać aktualne informacje o zakupach.

W przypadku 2 musisz wywołać metodę BillingClient.queryPurchasesAsync(), aby mieć pewność, że Twoja aplikacja przetworzy wszystkie zakupy. Zalecamy wykonanie tego, gdy aplikacja nawiąże połączenie z Biblioteką płatności w Google Play (co powinno nastąpić, gdy aplikacja zostanie uruchomiona lub przejdzie na pierwszy plan, jak opisano w sekcji inicjalizacja BillingClient). Można to zrobić, wywołując metodę queryPurchasesAsync po otrzymaniu pomyślnego wyniku z metody onServiceConnected. Przestrzeganie tej rekomendacji jest kluczowe w przypadku zdarzeń i sytuacji takich jak:

  • Problemy z siecią podczas zakupu: użytkownik może dokonać zakupu i otrzymać potwierdzenie od Google, ale jego urządzenie traci połączenie z siecią, zanim urządzenie i aplikacja otrzymają powiadomienie o zakupie za pomocą PurchasesUpdatedListener.
  • Wiele urządzeń: użytkownik może kupić produkt na jednym urządzeniu, a potem oczekiwać, że będzie on widoczny po przełączeniu urządzenia.
  • Obsługa zakupów dokonywanych poza aplikacją: niektóre zakupy, np. wykorzystanie promocji, można dokonać poza aplikacją.
  • Obsługa stanów przejściowych zakupu: użytkownik może dokonać płatności za zakup w stanie ODDATKOWYM, gdy aplikacja nie jest uruchomiona, i oczekywać potwierdzenia, że zakup został sfinalizowany, gdy otworzy aplikację.

Gdy aplikacja wykryje nowy lub zakończony zakup, powinna:

  • Potwierdź zakup.
  • Udostępnianie treści użytkownikowi po dokonaniu zakupu.
  • Powiadomienie użytkownika.
  • Poinformuj Google, że Twoja aplikacja przetworzyła zakupy.

W następnych sekcjach znajdziesz szczegółowe instrukcje, a na końcu znajdziesz podsumowanie wszystkich czynności.

Weryfikacja zakupu

Przed przyznaniem korzyści użytkownikowi aplikacja powinna zawsze weryfikować zakupy, aby upewnić się, że są one legalne. Aby to zrobić, postępuj zgodnie z wytycznymi opisanymi w artykule Weryfikowanie zakupów przed przyznawaniem uprawnień. Dopiero po zweryfikowaniu zakupu aplikacja powinna przetworzyć zakup i przyznać użytkownikowi uprawnienia. Więcej informacji na ten temat znajdziesz w następnej sekcji.

Przyznawanie uprawnień użytkownikowi

Gdy aplikacja potwierdzi zakup, może przyznać użytkownikowi uprawnienia i poinformować go o tym. Zanim przyznasz uprawnienia, sprawdź, czy Twoja aplikacja sprawdza stan zakupu (PURCHASED). Jeśli zakup jest w stanie OCZEKIWANIE, aplikacja powinna poinformować użytkownika, że musi on jeszcze wykonać czynności, aby dokończyć zakup, zanim zostaną przyznane uprawnienia. Przyznaj uprawnienia tylko wtedy, gdy stan zakupu zmieni się z OCZEKIWANIE na POWODZENIE. Więcej informacji znajdziesz w artykule Zarządzanie transakcjami oczekującymi.

Jeśli do zakupu zostały dołączone identyfikatory użytkowników zgodnie z opisem w sekcji Dołączanie identyfikatorów użytkowników, możesz je pobrać i używać do przypisywania zakupów do właściwego użytkownika w Twoim systemie. Ta metoda jest przydatna podczas uzgadniania zakupów, gdy aplikacja utraciła kontekst dotyczący tego, dla którego użytkownika dokonano zakupu. Pamiętaj, że w przypadku zakupów dokonywanych poza aplikacją te identyfikatory nie są ustawiane. W takim przypadku aplikacja może przyznać uprawnienia zalogowanemu użytkownikowi lub poprosić go o wybranie preferowanego konta.

Powiadomienie użytkownika

Po przyznaniu uprawnień użytkownikowi aplikacja powinna wyświetlić powiadomienie potwierdzające zakup. Dzięki temu użytkownik nie będzie miał wątpliwości, czy zakup został prawidłowo zrealizowany. W przeciwnym razie może on przestać korzystać z aplikacji, skontaktować się z zespołem pomocy lub złożyć skargę w mediach społecznościowych. Pamiętaj, że Twoja aplikacja może wykrywać aktualizacje zakupów w dowolnym momencie cyklu życia aplikacji. Na przykład rodzic zatwierdza oczekujący zakup na innym urządzeniu. W takim przypadku Twoja aplikacja może opóźnić wysłanie powiadomienia do użytkownika do odpowiedniego czasu. Oto kilka przykładów sytuacji, w których opóźnienie jest uzasadnione:

  • Podczas dynamicznych momentów w grze lub przerywników wyświetlanie wiadomości może rozpraszać użytkownika. W takim przypadku musisz powiadomić użytkownika po zakończeniu części dotyczącej działania.
  • podczas początkowego samouczka i konfiguracji użytkownika. Użytkownik może na przykład dokonać zakupu poza aplikacją przed jej zainstalowaniem. Zalecamy poinformowanie nowych użytkowników o nagrodach natychmiast po uruchomieniu gry lub podczas początkowej konfiguracji konta. Jeśli Twoja aplikacja wymaga od użytkownika utworzenia konta lub zalogowania się, zanim przyzna mu uprawnienia, zalecamy poinformowanie go, jakie kroki musi wykonać, aby zrealizować zakup. Jest to bardzo ważne, ponieważ po 3 dniach od zakupu środki są zwracane, jeśli aplikacja nie przetworzyła zakupu.

W Google Play zalecamy stosowanie następujących mechanizmów powiadamiania użytkownika o zakupie:

  • wyświetlić okno dialogowe w aplikacji.
  • Wyślij wiadomość do okienka wiadomości w aplikacji i wyraźnie zaznacz, że w okienku jest nowa wiadomość.
  • Użyj komunikatu z powiadomienia systemu operacyjnego.

Powiadomienie powinno informować użytkownika o korzyściach, które otrzymał. Na przykład: „Kupiono 100 złotych monet”. Jeśli zakup został dokonany w ramach programu, takiego jak Play Pass, aplikacja powinna poinformować o tym użytkownika. Na przykład „Otrzymane produkty! Udało Ci się otrzymać 100 klejnotów dzięki Play Pass. Kontynuuj”. Każdy program może zawierać wskazówki dotyczące zalecanego tekstu, który ma być wyświetlany użytkownikom w celu przedstawienia korzyści.

Powiadomienie Google o przetworzeniu zakupu

Gdy aplikacja przyzna użytkownikowi uprawnienia i powiadomi go o udanej transakcji, musi powiadomić Google o pomyślnym przetworzeniu zakupu. Musisz to zrobić w ciągu 3 dni, aby mieć pewność, że zakup nie zostanie automatycznie zwrócony, a uprawnienia nie zostaną cofnięte. Proces potwierdzania różnych typów zakupów opisaliśmy w następnych sekcjach.

Produkty konsumpcyjne

Jeśli Twoja aplikacja ma bezpieczne zaplecze, zalecamy użycie Purchases.products:consume, aby zapewnić niezawodne wykorzystanie zakupów. Sprawdź, czy zakup nie został już wykorzystany, sprawdzając wartość consumptionState z wyniku wywołania funkcji Purchases.products:get. Jeśli Twoja aplikacja jest aplikacją tylko po stronie klienta i nie ma zaplecza, użyj consumeAsync() z Biblioteki płatności w Google Play. Obie metody spełniają wymagania dotyczące potwierdzenia i wskazują, że aplikacja przyznała użytkownikowi uprawnienia. Te metody umożliwiają też aplikacji udostępnienie produktu jednorazowego odpowiadającego tokenowi zakupu wejściowego do ponownego zakupu. W przypadku funkcji consumeAsync() musisz też przekazać obiekt, który implementuje interfejs ConsumeResponseListener. Ten obiekt obsługuje wynik operacji konsumpcji. Możesz zastąpić metodę onConsumeResponse(), którą Biblioteka płatności w Google Play wywołuje po zakończeniu operacji.

Poniższy przykład pokazuje wykorzystanie produktu za pomocą biblioteki Google Play Billing przy użyciu powiązanego tokena zakupu:

Kotlin

    val consumeParams =
        ConsumeParams.newBuilder()
            .setPurchaseToken(purchase.getPurchaseToken())
            .build()
    val consumeResult = withContext(Dispatchers.IO) {
        client.consumePurchase(consumeParams)
    }

Java

    ConsumeParams consumeParams =
            ConsumeParams.newBuilder()
                .setPurchaseToken(purchase.getPurchaseToken())
                .build();

    ConsumeResponseListener listener = new ConsumeResponseListener() {
        @Override
        public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
            if (billingResult.getResponseCode() == BillingResponseCode.OK) {
                // Handle the success of the consume operation.
            }
        }
    };

    billingClient.consumeAsync(consumeParams, listener);

Produkty niekonsumpcyjne

Aby potwierdzić zakupy niekonsumpcyjnych, jeśli aplikacja ma bezpieczny backend, zalecamy użycie interfejsu Purchases.products:acknowledge, aby niezawodnie potwierdzać zakupy. Sprawdź, czy zakup nie został wcześniej potwierdzony, sprawdzając wartość acknowledgementState z wyniku wywołania funkcji Purchases.products:get.

Jeśli Twoja aplikacja jest przeznaczona tylko dla klienta, użyj w niej metody BillingClient.acknowledgePurchase() z Biblioteki płatności w Google Play. Przed potwierdzeniem zakupu aplikacja powinna sprawdzić, czy został on już potwierdzony, korzystając z metody isAcknowledged() w Bibliotece płatności w Google Play.

Poniższy przykład pokazuje, jak potwierdzić zakup za pomocą Biblioteki płatności w Google Play:

Kotlin

val client: BillingClient = ...
val acknowledgePurchaseResponseListener: AcknowledgePurchaseResponseListener = ...

val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
    .setPurchaseToken(purchase.purchaseToken)
val ackPurchaseResult = withContext(Dispatchers.IO) {
     client.acknowledgePurchase(acknowledgePurchaseParams.build())
}

Java

BillingClient client = ...
AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ...

AcknowledgePurchaseParams acknowledgePurchaseParams =
                AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build();
 client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);

Subskrypcje

Subskrypcje są obsługiwane podobnie jak niekonsumowalne. Jeśli to możliwe, użyj interfejsu Purchases.subscriptions.acknowledge z interfejsu Play Developer API, aby niezawodnie potwierdzić zakup z bezpiecznego backendu. Sprawdź, czy zakup nie został wcześniej potwierdzony, sprawdzając wartość atrybutu acknowledgementState w zasobie zakupu z Purchases.subscriptions:get. W przeciwnym razie możesz potwierdzić subskrypcję za pomocą BillingClient.acknowledgePurchase() z biblioteki płatności Google Play po sprawdzeniu isAcknowledged(). Wszystkie wstępne zakupy subskrypcji muszą zostać potwierdzone. Odnowienia subskrypcji nie wymagają potwierdzenia. Więcej informacji o tym, kiedy należy potwierdzić subskrypcję, znajdziesz w artykule Sprzedaż subskrypcji.

W skrócie

Poniższy fragment kodu zawiera podsumowanie tych czynności.

Kotlin

fun handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchasesAsync or your
    // onPurchasesUpdated.
    Purchase purchase = ...;

    // Step 1: Send the purchase to your secure backend to verify the purchase
    // following
    // https://developer.android.com/google/play/billing/security#verify
.
    // Step 2: Update your entitlement storage with the purchase. If purchase is
    // in PENDING state then ensure the entitlement is marked as pending and the
    // user does not receive benefits yet. It is recommended that this step is
    // done on your secure backend and can combine in the API call to your
    // backend in step 1.

    // Step 3: Notify the user using appropriate messaging (delaying
    // notification if needed as discussed above).

    // Step 4: Notify Google the purchase was processed using the steps
    // discussed in the processing purchases section.
}

Java

void handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchasesAsync or your
    // onPurchasesUpdated.
    Purchase purchase = ...;

    // Step 1: Send the purchase to your secure backend to verify the purchase
    // following
    // https://developer.android.com/google/play/billing/security#verify

    // Step 2: Update your entitlement storage with the purchase. If purchase is
    // in PENDING state then ensure the entitlement is marked as pending and the
    // user does not receive benefits yet. It is recommended that this step is
    // done on your secure backend and can combine in the API call to your
    // backend in step 1.

    // Step 3: Notify the user using appropriate messaging (delaying
    // notification if needed as discussed above).

    // Step 4: Notify Google the purchase was processed using the steps
    // discussed in the processing purchases section.
}

Aby sprawdzić, czy aplikacja poprawnie wdrożyła te kroki, możesz postępować zgodnie z przewodnikiem po testowaniu.

Obsługa oczekujących transakcji

Google Play obsługuje transakcje oczekujące, czyli transakcje, które wymagają co najmniej 1 dodatkowego kroku między rozpoczęciem zakupu przez użytkownika a przetworzeniem formy płatności. Twoja aplikacja nie powinna przyznawać uprawnień do tych rodzajów zakupów, dopóki Google nie powiadomi Cię, że obciążono formę płatności użytkownika.

Użytkownik może na przykład rozpocząć transakcję, wybierając sklep stacjonarny, w którym zapłaci gotówką. Użytkownik otrzyma kod zarówno w powiadomieniu, jak i e-mailu. Gdy użytkownik przyjdzie do sklepu stacjonarnego, może zrealizować kod u kasjera i zapłacić gotówką. Google powiadomi Ciebie i użytkownika o otrzymaniu płatności. Twoja aplikacja może wtedy przyznać użytkownikowi uprawnienia.

W ramach inicjowania BillingClient wywołaj funkcję enablePendingPurchases(), aby umożliwić oczekujące transakcje w aplikacji. Aplikacja musi umożliwiać i obsługiwać oczekujące transakcje w przypadku produktów kupowanych raz. Zanim dodasz wsparcie, zapoznaj się z cyklem życia zakupu w przypadku oczekujących transakcji.

Gdy Twoja aplikacja otrzyma nowy zakup, czy to za pomocą interfejsu PurchasesUpdatedListener, czy też w wyniku wywołania interfejsu queryPurchasesAsync, użyj metody getPurchaseState(), aby określić, czy stan zakupu to PURCHASED czy PENDING. Upoważnienie należy przyznać tylko, gdy stan jest PURCHASED.

Jeśli aplikacja jest uruchomiona i ma aktywne połączenie z Biblioteką płatności w Play, gdy użytkownik dokona zakupu, ponownie zostanie wywołana funkcja PurchasesUpdatedListener, a wartość PurchaseState zmieni się na PURCHASED. W tym momencie Twoja aplikacja może przetworzyć zakup za pomocą standardowej metody wykrywania i przetwarzania zakupów. Aplikacja powinna też wywoływać metodę queryPurchasesAsync() w metodie onResume(), aby obsługiwać zakupy, które przeszły do stanu PURCHASED, gdy aplikacja była wyłączona.

Gdy zakup przechodzi z PENDING na PURCHASED, klient real_time_developer_notifications otrzymuje powiadomienie ONE_TIME_PRODUCT_PURCHASED lub SUBSCRIPTION_PURCHASED. Jeśli zakup zostanie anulowany, otrzymasz powiadomienie ONE_TIME_PRODUCT_CANCELED lub SUBSCRIPTION_PENDING_PURCHASE_CANCELED. Może się tak zdarzyć, jeśli klient nie dokona płatności w wymaganym czasie. Pamiętaj, że zawsze możesz użyć interfejsu Google Play Developer API, aby sprawdzić bieżący stan zakupu.

Obsługa zakupów o różnej ilości

Biblioteka Google Play umożliwia klientom zakup więcej niż 1 sztukę tego samego produktu w aplikacji w ramach jednej transakcji. Aby to zrobić, należy określić liczbę w koszyku zakupów. Funkcja jest obsługiwana w wersjach 4.0 i wyższych biblioteki Google Play Billing Library. Aplikacja powinna obsługiwać zakupy w wielokrotnościach i przyznawać uprawnienia na podstawie określonej liczby zakupów.

Aby umożliwić zakupy w większej ilości, logika obsługi aplikacji musi sprawdzać ilość produktu. Do pola quantity możesz uzyskać dostęp za pomocą jednego z tych interfejsów API:

Po dodaniu logiki do obsługi zakupów w wielokrotnościach musisz włączyć tę funkcję w przypadku odpowiedniego produktu na stronie zarządzania produktem w aplikacji w Konsoli Play.

Zapytanie o konfigurację płatności użytkownika

getBillingConfigAsync() określa kraj, którego użytkownik używa w Google Play.

Konfigurację płatności użytkownika możesz sprawdzić po utworzeniu BillingClient. Ten fragment kodu pokazuje, jak wywołać funkcję getBillingConfigAsync(). Obsługuj odpowiedź, wdrażając BillingConfigResponseListener. Ten odbiornik otrzymuje informacje o wszystkich zapytaniach dotyczących konfiguracji rozliczeń, które zostały zainicjowane w Twojej aplikacji.

Jeśli zwrócony obiekt BillingResult nie zawiera błędów, możesz sprawdzić pole countryCode w obiekcie BillingConfig, aby uzyskać kraj użytkownika w Google Play.

Kotlin

// Use the default GetBillingConfigParams.
val getBillingConfigParams = GetBillingConfigParams.newBuilder().build()
billingClient.getBillingConfigAsync(getBillingConfigParams,
    object : BillingConfigResponseListener {
        override fun onBillingConfigResponse(
            billingResult: BillingResult,
            billingConfig: BillingConfig?
        ) {
            if (billingResult.responseCode == BillingResponseCode.OK
                && billingConfig != null) {
                val countryCode = billingConfig.countryCode
                ...
            } else {
                // TODO: Handle errors
            }
        }
    })

Java

// Use the default GetBillingConfigParams.
GetBillingConfigParams getBillingConfigParams = GetBillingConfigParams.newBuilder().build();
billingClient.getBillingConfigAsync(getBillingConfigParams,
    new BillingConfigResponseListener() {
      public void onBillingConfigResponse(
          BillingResult billingResult, BillingConfig billingConfig) {
        if (billingResult.getResponseCode() == BillingResponseCode.OK
            && billingConfig != null) {
            String countryCode = billingConfig.getCountryCode();
            ...
         } else {
            // TODO: Handle errors
        }
      }
    });

przypomnienia o poruszeniach koszyka na ekranie głównym Gier Google Play (włączone domyślnie);

W przypadku deweloperów gier, którzy zarabiają dzięki mikropłatnościom, jedną z sposobów sprzedaży aktywnych w Konsoli Google Play kodów SKU jest funkcja przypomnienia o porzuceniu koszyka, która zachęca użytkowników do dokończenia wcześniej przerwanych zakupów podczas przeglądania Sklepu Google Play. Te zakupy są dokonywane poza aplikacją, w Grze Google Play w Sklepie Google Play.

Ta funkcja jest domyślnie włączona, aby pomóc użytkownikom w powrocie do miejsca, w którym przerwali, oraz pomóc deweloperom w maksymalizacji sprzedaży. Możesz jednak zrezygnować z tej funkcji w swojej aplikacji, przesyłając formularz rezygnacji z funkcji przypomnienia o porzuceniu koszyka. Sprawdzone metody zarządzania SKU w Konsoli Google Play znajdziesz w artykule Tworzenie produktu w aplikacji.

Poniższe obrazy pokazują przypomnienie o porzuconym koszyku wyświetlane w Sklepie Google Play:

na ekranie Sklepu Google Play wyświetla się prośba o dokonanie zakupu w przypadku wcześniej porzuconego zakupu
Rysunek 2. Na ekranie Sklepu Google Play wyświetla się prośba o dokonanie zakupu w przypadku wcześniej porzuconego zakupu.

na ekranie Sklepu Google Play wyświetla się prośba o dokonanie zakupu w przypadku wcześniej porzuconego zakupu
Rysunek 3. Na ekranie Sklepu Google Play wyświetla się prośba o dokonanie zakupu w przypadku wcześniej porzuconego zakupu.