Z tego dokumentu dowiesz się, jak zintegrować Bibliotekę płatności w Google Play z aplikacją, aby zacząć sprzedawać produkty.
Cykl życia zakupu
Oto typowy proces zakupu jednorazowego lub subskrypcji.
- Pokaż użytkownikowi, co może kupić.
- Uruchom proces zakupu, aby użytkownik mógł zaakceptować zakup.
- Zweryfikuj zakup na serwerze.
- Przekaż treści użytkownikowi.
- Potwierdź dostarczenie treści. W przypadku produktów konsumpcyjnych zużyj zakup, aby użytkownik mógł ponownie kupić produkt.
Subskrypcje odnawiają się automatycznie, dopóki nie zostaną anulowane. Subskrypcja może mieć te stany:
- Aktywna: użytkownik ma dobrą opinię i dostęp do subskrypcji.
- Anulowana: użytkownik anulował subskrypcję, ale nadal ma do niej dostęp, dopóki nie wygaśnie.
- W okresie prolongaty: u użytkownika wystąpił problem z płatnością, ale nadal ma on dostęp do subskrypcji, podczas gdy Google ponawia próbę obciążenia formy płatności.
- Wstrzymana: u użytkownika wystąpił problem z płatnością i nie ma on już dostępu do subskrypcji, podczas gdy Google ponawia próbę obciążenia formy płatności.
- Wstrzymany: użytkownik wstrzymał dostęp i nie będzie go miał, dopóki go nie wznowi.
- Wygasła: użytkownik anulował subskrypcję i stracił do niej dostęp. Po wygaśnięciu subskrypcji użytkownik jest uznawany 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 zainicjowanie 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.gradle aplikacji w ten sposób:
Dynamiczny
dependencies { def billing_version = "9.1.0" implementation "com.android.billingclient:billing:$billing_version" }
Kotlin
dependencies { val billing_version = "9.1.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ę współprogramów, które umożliwiają pisanie idiomatycznego kodu Kotlina podczas korzystania z Biblioteki płatności w Google Play. Aby uwzględnić te rozszerzenia w projekcie, dodaj do pliku build.gradle aplikacji tę zależność:
Dynamiczny
dependencies { def billing_version = "9.1.0" implementation "com.android.billingclient:billing-ktx:$billing_version" }
Kotlin
dependencies { val billing_version = "9.1.0" implementation("com.android.billingclient:billing-ktx:$billing_version") }
Inicjowanie BillingClient
Po dodaniu zależności od Biblioteki płatności w Google Play musisz zainicjować instancję 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 rozliczeniowych. Zwróć uwagę na te kwestie:
- Zalecamy, aby w danym momencie było otwarte tylko 1 aktywne połączenie
BillingClient. Pozwoli to uniknąć wielu wywołań zwrotnychPurchasesUpdatedListenerw przypadku pojedynczego zdarzenia. - Zalecamy zainicjowanie połączenia z BillingClient, gdy aplikacja zostanie uruchomiona lub przejdzie na pierwszy plan, aby mieć pewność, że zakupy będą przetwarzane na czas. Można to zrobić, używając interfejsu
ActivityLifecycleCallbackszarejestrowanego przezregisterActivityLifecycleCallbacksi nasłuchując zdarzenia onActivityResumed, aby zainicjować połączenie, gdy po raz pierwszy wykryjesz wznowienie aktywności. Więcej informacji o tym, dlaczego warto stosować tę sprawdzoną metodę, znajdziesz w sekcji poświęconej przetwarzaniu zakupów. Pamiętaj też, aby zakończyć połączenie, gdy aplikacja zostanie zamknięta.
Aby utworzyć BillingClient, użyj newBuilder. Do newBuilder() możesz przekazać dowolny kontekst, a BillingClient użyje go do uzyskania kontekstu aplikacji. Oznacza to, że nie musisz się martwić o wycieki pamięci. Aby otrzymywać aktualizacje dotyczące zakupów, musisz też wywołać metodę setListener, przekazując odwołanie do PurchasesUpdatedListener. Ten detektor otrzymuje aktualizacje dotyczące wszystkich zakupów 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, wywołaj startConnection. Proces połączenia jest asynchroniczny. Aby otrzymać wywołanie zwrotne po zakończeniu konfiguracji klienta i gdy będzie on gotowy do wysyłania kolejnych żądań, musisz zaimplementować interfejs BillingClientStateListener.
Jeśli nie masz włączonego automatycznego ponownego łączenia z usługą, musisz też zaimplementować logikę ponawiania prób, aby obsługiwać utracone połączenia z Google Play. Aby wdrożyć logikę ponawiania, zastąp metodę wywołania zwrotnego onBillingServiceDisconnected() i upewnij się, że BillingClient wywołuje metodę startConnection(), aby ponownie połączyć się z Google Play przed wysłaniem kolejnych żądań. Jeśli masz włączone automatyczne ponowne łączenie z usługą, możesz zaimplementować tę metodę jako operację bezczynności.
Poniższy przykład pokazuje, jak rozpocząć połączenie i sprawdzić, czy jest 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() { // If automatic service reconnection is enabled, this can be left empty (no-op) // because the library handles retries. You can still use this for non-retry // tasks like logging or updating the UI to reflect a disconnected state. // Otherwise, 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. // It's a good practice to query products after the connection is established. queryProductDetails(); } } @Override public void onBillingServiceDisconnected() { // Try to restart the connection on the next request to // Google Play by calling the startConnection() method. // This is automatically handled by the library when you call a method that requires a connection. } });
Automatyczne ponowne nawiązywanie połączenia
Wraz z wprowadzeniem metody enableAutoServiceReconnection() w BillingClient.Builder w wersji 8.0.0 Biblioteka płatności w Play może teraz automatycznie ponownie nawiązywać połączenie z usługą, jeśli wywołanie interfejsu API zostanie wykonane, gdy usługa jest odłączona. Może to prowadzić do zmniejszenia liczby odpowiedzi SERVICE_DISCONNECTED, ponieważ ponowne połączenie jest obsługiwane wewnętrznie przed wywołaniem interfejsu API.
Jak włączyć automatyczne ponowne łączenie
Podczas tworzenia instancji BillingClient użyj metody enableAutoServiceReconnection() w BillingClient.Builder, aby włączyć automatyczne ponowne łączenie.
Kotlin
val billingClient = BillingClient.newBuilder(context) .setListener(listener) .enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build()) .enableAutoServiceReconnection() // Add this line to enable reconnection .build()
Java
BillingClient billingClient = BillingClient.newBuilder(context)
.setListener(listener)
.enablePendingPurchases()
.enableAutoServiceReconnection() // Add this line to enable reconnection
.build();
Wyświetlanie produktów dostępnych do kupienia
Po nawiązaniu połączenia z Google Play możesz wysyłać zapytania o dostępne produkty i wyświetlać je użytkownikom.
Wysłanie zapytania o szczegóły produktu to ważny krok przed wyświetleniem produktów użytkownikom, ponieważ zwraca ono informacje o produkcie dostosowane do lokalizacji. W przypadku subskrypcji sprawdź, czy wyświetlanie produktu jest zgodne ze wszystkimi zasadami Google Play.
Aby wysłać zapytanie o szczegóły produktu kupowanego raz, wywołaj metodę queryProductDetailsAsync. Ta metoda może zwrócić kilka ofert na podstawie konfiguracji produktu kupowanego raz. Więcej informacji znajdziesz w artykule Wiele opcji zakupu i ofert w przypadku produktów kupowanych raz.
Aby obsłużyć wynik operacji asynchronicznej, musisz też określić detektor, który implementuje interfejs ProductDetailsResponseListener.
Następnie możesz zastąpić metodę onProductDetailsResponse, która powiadamia obiekt nasłuchujący o zakończeniu zapytania, jak w tym przykładzie:
Kotlin
val queryProductDetailsParams = QueryProductDetailsParams.newBuilder() .setProductList( listOf( Product.newBuilder() .setProductId("product_id_example") .setProductType(ProductType.SUBS) .build() ) ) .build() billingClient.queryProductDetailsAsync(queryProductDetailsParams) { billingResult, queryProductDetailsResult -> if (billingResult.responseCode == BillingResponseCode.OK) { for (productDetails in queryProductDetailsResult.productDetailsList) { // Process successfully retrieved product details here. } for (unfetchedProduct in queryProductDetailsResult.unfetchedProductList) { // Handle any unfetched products as appropriate. } } }
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,
QueryProductDetailsResult queryProductDetailsResult) {
if (billingResult.getResponseCode() == BillingResponseCode.OK) {
for (ProductDetails productDetails : queryProductDetailsResult.getProductDetailsList()) {
// Process successfully retrieved product details here.
}
for (UnfetchedProduct unfetchedProduct : queryProductDetailsResult.getUnfetchedProductList()) {
// Handle any unfetched products as appropriate.
}
}
}
}
)
Podczas wysyłania zapytania o szczegóły produktu przekaż instancję QueryProductDetailsParams, która określa listę ciągów identyfikatorów produktów utworzonych w Konsoli Google Play, wraz z ProductType. Wartość ProductType może wynosić ProductType.INAPP w przypadku produktów kupowanych raz lub ProductType.SUBS w przypadku subskrypcji.
Zapytanie z rozszerzeniami Kotlin
Jeśli używasz rozszerzeń Kotlina, możesz wysłać zapytanie o szczegóły produktu kupowanego raz, wywołując funkcję rozszerzenia queryProductDetails().
queryProductDetails() wykorzystuje współprogramy Kotlin, dzięki czemu nie musisz definiować osobnego detektora. Zamiast tego funkcja zawiesza działanie do momentu zakończenia 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 rzadkich przypadkach niektóre urządzenia nie obsługują aplikacji ProductDetails i queryProductDetailsAsync(), zwykle z powodu nieaktualnych wersji Usług Google Play. Aby zapewnić odpowiednią obsługę tego scenariusza, dowiedz się, jak korzystać z funkcji zgodności wstecznej, w przewodniku po migracji na Bibliotekę płatności w Play 7.
Przetwarzanie wyniku
Biblioteka płatności w Google Play przechowuje wyniki zapytania w obiekcie QueryProductDetailsResult. QueryProductDetailsResult zawiera List obiektów ProductDetails. Następnie możesz wywołać różne metody na każdym obiekcie ProductDetails na liście, aby wyświetlić odpowiednie informacje o pobranym produkcie kupowanym raz, takie jak jego cena czy opis. Aby wyświetlić dostępne szczegółowe informacje o produkcie, zapoznaj się z listą metod w klasie ProductDetails.
QueryProductDetailsResult zawiera też List obiektów UnfetchedProduct. Następnie możesz wysłać zapytanie o każdy obiekt UnfetchedProduct, aby uzyskać kod stanu odpowiadający przyczynie niepowodzenia pobierania.
Aby wyświetlić dostępne niepobrane informacje o produkcie, zapoznaj się z listą metod w klasie UnfetchedProduct.
Zanim zaoferujesz produkt na sprzedaż, sprawdź, czy użytkownik nie jest już jego właścicielem. Jeśli użytkownik ma w bibliotece produktów produkt konsumpcyjny, musi go zużyć, zanim będzie mógł go kupić ponownie.
Zanim zaoferujesz subskrypcję, sprawdź, czy użytkownik nie ma już subskrypcji. Pamiętaj też o tych kwestiach:
W przypadku subskrypcji metoda
queryProductDetailsAsync()zwraca szczegóły produktu objętego subskrypcją i maksymalnie 50 ofert dostępnych dla użytkownika na subskrypcję. Jeśli użytkownik spróbuje kupić ofertę, która nie jest dla niego dostępna (np. jeśli aplikacja wyświetla nieaktualną listę dostępnych ofert), Google Play poinformuje go o tym, że nie może skorzystać z oferty, i będzie on mógł zamiast tego kupić abonament podstawowy.W przypadku produktów kupowanych raz metoda
queryProductDetailsAsync()zwraca tylko oferty, z których użytkownik może skorzystać. Jeśli użytkownik spróbuje kupić ofertę, do której się nie kwalifikuje (np. jeśli osiągnął limit liczby zakupów), Google Play poinformuje go o tym, że nie może skorzystać z tej oferty, i będzie mógł wybrać inną opcję zakupu.
Uruchamianie procesu zakupu
Aby rozpocząć prośbę o zakup z 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.
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.getSubscriptionOfferDetails() // 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<BillingFlowParams.ProductDetailsParams> productDetailsParamsList = ImmutableList.of( 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.getSubscriptionOfferDetails() // 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. Pamiętaj, aby sprawdzić ten wynik i upewnić się, że podczas uruchamiania procesu zakupu nie wystąpiły błędy. BillingResponseCode o wartości OK oznacza udane uruchomienie.
Po udanym wywołaniu metody launchBillingFlow() system wyświetla ekran zakupu w Google Play. Rysunek 1 przedstawia ekran zakupu subskrypcji:
Google Play wywołuje metodę onPurchasesUpdated(), aby dostarczyć wynik operacji zakupu do detektora, który implementuje interfejs PurchasesUpdatedListener. Detektor jest określany za pomocą metody setListener() podczas inicjowania klienta.
Aby obsługiwać możliwe kody odpowiedzi, musisz zaimplementować interfejs 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 udanym zakupie wyświetli się ekran udanego zakupu w Google Play podobny do tego na rysunku 2.
Udany zakup generuje też token zakupu, który jest unikalnym identyfikatorem reprezentującym użytkownika i identyfikator produktu kupowanego raz. Aplikacje mogą przechowywać token zakupu lokalnie, ale zdecydowanie zalecamy przekazanie go na bezpieczny serwer backendu, gdzie można zweryfikować zakup i chronić się przed oszustwami. Ten proces został szczegółowo opisany w artykule Wykrywanie i przetwarzanie zakupów.
Użytkownik otrzyma 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 zakupu produktu kupowanego raz, a także w przypadku pierwszego zakupu subskrypcji i kolejnych cyklicznych automatycznych odnowień. Możesz użyć identyfikatora zamówienia, aby zarządzać zwrotami środków w Konsoli Google Play.
Wskazywanie ceny przygotowanej specjalnie dla klienta
Jeśli Twoja aplikacja może być rozpowszechniana wśród użytkowników w Unii Europejskiej, podczas wywoływania metody launchBillingFlow użyj metody setIsOfferPersonalized(), aby poinformować użytkowników, że cena produktu została spersonalizowana przy użyciu automatycznego podejmowania decyzji.
Aby ustalić, czy ceny, które oferujesz użytkownikom, są spersonalizowane w świetle tych przepisów, zapoznaj się z artykułem 6 (1) (ea) dyrektywy w sprawie praw konsumentów 2011/83/EU.
setIsOfferPersonalized() przyjmuje wartość logiczną. Gdy true, interfejs Google Play zawiera informacje o wykorzystaniu AI. Gdy false, interfejs pomija komunikat. Wartością domyślną jest false.
Więcej informacji znajdziesz w Centrum pomocy dla klientów.
Dołączanie identyfikatorów użytkowników
Gdy uruchomisz proces zakupu, aplikacja może dołączyć dowolne identyfikatory użytkownika, które masz dla użytkownika dokonującego zakupu, za pomocą obfuscatedAccountId lub obfuscatedProfileId. Przykładowym identyfikatorem może być zaciemniona wersja loginu użytkownika w Twoim systemie. Ustawienie tych parametrów może pomóc Google wykrywać oszustwa. Może też pomóc w zapewnieniu, że zakupy są przypisywane właściwym użytkownikom, jak opisano w sekcji Przyznawanie uprawnień użytkownikom.
Wykrywanie i przetwarzanie zakupów
Wykrywanie i przetwarzanie zakupów opisane w tej sekcji dotyczy wszystkich typów zakupów, w tym zakupów poza aplikacją, takich jak wykorzystanie promocji.
Aplikacja wykrywa nowe zakupy i zrealizowane oczekujące zakupy na jeden z tych sposobów:
- gdy metoda
onPurchasesUpdatedjest wywoływana w wyniku wywołania przez aplikację metodylaunchBillingFlow(jak opisano w poprzedniej sekcji) lub gdy aplikacja działa z aktywnym połączeniem z Biblioteką płatności, gdy zakup jest dokonywany poza aplikacją lub gdy oczekujący zakup zostanie sfinalizowany. Na przykład członek grupy rodzinnej zatwierdza oczekujący zakup na innym urządzeniu. - gdy aplikacja wywołuje metodę queryPurchasesAsync, aby sprawdzić zakupy użytkownika;
W przypadku #1 funkcja onPurchasesUpdated będzie automatycznie wywoływana w odniesieniu do nowych lub zrealizowanych zakupów, o ile aplikacja jest uruchomiona i ma aktywne połączenie z Biblioteką płatności w Google Play. Jeśli aplikacja nie jest uruchomiona lub nie ma aktywnego połączenia z biblioteką Płatności w Google Play, metoda onPurchasesUpdated nie zostanie wywołana. Pamiętaj, że zalecamy, aby aplikacja próbowała utrzymać aktywne połączenie, dopóki jest na pierwszym planie, aby otrzymywać aktualne informacje o zakupach.
W przypadku punktu 2 musisz wywołać metodę BillingClient.queryPurchasesAsync(), aby mieć pewność, że aplikacja przetworzy wszystkie zakupy. Zalecamy, aby zrobić to, gdy aplikacja pomyślnie nawiąże połączenie z Biblioteką płatności w Google Play (co jest zalecane, gdy aplikacja zostanie uruchomiona lub przejdzie na pierwszy plan, jak opisano w sekcji Inicjowanie BillingClient). Możesz to zrobić, wywołując metodę queryPurchasesAsync po otrzymaniu wyniku powodzenia dla onServiceConnected. Zastosowanie się do tej rekomendacji jest kluczowe w przypadku takich zdarzeń i sytuacji jak:
- Problemy z siecią podczas zakupu: użytkownik może dokonać zakupu i otrzymać potwierdzenie od Google, ale jego urządzenie traci połączenie sieciowe, 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 na innym.
- Obsługa zakupów dokonywanych poza aplikacją: niektóre zakupy, np. wykorzystanie promocji, mogą być dokonywane poza aplikacją.
- Obsługa zmian stanu zakupu: użytkownik może dokonać płatności za OCZEKUJĄCY zakup, gdy aplikacja nie jest uruchomiona, i oczekiwać potwierdzenia dokonania zakupu po otwarciu aplikacji.
- Zawieszone subskrypcje: subskrypcja może zostać zawieszona w trakcie cyklu życia subskrypcji. BillingClient.queryPurchasesAsync() zwróci zawieszone subskrypcje tylko wtedy, gdy parametr
includeSuspendedSubscriptionsjest ustawiony naQueryPurchasesParams.Builder. Zawieszone subskrypcje nie są zwracane wPurchasesUpdatedListener.
Gdy aplikacja wykryje nowy lub sfinalizowany zakup, powinna:
- Zweryfikuj zakup.
- przyznawać użytkownikom dostęp do treści po dokonaniu zakupu;
- Powiadom użytkownika.
- powiadomić Google, że aplikacja przetworzyła zrealizowane zakupy;
Te kroki zostały szczegółowo omówione w kolejnych sekcjach, a na końcu znajduje się sekcja z podsumowaniem wszystkich kroków.
Weryfikacja zakupu
Zanim przyznasz użytkownikowi korzyści, Twoja aplikacja powinna zawsze zweryfikować, czy zakupy są legalne. Możesz to zrobić, postępując zgodnie ze wskazówkami opisanymi w artykule Weryfikowanie zakupów przed przyznaniem uprawnień. Dopiero po zweryfikowaniu zakupu aplikacja powinna kontynuować jego przetwarzanie i przyznać uprawnienia użytkownikowi, co omówimy w następnej sekcji. Jeśli zakup nie przejdzie weryfikacji, sprawdzania kryteriów kwalifikacji lub kontroli nadużyć, zapoznaj się z artykułem Postępowanie w przypadku odrzuconych lub niezrealizowanych zakupów.
Przyznawanie uprawnień użytkownikowi
Gdy aplikacja zweryfikuje zakup, może nadal przyznawać uprawnienia użytkownikowi i powiadamiać go o tym. Zanim przyznasz uprawnienia, upewnij się, że aplikacja sprawdza, czy stan zakupu to PURCHASED. Jeśli zakup ma stan OCZEKUJĄCY, aplikacja powinna powiadomić użytkownika, że musi on jeszcze wykonać działania, aby sfinalizować zakup, zanim otrzyma uprawnienia.
Przyznaj uprawnienia tylko wtedy, gdy stan zakupu zmieni się z OCZEKUJĄCY na ZAKUPIONY.
Więcej informacji znajdziesz w artykule Obsługa oczekujących transakcji.
Jeśli do zakupu zostały dołączone identyfikatory użytkowników, jak opisano w sekcji Dołączanie identyfikatorów użytkowników, możesz je pobrać i użyć do przypisania zakupu do odpowiedniego użytkownika w systemie. Ta technika jest przydatna podczas uzgadniania zakupów, gdy aplikacja mogła utracić kontekst dotyczący tego, dla którego użytkownika jest dany zakup. Aby chronić się przed nadużyciami, Google Play zaleca zweryfikowanie tych identyfikatorów w bezpiecznym backendzie przed przyznaniem uprawnień. Więcej informacji znajdziesz w artykule Weryfikowanie zakupów przed przyznaniem uprawnień. Pamiętaj, że zakupy dokonane poza aplikacją nie będą miały ustawionych tych identyfikatorów. W takim przypadku aplikacja może przyznać uprawnienia zalogowanemu użytkownikowi lub poprosić go o wybranie preferowanego konta.
W przypadku zamówień w przedsprzedaży zakup ma stan OCZEKUJĄCY, dopóki nie nadejdzie czas premiery. Zakup w przedsprzedaży zostanie sfinalizowany w momencie premiery, a stan zmieni się na KUPIONY bez konieczności podejmowania dodatkowych działań.
Powiadamianie użytkownika
Po przyznaniu uprawnień użytkownikowi aplikacja powinna wyświetlić powiadomienie potwierdzające zakup. Dzięki powiadomieniu użytkownik nie ma wątpliwości, czy zakup został sfinalizowany. W przeciwnym razie mógłby przestać korzystać z aplikacji, skontaktować się z zespołem pomocy lub poskarżyć się w mediach społecznościowych. Pamiętaj, że aplikacja może wykryć aktualizacje zakupów w dowolnym momencie cyklu życia aplikacji. Na przykład rodzic zatwierdza oczekujący zakup na innym urządzeniu. W takim przypadku aplikacja może opóźnić powiadomienie użytkownika do odpowiedniego momentu. Oto kilka przykładów, w których opóźnienie byłoby odpowiednie:
- Podczas rozgrywki lub przerywników filmowych wyświetlenie wiadomości może rozpraszać użytkownika. W takim przypadku musisz powiadomić użytkownika po zakończeniu działania.
- podczas początkowego samouczka i konfiguracji gry przez użytkownika; Użytkownik mógł na przykład dokonać zakupu poza aplikacją przed jej zainstalowaniem. Zalecamy powiadomienie nowych użytkowników o nagrodzie natychmiast po uruchomieniu gry lub podczas początkowej konfiguracji. Jeśli aplikacja wymaga od użytkownika utworzenia konta lub zalogowania się przed przyznaniem mu uprawnień, zalecamy poinformowanie go o czynnościach, które musi wykonać, aby odebrać zakup. Jest to bardzo ważne, ponieważ jeśli aplikacja nie przetworzy zakupu, po 3 dniach środki zostaną zwrócone.
Google Play zaleca te mechanizmy powiadamiania użytkownika o zakupie:
- wyświetlić okno w aplikacji,
- Dostarczyć wiadomość do skrzynki odbiorczej w aplikacji i wyraźnie poinformować, że w skrzynce odbiorczej w aplikacji jest nowa wiadomość.
- Użyj powiadomienia systemu operacyjnego.
Powiadomienie powinno informować użytkownika o otrzymanej korzyści. Na przykład: „Kupiono 100 złotych monet!”. Dodatkowo, jeśli zakup był wynikiem korzyści z programu takiego jak Play Pass, aplikacja informuje o tym użytkownika. Na przykład „Otrzymano produkty! Właśnie otrzymujesz 100 klejnotów dzięki Play Pass. Kontynuuj”. Każdy program może zawierać wskazówki dotyczące zalecanego tekstu, który należy wyświetlać użytkownikom, aby poinformować ich o korzyściach.
Powiadamianie Google o przetworzeniu zakupu
Gdy aplikacja przyzna uprawnienia użytkownikowi i powiadomi go o pomyślnej transakcji, musi powiadomić Google, że zakup został pomyślnie przetworzony. W tym celu musisz potwierdzić zakup. Musisz to zrobić w ciągu 3 dni, aby środki nie zostały automatycznie zwrócone, a uprawnienia cofnięte. Proces potwierdzania różnych typów zakupów opisujemy w sekcjach poniżej.
Produkty do wykorzystania
W przypadku produktów konsumpcyjnych, jeśli Twoja aplikacja ma bezpieczny backend, zalecamy używanie metody Purchases.products:consume, aby niezawodnie wykorzystywać zakupy. Sprawdź, czy zakup nie został już wykorzystany, sprawdzając consumptionState w wyniku wywołania Purchases.products:get. Jeśli Twoja aplikacja działa tylko po stronie klienta i nie ma backendu, użyj metody 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 kupowanego raz, który odpowiada wejściowemu tokenowi zakupu, do ponownego zakupu. W przypadku consumeAsync() musisz też przekazać obiekt, który implementuje interfejs ConsumeResponseListener. Ten obiekt obsługuje wynik operacji wykorzystania. 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, jak wykorzystać produkt za pomocą Biblioteki płatności w Google Play i 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 = (billingResult, purchaseToken) -> { if (billingResult.getResponseCode() == BillingResponseCode.OK) { // Handle the success of the consume operation. } }; billingClient.consumeAsync(consumeParams, listener);
Produkty, które się nie zużywają
Jeśli Twoja aplikacja ma bezpieczny backend, do potwierdzania zakupów produktów niekonsumpcyjnych zalecamy używanie metody Purchases.products:acknowledge. Sprawdź, czy zakup nie został już potwierdzony, sprawdzając acknowledgementState w wyniku wywołania Purchases.products:get.
Jeśli Twoja aplikacja działa tylko po stronie 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, używając metody isAcknowledged() z Biblioteki 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 = billingClient val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.purchaseToken) val ackPurchaseResult = withContext(Dispatchers.IO) { client.acknowledgePurchase(acknowledgePurchaseParams.build()) }
Java
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) { if (!purchase.isAcknowledged()) { AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); billingClient.acknowledgePurchase(acknowledgePurchaseParams, (billingResult) -> { // Acknowledgment handled. }); } }
Subskrypcje
Subskrypcje są obsługiwane podobnie jak produkty niekonsumpcyjne. Jeśli to możliwe, użyj metody Purchases.subscriptions.acknowledge z interfejsu Google Play Developer API, aby niezawodnie potwierdzić zakup z bezpiecznego backendu. Sprawdź, czy zakup nie został wcześniej potwierdzony, sprawdzając pole acknowledgementState w zasobie zakupu z Purchases.subscriptions:get. W przeciwnym razie możesz potwierdzić subskrypcję za pomocą metody BillingClient.acknowledgePurchase() z Biblioteki płatności w Google Play po sprawdzeniu isAcknowledged(). Wszystkie początkowe zakupy subskrypcji muszą zostać potwierdzone. Odnowienia subskrypcji nie wymagają potwierdzenia. Więcej informacji o tym, kiedy należy potwierdzać subskrypcje, znajdziesz w temacie Sprzedaż subskrypcji.
Odrzucone lub niezrealizowane zakupy
Jeśli zakup nie przejdzie weryfikacji backendu, sprawdzania uprawnień użytkownika, kontroli pod kątem oszustw i nadużyć lub jeśli Twój system nie może przyznać uprawnień, nie przyznawaj ich i nie potwierdzaj ani nie wykorzystuj zakupu.
Niepotwierdzone zakupy są automatycznie zwracane i unieważniane po upływie okresu potwierdzenia, aby chronić konsumentów, ale nie polegaj na tym okresie, aby odrzucać zakupy. Jeśli okno potwierdzenia wygaśnie, zamówienie pozostanie w stanie niepotwierdzonym i będzie niejednoznaczne dla Google Play, które nie będzie w stanie odróżnić celowego odrzucenia przez dewelopera od przekroczenia limitu czasu przetwarzania backendu.
Zamiast tego natychmiast anuluj odrzucone zakupy i zwróć środki z poziomu backendu za pomocą interfejsu Google Play Developer API:
- Subskrypcje: wywołaj
purchases.subscriptionsv2.revokez"fullRefund": {}wrevocationContext. Spowoduje to natychmiastowe zakończenie subskrypcji, odebranie dostępu i rozpoczęcie procesu pełnego zwrotu środków. - Produkty kupowane raz: wywołaj metodę
orders.refundz parametremrevokeustawionym natrue, aby natychmiast zwrócić środki za zamówienie i unieważnić uprawnienia. Podczas wywoływania tej metody musisz przekazać identyfikator zamówienia, który możesz pobrać za pomocąPurchase.getOrderId()lubpurchases.productsv2.getproductpurchasev2. Nigdy nie dzwoń doconsumeAsync(),acknowledgePurchase(),Purchases.products:consumeaniPurchases.products:acknowledgew sprawie odrzuconych zakupów. - Zachowanie RTDN i unieważnionych zakupów: odwołania i zwroty środków zainicjowane przez dewelopera (
purchases.subscriptionsv2.revokeiorders.refundz parametremrevokeustawionym natrue) wywołują powiadomienia w czasie rzeczywistym dla deweloperów i są rejestrowane w Voided Purchases API (purchases.voidedpurchases.listz polem odpowiedzivoidedSourceustawionym na1dla dewelopera):- Subskrypcje: wysyła powiadomienie
SUBSCRIPTION_REVOKEDiVoidedPurchaseNotification. - Produkty kupowane raz: wysyła powiadomienie
VoidedPurchaseNotification(oraz powiadomienieONE_TIME_PRODUCT_CANCELED, jeśli aplikacja jest skonfigurowana w Konsoli Play tak, aby otrzymywać wszystkie powiadomienia o produktach kupowanych raz). - Wywołanie
orders.refundbez ustawieniarevokenatruepowoduje zwrot środków za zamówienie bez unieważnienia uprawnień i nie powoduje wysłania powiadomienia o unieważnieniu ani o anulowaniu zakupu. Więcej informacji znajdziesz w artykule Zarządzanie subskrypcjami i jednorazowymi zakupami.
- Subskrypcje: wysyła powiadomienie
Podsumowanie
Poniżej znajdziesz podsumowanie tych kroków.
Wyślij zakup do bezpiecznego backendu, aby zweryfikować zakupy przed przyznaniem uprawnień.
Zaktualizuj miejsce na dane uprawnień przy zakupie. Jeśli zakup jest w stanie OCZEKUJĄCY, upewnij się, że uprawnienie jest oznaczone jako oczekujące, a użytkownik nie otrzymuje jeszcze korzyści. Zalecamy wykonanie tego kroku w bezpiecznym backendzie. Można go połączyć z wywołaniem interfejsu API do backendu w kroku 1.
Powiadom użytkownika za pomocą odpowiedniego komunikatu (w razie potrzeby opóźnij powiadomienie, jak opisano wcześniej).
Powiadom Google, że zakup został przetworzony, wykonując czynności opisane w sekcji dotyczącej przetwarzania zakupów.
Aby sprawdzić, czy aplikacja prawidłowo wykonuje te czynności, możesz skorzystać z przewodnika po testowaniu.
Obsługa oczekujących transakcji
Google Play obsługuje oczekujące transakcje, czyli transakcje, które wymagają wykonania co najmniej 1 dodatkowej czynności między rozpoczęciem zakupu przez użytkownika a przetworzeniem formy płatności za ten zakup. Twoja aplikacja nie powinna przyznawać uprawnień do tego typu zakupów, dopóki Google nie powiadomi Cię, że forma płatności użytkownika została obciążona.
Na przykład użytkownik może zainicjować transakcję, wybierając sklep stacjonarny, w którym później zapłaci gotówką. Użytkownik otrzyma kod w powiadomieniu i e-mailu. Gdy użytkownik dotrze do sklepu stacjonarnego, może podać kod kasjerowi i zapłacić gotówką. Google powiadomi Ciebie i użytkownika o otrzymaniu płatności. Aplikacja może wtedy przyznać użytkownikowi uprawnienia.
Wywołaj enablePendingPurchases() w ramach inicjowania BillingClient, aby włączyć oczekujące transakcje w aplikacji. Aplikacja musi włączać i obsługiwać oczekujące transakcje w przypadku produktów kupowanych raz. Zanim dodasz obsługę, zapoznaj się z cyklem życia zakupu w przypadku oczekujących transakcji.
Gdy Twoja aplikacja otrzyma informację o nowym zakupie, czy to przez PurchasesUpdatedListener, czy w wyniku wywołania queryPurchasesAsync, użyj metody getPurchaseState(), aby określić, czy stan zakupu to PURCHASED czy PENDING. Uprawnienia należy przyznawać tylko wtedy, gdy stan ma wartość PURCHASED.
Jeśli aplikacja jest uruchomiona i masz aktywne połączenie z Biblioteką płatności w Play, gdy użytkownik dokona zakupu, metoda PurchasesUpdatedListener zostanie wywołana ponownie, a PurchaseState będzie mieć wartość PURCHASED. W tym momencie aplikacja może przetworzyć zakup, korzystając ze standardowej metody wykrywania i przetwarzania zakupów. Aplikacja powinna też wywoływać metodę queryPurchasesAsync() w metodzie onResume(), aby obsługiwać zakupy, które przeszły do stanu PURCHASED, gdy aplikacja nie była uruchomiona.
Gdy stan zakupu zmieni się z PENDING na PURCHASED, klient real_time_developer_notifications otrzyma 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 terminie. Pamiętaj, że zawsze możesz użyć interfejsu Google Play Developer API, aby sprawdzić bieżący stan zakupu.
Obsługa zakupów wielu sztuk
W Bibliotece płatności w Google Play w wersji 4.0 i nowszych Google Play umożliwia klientom kupowanie więcej niż 1 sztuki tego samego produktu kupowanego raz w ramach jednej transakcji przez określenie ilości w koszyku. Aplikacja powinna obsługiwać zakupy wielu sztuk i przyznawać uprawnienia na podstawie określonej liczby zakupionych produktów.
Aby uwzględniać zakupy wielu sztuk, logika udostępniania aplikacji musi sprawdzać liczbę sztuk produktu. Dostęp do pola quantity możesz uzyskać za pomocą jednego z tych interfejsów API:
getQuantity()z Biblioteki płatności w Google Play.Purchases.products.quantityz interfejsu Google Play Developer API
Po dodaniu logiki obsługującej zakupy wielu sztuk musisz włączyć tę funkcję dla odpowiedniego produktu na stronie zarządzania produktami kupowanymi raz w Konsoli Google Play.
Sprawdzanie konfiguracji płatności użytkownika
getBillingConfigAsync() podaje kraj, który użytkownik ma ustawiony w Google Play.
Po utworzeniu BillingClient możesz wysłać zapytanie o konfigurację płatności użytkownika. Poniższy fragment kodu pokazuje, jak wywołać getBillingConfigAsync(). Obsłuż odpowiedź, implementując interfejs BillingConfigResponseListener. Ten detektor otrzymuje aktualizacje dotyczące wszystkich zapytań o konfigurację rozliczeń zainicjowanych z poziomu aplikacji.
Jeśli zwrócony obiekt BillingResult nie zawiera błędów, możesz sprawdzić pole countryCode w obiekcie BillingConfig, aby uzyskać informacje o kraju 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 { // Handle errors } } } )
Java
GetBillingConfigParams getBillingConfigParams = GetBillingConfigParams.newBuilder().build(); billingClient.getBillingConfigAsync( getBillingConfigParams, (billingResult, billingConfig) -> { if (billingResult.getResponseCode() == BillingResponseCode.OK && billingConfig != null) { String countryCode = billingConfig.getCountryCode(); } else { // TODO: Handle errors } });