In diesem Artikel wird beschrieben, wie du die Google Play Billing Library in deine App einbindest, um mit dem Verkauf von Produkten zu beginnen.
Laufzeit eines Kaufs
Im Folgenden sehen Sie einen typischen Kaufvorgang für einen einmaligen Kauf oder ein Abo.
- Zeigen Sie den Nutzern, was sie kaufen können.
- Starten Sie den Kaufvorgang, damit der Nutzer den Kauf akzeptieren kann.
- Bestätige den Kauf auf deinem Server.
- Stellen Sie dem Nutzer Inhalte zur Verfügung.
- Die Übermittlung der Inhalte bestätigen. Bei Verbrauchsgütern kannst du den gekauften Artikel noch einmal kaufen.
Abos werden so lange automatisch verlängert, bis sie gekündigt werden. Ein Abo kann die folgenden Status haben:
- Aktiv:Der Status des Nutzers ist einwandfrei und er hat Zugriff auf das Abo.
- Gekündigt:Der Nutzer hat gekündigt, hat aber noch bis zum Ablaufdatum Zugriff.
- Im Kulanzzeitraum:Der Nutzer hat ein Zahlungsproblem festgestellt, hat aber weiterhin Zugriff, während Google versucht, die Zahlungsmethode zu verwenden.
- Wartephase:Der Nutzer hat ein Zahlungsproblem festgestellt und hat keinen Zugriff mehr, während Google versucht, die Zahlungsmethode zu verwenden.
- Pausiert: Der Nutzer hat seinen Zugriff pausiert und erhält erst wieder Zugriff, wenn er fortgesetzt wird.
- Abgelaufen:Der Nutzer hat das Abo gekündigt und keinen Zugriff mehr auf das Abo. Der Nutzer gilt nach Ablauf als abgewandert.
Verbindung zu Google Play herstellen
Der erste Schritt zur Einbindung in das Abrechnungssystem von Google Play besteht darin, der App die Google Play Billing Library hinzuzufügen und eine Verbindung zu initialisieren.
Abhängigkeit der Google Play Billing Library hinzufügen
Füge die Google Play Billing Library-Abhängigkeit wie gezeigt in die Datei build.gradle
deiner App ein:
Cool
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") }
Wenn Sie Kotlin verwenden, enthält das Modul der Google Play Billing Library KTX Kotlin-Erweiterungen und unterstützt Koroutinen, mit denen Sie bei Verwendung der Google Play Billing Library idiomatischen Kotlin-Code schreiben können. Wenn Sie diese Erweiterungen in Ihr Projekt aufnehmen möchten, fügen Sie der Datei build.gradle
Ihrer Anwendung die folgende Abhängigkeit hinzu:
Cool
dependencies { def billing_version = "7.0.0" implementation "com.android.billingclient:billing-ktx:$billing_version" }
Kotlin
dependencies { val billing_version = "7.0.0" implementation("com.android.billingclient:billing-ktx:$billing_version") }
BillingClient initialisieren
Nachdem du eine Abhängigkeit von der Google Play Billing Library hinzugefügt hast, musst du eine BillingClient
-Instanz initialisieren. BillingClient
ist die Hauptschnittstelle für die Kommunikation zwischen der Google Play Billing Library und dem Rest deiner App. BillingClient
bietet praktische Methoden, sowohl synchron als auch asynchron, für viele gängige Abrechnungsvorgänge. Wir empfehlen dringend, jeweils eine aktive BillingClient
-Verbindung geöffnet zu haben, um mehrere PurchasesUpdatedListener
-Callbacks für ein einzelnes Ereignis zu vermeiden.
Verwenden Sie zum Erstellen von BillingClient
newBuilder()
. Sie können jeden Kontext an newBuilder()
übergeben und BillingClient
verwendet ihn, um einen Anwendungskontext abzurufen.
So müssen Sie sich keine Gedanken über Speicherlecks machen. Um Benachrichtigungen zu Käufen zu erhalten, musst du auch setListener()
aufrufen und einen Verweis auf einen PurchasesUpdatedListener
übergeben. Dieser Listener erhält Aktualisierungen zu allen Käufen in deiner App.
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();
Mit Google Play verbinden
Nachdem Sie ein BillingClient
erstellt haben, müssen Sie eine Verbindung zu Google Play herstellen.
Rufen Sie startConnection()
auf, um eine Verbindung zu Google Play herzustellen. Der Verbindungsvorgang ist asynchron und Sie müssen einen BillingClientStateListener
implementieren, um einen Callback zu erhalten, sobald die Einrichtung des Clients abgeschlossen ist und weitere Anfragen gesendet werden können.
Außerdem müssen Sie eine Wiederholungslogik implementieren, um unterbrochene Verbindungen zu Google Play zu verarbeiten.
Zum Implementieren einer Wiederholungslogik musst du die Callback-Methode onBillingServiceDisconnected()
überschreiben und BillingClient
die Methode startConnection()
aufrufen, um die Verbindung zu Google Play wiederherzustellen, bevor weitere Anfragen gesendet werden.
Das folgende Beispiel zeigt, wie Sie eine Verbindung starten und testen, ob sie einsatzbereit ist:
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. } });
Zum Kauf verfügbare Produkte anzeigen
Nachdem Sie eine Verbindung zu Google Play hergestellt haben, können Sie eine Abfrage nach Ihren verfügbaren Produkten stellen und sie Ihren Nutzern anzeigen lassen.
Das Abfragen von Produktdetails ist ein wichtiger Schritt, bevor Ihre Produkte Nutzern angezeigt werden, da lokalisierte Produktinformationen zurückgegeben werden. Achten Sie bei Abos darauf, dass Ihre Produktdarstellung allen Google Play-Richtlinien entspricht.
Rufen Sie queryProductDetailsAsync()
auf, um Details zu In-App-Produkten abzufragen.
Damit das Ergebnis des asynchronen Vorgangs verarbeitet wird, müssen Sie außerdem einen Listener angeben, der die ProductDetailsResponseListener
-Schnittstelle implementiert.
Sie können dann onProductDetailsResponse()
überschreiben, der den Listener benachrichtigt, wenn die Abfrage abgeschlossen ist, wie im folgenden Beispiel gezeigt:
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 } } )
Übergeben Sie beim Abfragen von Produktdetails eine Instanz von QueryProductDetailsParams
, die eine Liste von Produkt-ID-Strings angibt, die in der Google Play Console erstellt wurden, zusammen mit einem ProductType
. Die ProductType
kann entweder ProductType.INAPP
für Einmalkaufprodukte oder ProductType.SUBS
für Abos sein.
Abfragen mit Kotlin-Erweiterungen
Wenn Sie Kotlin-Erweiterungen verwenden, können Sie die Erweiterungsfunktion queryProductDetails()
aufrufen, um Details zu In-App-Produkten abzufragen.
queryProductDetails()
nutzt Kotlin-Koroutinen, sodass Sie keinen separaten Listener definieren müssen. Stattdessen hält die Funktion an, bis die Abfrage abgeschlossen ist. Anschließend können Sie das Ergebnis verarbeiten:
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.
}
In seltenen Fällen können ProductDetails
und queryProductDetailsAsync()
auf einigen Geräten nicht unterstützt werden. Das liegt meist an veralteten Versionen der Google Play-Dienste. Informationen zur Verwendung der Abwärtskompatibilitätsfunktionen findest du im Migrationsleitfaden für Play Billing Library 5, damit dieses Szenario korrekt unterstützt wird.
Ergebnis verarbeiten
Die Google Play Billing Library speichert die Abfrageergebnisse in einer List
mit ProductDetails
-Objekten. Anschließend kannst du für jedes ProductDetails
-Objekt in der Liste verschiedene Methoden aufrufen, um relevante Informationen zu einem In-App-Produkt wie Preis oder Beschreibung abzurufen. Die verfügbaren Produktdetailinformationen finden Sie in der Liste der Methoden in der Klasse ProductDetails
.
Bevor du einen Artikel zum Verkauf anbietest, solltest du prüfen, ob dem Nutzer der Artikel bereits gehört. Wenn der Nutzer ein Verbrauchsmaterial hat, das sich noch in seiner Artikelbibliothek befindet, muss er den Artikel zuerst verbrauchen, bevor er es noch einmal kaufen kann.
Bevor Sie ein Abo anbieten, prüfen Sie, ob der Nutzer bereits ein Abo hat. Beachten Sie außerdem Folgendes:
queryProductDetailsAsync()
gibt Details zu Abo-Produkten und maximal 50 Angebote pro Abo zurück.queryProductDetailsAsync()
gibt nur Angebote zurück, für die der Nutzer berechtigt ist. Wenn der Nutzer versucht, ein Angebot zu kaufen, für das er nicht berechtigt ist (z. B. wenn in der App eine veraltete Liste zulässiger Angebote angezeigt wird), teilt Google Play den Nutzer mit, dass er nicht berechtigt ist, und er kann stattdessen das Basis-Abo erwerben.
Kaufvorgang starten
Um eine Kaufanfrage von deiner App aus zu starten, rufe die Methode launchBillingFlow()
im Hauptthread deiner App auf. Diese Methode verweist auf ein BillingFlowParams
-Objekt, das das relevante ProductDetails
-Objekt enthält, das durch den Aufruf von queryProductDetailsAsync()
abgerufen wurde. Verwenden Sie zum Erstellen eines BillingFlowParams
-Objekts die Klasse 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 product, "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);
Die Methode launchBillingFlow()
gibt einen von mehreren in BillingClient.BillingResponseCode
aufgeführten Antwortcodes zurück. Überprüfe dieses Ergebnis, um sicherzustellen, dass beim Starten des Kaufvorgangs keine Fehler aufgetreten sind. Ein BillingResponseCode
von OK
bedeutet, dass der Start erfolgreich war.
Bei einem erfolgreichen Aufruf von launchBillingFlow()
zeigt das System den Google Play-Kaufbildschirm an. Abbildung 1 zeigt einen Kaufbildschirm für ein Abo:
![Auf dem Google Play-Kaufbildschirm wird ein Abo angezeigt, das zum Kauf angeboten wird](https://developer.android.google.cn/static/images/google/play/billing/purchase-screen.png?authuser=9&hl=de)
Google Play ruft onPurchasesUpdated()
auf, um das Ergebnis des Kaufvorgangs an einen Listener zu übergeben, der die PurchasesUpdatedListener
-Schnittstelle implementiert. Der Listener wird mit der Methode setListener()
bei der Initialisierung des Clients angegeben.
Sie müssen onPurchasesUpdated()
implementieren, um mögliche Antwortcodes zu verarbeiten. Das folgende Beispiel zeigt, wie onPurchasesUpdated()
überschrieben wird:
Kotlin
override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List<Purchase>?) { if (billingResult.responseCode == BillingResponseCode.OK && purchases != null) { for (purchase in purchases) { handlePurchase(purchase) } } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) { // Handle an error caused by a user cancelling 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) { handlePurchase(purchase); } } else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) { // Handle an error caused by a user cancelling the purchase flow. } else { // Handle any other error codes. } }
Nach einem erfolgreichen Kauf wird bei Google Play ein Bildschirm für den Kaufabschluss angezeigt, der Abbildung 2 ähnelt.
![Google Play-Kaufbestätigungsbildschirm](https://developer.android.google.cn/static/images/google/play/billing/purchase-success.png?authuser=9&hl=de)
Bei einem erfolgreichen Kauf wird auch ein Kauftoken generiert. Dabei handelt es sich um eine eindeutige Kennung, die den Nutzer und die Produkt-ID des gekauften In-App-Produkts darstellt. Ihre Apps können das Kauftoken lokal speichern. Wir empfehlen jedoch, das Token an Ihren sicheren Backend-Server weiterzugeben, damit Sie den Kauf dann prüfen und vor Betrug schützen können. Dieser Vorgang wird im folgenden Abschnitt näher beschrieben.
Der Nutzer erhält außerdem per E-Mail einen Beleg der Transaktion, der eine Bestell-ID oder eine eindeutige ID der Transaktion enthält. Nutzer erhalten für jeden einmaligen Produktkauf sowie für den ersten Abokauf und alle nachfolgenden automatischen Verlängerungen eine E-Mail mit einer eindeutigen Bestell-ID. Mithilfe der Bestell-ID kannst du Erstattungen in der Google Play Console verwalten.
einen personalisierten Preis angeben,
Wenn deine App an Nutzer in der Europäischen Union vertrieben werden kann, kannst du Nutzern mithilfe der Methode setIsOfferPersonalized()
mitteilen, dass der Preis eines Artikels durch automatisierte Entscheidungsfindung personalisiert wurde.
![Auf dem Google Play-Kaufbildschirm wird angezeigt, dass der Preis für den Nutzer angepasst wurde.](https://developer.android.google.cn/static/images/google/play/billing/personalized-pricing.png?authuser=9&hl=de)
Sie müssen Art. 6 (1) (ea) CRD der Richtlinie 2011/83/EU zu Verbraucherrechten zur Bestimmung, ob der Preis, den Sie Nutzern anbieten, personalisiert wird.
setIsOfferPersonalized()
verwendet eine boolesche Eingabe. Wenn true
, enthält die Play-UI die Offenlegung. Bei false
wird die Offenlegung in der Benutzeroberfläche weggelassen. Der Standardwert ist false
.
Weitere Informationen finden Sie in der Hilfe für Verbraucher.
Käufe werden verarbeitet
Sobald ein Nutzer einen Kauf abgeschlossen hat, muss dieser Kauf in Ihrer App verarbeitet werden.
In den meisten Fällen wird deine App über die PurchasesUpdatedListener
über Käufe benachrichtigt. Es gibt jedoch Fälle, in denen deine App auf Käufe aufmerksam wird, indem du BillingClient.queryPurchasesAsync()
aufrufst, wie unter Käufe abrufen beschrieben.
Wenn du einen Client für Entwicklerbenachrichtigungen in Echtzeit in deinem sicheren Back-End verwendest, kannst du neue Käufe auch registrieren, indem du eine subscriptionNotification
- oder oneTimeProductNotification
-Benachrichtigung über einen neuen Kauf erhältst. Rufen Sie nach Erhalt dieser Benachrichtigungen die Google Play Developer API auf, um den vollständigen Status abzurufen und Ihren eigenen Back-End-Status zu aktualisieren.
In Ihrer App sollte ein Kauf folgendermaßen verarbeitet werden:
- Bestätigen Sie den Kauf.
- Nutzern Inhalte zur Verfügung stellen und deren Übermittlung bestätigen Sie können den Artikel als gebraucht markieren, damit der Nutzer ihn noch einmal kaufen kann.
Für die Bestätigung eines Kaufs muss der Kaufstatus PURCHASED
sein. Wenn der Kauf den Status PENDING
hat, solltest du den Kauf wie unter Ausstehende Transaktionen verarbeiten beschrieben verarbeiten. Bei Käufen, die du über onPurchasesUpdated()
oder queryPurchasesAsync()
erhältst, solltest du den Kauf zusätzlich bestätigen, um seine Legitimität sicherzustellen, bevor deine App die Berechtigung erteilt. Informationen zur ordnungsgemäßen Bestätigung eines Kaufs findest du unter Käufe vor dem Gewähren von Berechtigungen prüfen.
Sobald du den Kauf bestätigt hast, kann dem Nutzer über deine App die Berechtigung erteilt werden. Das mit dem Kauf verknüpfte Nutzerkonto kann anhand des ProductPurchase.obfuscatedExternalAccountId
identifiziert werden, der von Purchases.products:get
für In-App-Produktkäufe und dem SubscriptionPurchase.obfuscatedExternalAccountId
von Purchases.subscriptions:get
für Abos auf der Serverseite oder mit obfuscatedAccountId
von Purchase.getAccountIdentifiers()
auf Clientseite zurückgegeben wird, wenn auf [19/2] festgelegt wurde.setObfuscatedAccountId
Nachdem die Berechtigung gewährt wurde, muss Ihre App den Kauf bestätigen. Mit dieser Bestätigung wird Google Play mitgeteilt, dass du eine Berechtigung für den Kauf gewährt hast.
Wie die Berechtigung gewährt und der Kauf bestätigt wird, hängt davon ab, ob es sich beim Kauf um ein Verbrauchsmaterial, ein nicht konsumierbares Produkt oder ein Abo handelt.
Verbrauchsgüter
Wenn deine App ein sicheres Back-End für Verbrauchsgüter hat, empfehlen wir die Verwendung von Purchases.products:consume
, um Käufe zuverlässig abzuschließen. Prüfe, ob der Kauf bereits verbraucht wurde. Prüfe dazu consumptionState
aus dem Ergebnis des Aufrufs von Purchases.products:get
. Wenn deine App nur Client ohne Back-End ist, verwende consumeAsync()
aus der Google Play Billing Library. Beide Methoden erfüllen die Anforderung zur Bestätigung und zeigen an, dass Ihre App dem Nutzer eine Berechtigung gewährt hat.
Mit diesen Methoden kann Ihre Anwendung außerdem das einmalige Produkt, das dem eingegebenen Kauftoken entspricht, zum erneuten Kauf zur Verfügung stellen. Bei consumeAsync()
müssen Sie außerdem ein Objekt übergeben, das die Schnittstelle ConsumeResponseListener
implementiert. Dieses Objekt verarbeitet das Ergebnis des Verbrauchsvorgangs. Du kannst die Methode onConsumeResponse()
überschreiben, die von der Google Play Billing Library nach Abschluss des Vorgangs aufgerufen wird.
Das folgende Beispiel zeigt, wie ein Produkt mit der Google Play Billing Library mit dem zugehörigen Kauftoken genutzt wird:
Kotlin
suspend fun handlePurchase(purchase: Purchase) { // Purchase retrieved from BillingClient#queryPurchasesAsync or your PurchasesUpdatedListener. val purchase : Purchase = ...; // Verify the purchase. // Ensure entitlement was not already granted for this purchaseToken. // Grant entitlement to the user. val consumeParams = ConsumeParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build() val consumeResult = withContext(Dispatchers.IO) { client.consumePurchase(consumeParams) } }
Java
void handlePurchase(Purchase purchase) { // Purchase retrieved from BillingClient#queryPurchasesAsync or your PurchasesUpdatedListener. Purchase purchase = ...; // Verify the purchase. // Ensure entitlement was not already granted for this purchaseToken. // Grant entitlement to the user. 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); }
Nicht konsumierbare Produkte
Wenn deine App ein sicheres Back-End hat, empfehlen wir zur Bestätigung von nicht konsumierbaren Käufen Purchases.products:acknowledge
zu verwenden, um Käufe zuverlässig zu bestätigen. Prüfe, ob der Kauf zuvor noch nicht bestätigt wurde. Prüfe dazu acknowledgementState
aus dem Ergebnis des Aufrufs von Purchases.products:get
.
Wenn deine App nur eine Client-App ist, verwende BillingClient.acknowledgePurchase()
aus der Google Play Billing Library in deiner App. Bevor du einen Kauf bestätigst, sollte deine App prüfen, ob der Kauf bereits mit der Methode isAcknowledged()
in der Google Play Billing Library bestätigt wurde.
Das folgende Beispiel zeigt, wie du einen Kauf über die Google Play Billing Library bestätigen kannst:
Kotlin
val client: BillingClient = ... val acknowledgePurchaseResponseListener: AcknowledgePurchaseResponseListener = ... suspend fun handlePurchase() { if (purchase.purchaseState === PurchaseState.PURCHASED) { if (!purchase.isAcknowledged) { val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.purchaseToken) val ackPurchaseResult = withContext(Dispatchers.IO) { client.acknowledgePurchase(acknowledgePurchaseParams.build()) } } } }
Java
BillingClient client = ... AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ... void handlePurchase(Purchase purchase) { if (purchase.getPurchaseState() == PurchaseState.PURCHASED) { if (!purchase.isAcknowledged()) { AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener); } } }
Abos
Abos werden ähnlich gehandhabt wie Nicht-Verbrauchsgüter. Verwende nach Möglichkeit Purchases.subscriptions.acknowledge
aus der Google Play Developer API, um den Kauf über dein sicheres Back-End zuverlässig zu bestätigen. Prüfe, ob der Kauf zuvor nicht bestätigt wurde. Prüfe dazu die acknowledgementState
in der Kaufressource von Purchases.subscriptions:get
. Alternativ kannst du ein Abo mit BillingClient.acknowledgePurchase()
in der Google Play Billing Library bestätigen, nachdem du isAcknowledged()
geprüft hast. Alle ersten Abokäufe müssen bestätigt werden. Aboverlängerungen müssen nicht bestätigt werden. Weitere Informationen dazu, wann Abos bestätigt werden müssen, finden Sie unter dem Thema Abos verkaufen.
Käufe werden abgerufen
Es reicht nicht aus, mit einem PurchasesUpdatedListener
auf Kaufaktualisierungen zu warten, um sicherzustellen, dass deine App alle Käufe verarbeitet. Es ist möglich, dass Ihre App nicht alle Käufe eines Nutzers kennt. Hier sind einige Szenarien, in denen Ihre App den Überblick über Käufe verliert oder keine Käufe erkennt:
- Netzwerkprobleme während des Kaufs: Ein Nutzer schließt einen Kauf ab und erhält eine Bestätigung von Google, aber sein Gerät verliert die Netzwerkverbindung, bevor sein Gerät über die
PurchasesUpdatedListener
eine Benachrichtigung über den Kauf erhält. - Mehrere Geräte: Ein Nutzer kauft einen Artikel auf einem Gerät und erwartet dann, dass der Artikel angezeigt wird, wenn er das Gerät wechselt.
- Käufe außerhalb deiner App verarbeiten: Einige Käufe, z. B. das Einlösen von Angeboten, können außerhalb deiner App getätigt werden.
Deine App muss in dieser Situation BillingClient.queryPurchasesAsync()
in der Methode onResume()
aufrufen, damit alle Käufe erfolgreich verarbeitet werden, wie unter Käufe verarbeiten beschrieben.
Das folgende Beispiel zeigt, wie die Abokäufe eines Nutzers abgerufen werden.
queryPurchasesAsync()
gibt nur aktive Abos und nicht verbrauchte einmalige Käufe zurück.
Kotlin
val params = QueryPurchasesParams.newBuilder() .setProductType(ProductType.SUBS) // uses queryPurchasesAsync Kotlin extension function val purchasesResult = billingClient.queryPurchasesAsync(params.build()) // check purchasesResult.billingResult // process returned purchasesResult.purchasesList, e.g. display the plans user owns
Java
billingClient.queryPurchasesAsync( QueryPurchasesParams.newBuilder() .setProductType(ProductType.SUBS) .build(), new PurchasesResponseListener() { public void onQueryPurchasesResponse(BillingResult billingResult, List<Purchase> purchases) { // check billingResult // process returned purchase list, e.g. display the plans user owns } } );
Käufe außerhalb deiner App verarbeiten
Einige Käufe, z. B. das Einlösen von Angeboten, können außerhalb Ihrer App erfolgen. Wenn ein Nutzer einen Kauf außerhalb Ihrer App tätigt, erwartet er, dass in der App eine In-App-Nachricht angezeigt wird oder dass ein Benachrichtigungsmechanismus verwendet wird, der den Nutzer darüber informiert, dass die App den Kauf korrekt erhalten und verarbeitet hat. Einige akzeptable Mechanismen sind:
- In-App-Pop-up anzeigen
- Senden Sie die Nachricht an ein In-App-Nachrichtenfeld und geben Sie deutlich an, dass sich darin eine neue Nachricht befindet.
- Verwenden Sie eine Betriebssystembenachrichtigung.
Deine App kann sich in einem beliebigen Status befinden, wenn sie den Kauf erkennt. Es ist sogar möglich, dass die App zum Zeitpunkt des Kaufs gar nicht installiert wurde. Nutzer erwarten, ihren Kauf zu erhalten, wenn sie die App fortsetzen, unabhängig davon, in welchem Bundesstaat sich die App befindet.
Sie müssen Käufe unabhängig davon erkennen, in welchem Status sich die App zum Zeitpunkt des Kaufs befindet. Es gibt jedoch einige Ausnahmen, bei denen es akzeptabel ist, den Nutzer nicht sofort über den Erhalt des Artikels zu informieren. Beispiele:
- Während der Aktion eines Spiels kann das Zeigen einer Nachricht den Nutzer ablenken. In diesem Fall müssen Sie den Nutzer benachrichtigen, nachdem die Aktion abgeschlossen ist.
- Während Zwischensequenzen, wo eine Nachricht den Nutzer ablenken kann. In diesem Fall muss der Nutzer nach Abschluss der Zwischensequenz benachrichtigt werden.
- Während der ersten Anleitung und der ersten Einrichtung durch den Nutzer im Spiel Wir empfehlen, neue Nutzer sofort nach dem Öffnen des Spiels oder bei der Ersteinrichtung durch den Nutzer über die Prämie zu informieren. Sie können jedoch warten, bis die Hauptspielsequenz verfügbar ist, um den Nutzer zu benachrichtigen.
Bei der Entscheidung, wann und wie du deine Nutzer über Käufe außerhalb deiner App informieren möchtest, solltest du immer den Nutzer im Hinterkopf behalten. Wenn ein Nutzer nicht sofort eine Benachrichtigung erhält, kann er verwirrend sein, deine App nicht mehr verwenden, den Nutzersupport kontaktieren oder dich in den sozialen Medien darüber beschweren. Hinweis: PurchasesUpdatedListener
ist bei deinem Kontext deiner App registriert, um Kauf-Updates zu verarbeiten, einschließlich Käufen, die außerhalb deiner App initiiert wurden. Wenn dein Anwendungsprozess also nicht vorhanden ist, wird PurchasesUpdatedListener
nicht benachrichtigt. Aus diesem Grund sollte deine App BillingClient.queryPurchasesAsync()
in der onResume()
-Methode aufrufen, wie unter Käufe abrufen beschrieben.
Ausstehende Transaktionen verarbeiten
Google Play unterstützt ausstehende Transaktionen oder Transaktionen, die einen oder mehrere zusätzliche Schritte zwischen dem Kaufabschluss und der Verarbeitung der Zahlungsmethode für den Kauf erfordern. Ihre App sollte keine Berechtigungen für diese Art von Käufen gewähren, bis Google Sie darüber informiert, dass die Zahlungsmethode des Nutzers erfolgreich belastet wurde.
Zum Beispiel kann ein Nutzer eine Transaktion initiieren, indem er ein Geschäft auswählt, in dem er später mit Bargeld bezahlt. Der Nutzer erhält einen Code sowohl über eine Benachrichtigung als auch per E-Mail. Wenn der Nutzer im Geschäft ankommt, kann er den Code an der Kasse einlösen und bar bezahlen. Google benachrichtigt dann sowohl Sie als auch den Nutzer, dass die Zahlung eingegangen ist. Ihre App kann dem Nutzer dann Berechtigungen gewähren.
Rufen Sie im Rahmen der Initialisierung von BillingClient
enablePendingPurchases()
auf, um ausstehende Transaktionen für Ihre App zu aktivieren. Ihre App muss ausstehende Transaktionen für Einmalprodukte aktivieren und unterstützen. Bevor Sie Support hinzufügen, sollten Sie sich mit dem Kauflebenszyklus für ausstehende Transaktionen vertraut machen.
Wenn deine App einen neuen Kauf erhält, entweder über deinen PurchasesUpdatedListener
oder durch den Aufruf von queryPurchasesAsync()
, verwende die Methode getPurchaseState()
, um zu ermitteln, ob der Kaufstatus PURCHASED
oder PENDING
ist. Du solltest die Berechtigung nur dann gewähren, wenn der Status PURCHASED
ist.
Wenn Ihre App ausgeführt wird, nachdem der Nutzer den Kauf abgeschlossen hat, wird PurchasesUpdatedListener
noch einmal aufgerufen und PurchaseState
ist jetzt PURCHASED
. An diesem Punkt kann deine App den Kauf mit der Standardmethode zur Verarbeitung von Käufen verarbeiten. Deine App sollte außerdem queryPurchasesAsync()
in der Methode onResume()
deiner App aufrufen, um Käufe abzuwickeln, die in den Status PURCHASED
übergegangen sind, während deine App nicht ausgeführt wurde.
Wenn der Kauf von PENDING
auf PURCHASED
umgestellt wird, erhält Ihr Client für Entwicklerbenachrichtigungen in Echtzeit eine ONE_TIME_PRODUCT_PURCHASED
- oder SUBSCRIPTION_PURCHASED
-Benachrichtigung. Wenn der Kauf storniert wird, erhalten Sie eine ONE_TIME_PRODUCT_CANCELED
- oder SUBSCRIPTION_PENDING_PURCHASE_CANCELED
-Benachrichtigung. Dies kann passieren, wenn Ihr Kunde die Zahlung nicht innerhalb des erforderlichen Zeitraums abschließt. Du kannst den aktuellen Status eines Kaufs jederzeit über die Google Play Developer API prüfen.
Käufe in variabler Stückzahl verarbeiten
Google Play wird ab Version 4.0 der Google Play Billing Library unterstützt und ermöglicht Kunden, mehr als ein In-App-Produkt in einer Transaktion zu kaufen, indem sie eine Menge im Einkaufswagen angeben. Deine App muss Käufe in variabler Stückzahl verarbeiten und eine Berechtigung basierend auf der angegebenen Kaufmenge gewähren.
Damit Käufe in variabler Stückzahl berücksichtigt werden können, muss die Bereitstellungslogik Ihrer App nach einer Artikelmenge suchen. Sie können über eine der folgenden APIs auf das Feld quantity
zugreifen:
getQuantity()
aus der Google Play Billing Library.Purchases.products.quantity
aus der Google Play Developer API
Nachdem du die Logik zum Verarbeiten von Käufen in variabler Stückzahl hinzugefügt hast, musst du die Funktion für variable Stückzahlen für das entsprechende Produkt auf der In-App-Produktverwaltungsseite in der Google Play Developer Console aktivieren.
Abrechnungskonfiguration des Nutzers abfragen
getBillingConfigAsync()
gibt das Land an, das der Nutzer für Google Play verwendet.
Sie können die Abrechnungskonfiguration des Nutzers abfragen, nachdem Sie eine BillingClient
erstellt haben. Im folgenden Code-Snippet wird beschrieben, wie getBillingConfigAsync()
aufgerufen wird. Verarbeiten Sie die Antwort, indem Sie BillingConfigResponseListener
implementieren. Dieser Listener erhält Aktualisierungen für alle von Ihrer Anwendung initiierten Abfragen von Abrechnungskonfigurationen.
Wenn das zurückgegebene BillingResult
keine Fehler enthält, kannst du das Feld countryCode
im Objekt BillingConfig
prüfen, um das Play-Land des Nutzers abzurufen.
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
}
}
});