Google Play Billing Library in deine App integrieren

In diesem Dokument wird beschrieben, wie Sie die Google Play Billing Library in Ihre App einbinden, um Produkte zu verkaufen.

Ablauf eines Kaufs

Hier ist ein typischer Kaufvorgang für einen einmaligen Kauf oder ein Abo.

  1. Zeigen Sie Nutzern, was sie kaufen können.
  2. Starte den Kaufvorgang, damit der Nutzer den Kauf akzeptieren kann.
  3. Bestätige den Kauf auf deinem Server.
  4. Inhalte für den Nutzer bereitstellen
  5. Bestätigen Sie die Bereitstellung der Inhalte. Bei Verbrauchsgütern musst du den Kauf verbrauchen, damit der Nutzer den Artikel noch einmal kaufen kann.

Abos werden automatisch verlängert, bis sie gekündigt werden. Ein Abo kann die folgenden Status haben:

  • Aktiv: Der Nutzer ist einwandfrei und hat Zugriff auf das Abo.
  • Gekündigt: Der Nutzer hat gekündigt, hat aber bis zum Ablauf des Abos noch Zugriff.
  • Im Kulanzzeitraum: Beim Nutzer ist ein Zahlungsproblem aufgetreten, er hat aber weiterhin Zugriff, während Google die Zahlungsmethode noch einmal versucht.
  • Gesperrt: Bei der Zahlung ist ein Problem aufgetreten und der Nutzer hat keinen Zugriff mehr, während Google die Zahlungsmethode noch einmal versucht.
  • Pausiert: Der Nutzer hat den Zugriff pausiert und kann erst wieder darauf zugreifen, wenn er ihn fortsetzt.
  • Abgelaufen: Der Nutzer hat das Abo gekündigt und den Zugriff darauf verloren. Der Nutzer gilt nach Ablauf als abgewandert.

Verbindung zu Google Play initialisieren

Der erste Schritt zur Integration des Abrechnungssystems von Google Play besteht darin, die Google Play Billing Library in deine App einzubinden und eine Verbindung zu initialisieren.

Google Play Billing Library-Abhängigkeit hinzufügen

Fügen Sie der Datei build.gradle Ihrer App die Abhängigkeit für die Google Play Billing Library hinzu, wie hier gezeigt:

Groovy

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")
}

Wenn Sie Kotlin verwenden, enthält das KTX-Modul der Google Play Billing Library Kotlin-Erweiterungen und Koroutinen-Unterstützung, mit denen Sie idiomatischen Kotlin-Code schreiben können, wenn Sie die Google Play Billing Library verwenden. Wenn Sie diese Erweiterungen in Ihr Projekt einbinden möchten, fügen Sie der Datei build.gradle Ihrer App die folgende Abhängigkeit hinzu:

Groovy

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")
}

BillingClient initialisieren

Nachdem Sie eine Abhängigkeit von der Google Play Billing Library hinzugefügt haben, müssen Sie eine BillingClient-Instanz initialisieren. BillingClient ist die Hauptschnittstelle für die Kommunikation zwischen der Google Play Billing Library und dem Rest Ihrer App. BillingClient bietet praktische synchrone und asynchrone Methoden für viele gängige Abrechnungsvorgänge. Beachten Sie Folgendes:

  • Es wird empfohlen, jeweils nur eine aktive BillingClient-Verbindung zu haben, um mehrere PurchasesUpdatedListener-Callbacks für ein einzelnes Ereignis zu vermeiden.
  • Es empfiehlt sich, eine Verbindung für den BillingClient zu initiieren, wenn deine App gestartet oder in den Vordergrund gebracht wird, damit Käufe in deiner App zeitnah verarbeitet werden. Dazu kannst du ActivityLifecycleCallbacks verwenden, das von registerActivityLifecycleCallbacks registriert wurde, und auf „onActivityResumed“ warten, um eine Verbindung zu initialisieren, wenn du zum ersten Mal feststellst, dass eine Aktivität fortgesetzt wird. Weitere Informationen dazu, warum diese Best Practice befolgt werden sollte, findest du im Abschnitt Käufe verarbeiten. Denken Sie auch daran, die Verbindung zu beenden, wenn Ihre App geschlossen wird.

Verwenden Sie zum Erstellen eines BillingClient newBuilder. Sie können einen beliebigen Kontext an newBuilder() übergeben. BillingClient verwendet ihn, um einen Anwendungskontext abzurufen. Das bedeutet, dass Sie sich keine Sorgen um Speicherlecks machen müssen. Wenn du Updates zu Käufen erhalten möchtest, musst du außerdem setListener aufrufen und einen Verweis auf einen PurchasesUpdatedListener übergeben. Dieser Listener empfängt Updates für alle Käufe in Ihrer 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 eine BillingClient erstellt haben, müssen Sie eine Verbindung zu Google Play herstellen.

Wenn Sie eine Verbindung zu Google Play herstellen möchten, rufen Sie startConnection auf. Der Verbindungsprozess ist asynchron. Sie müssen einen BillingClientStateListener implementieren, um einen Callback zu erhalten, sobald die Einrichtung des Clients abgeschlossen ist und er bereit ist, weitere Anfragen zu stellen.

Wenn du die automatische Wiederherstellung der Verbindung zum Dienst nicht aktiviert hast, musst du auch eine Wiederholungslogik implementieren, um verlorene Verbindungen zu Google Play zu verarbeiten. Wenn Sie eine Wiederholungslogik implementieren möchten, überschreiben Sie die Callback-Methode onBillingServiceDisconnected() und sorgen Sie dafür, dass die BillingClient die Methode startConnection() aufruft, um die Verbindung zu Google Play wiederherzustellen, bevor weitere Anfragen gestellt werden. Wenn Sie die automatische Wiederherstellung der Dienstverbindung aktiviert haben, können Sie diese Methode als No-Op implementieren.

Im folgenden Beispiel wird gezeigt, wie Sie eine Verbindung herstellen 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() {
        // 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.
            }
        });

Verbindung automatisch wiederherstellen

Mit der Einführung der Methode enableAutoServiceReconnection() in BillingClient.Builder in Version 8.0.0 kann die Play Billing Library die Dienstverbindung jetzt automatisch wiederherstellen, wenn ein API-Aufruf erfolgt, während die Verbindung zum Dienst getrennt ist. Dies kann zu einer Reduzierung der SERVICE_DISCONNECTED-Antworten führen, da die Wiederverbindung intern verarbeitet wird, bevor der API-Aufruf erfolgt.

Automatische Wiederverbindung aktivieren

Verwenden Sie beim Erstellen einer BillingClient-Instanz die Methode enableAutoServiceReconnection() in BillingClient.Builder, um die automatische Wiederverbindung zu aktivieren.

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

Produkte anzeigen, die gekauft werden können

Nachdem du eine Verbindung zu Google Play hergestellt hast, kannst du deine verfügbaren Produkte abfragen und deinen Nutzern anzeigen lassen.

Die Abfrage von Produktdetails ist ein wichtiger Schritt, bevor du deine Produkte den Nutzern präsentierst, da sie lokalisierte Produktinformationen zurückgibt. Prüfen Sie bei Abos, ob die Produktanzeige allen Google Play-Richtlinien entspricht.

Rufen Sie die Methode queryProductDetailsAsync auf, um Produktdetails zu Einmalkaufprodukten abzufragen. Diese Methode kann je nach Konfiguration des Einmalkaufprodukts mehrere Angebote zurückgeben. Weitere Informationen finden Sie unter Mehrere Kaufoptionen und Angebote für Einmalkaufprodukte.

Um das Ergebnis des asynchronen Vorgangs zu verarbeiten, müssen Sie auch einen Listener angeben, der die Schnittstelle ProductDetailsResponseListener implementiert. Anschließend können Sie onProductDetailsResponse überschreiben, wodurch der Listener benachrichtigt wird, wenn die Abfrage abgeschlossen ist. Dies wird im folgenden Beispiel gezeigt:

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.
           }
        }
    }
}
)

Wenn Sie Produktdetails abfragen, übergeben Sie eine Instanz von QueryProductDetailsParams, die eine Liste von Produkt-ID-Strings angibt, die in der Google Play Console zusammen mit einem ProductType erstellt wurden. ProductType kann entweder ProductType.INAPP für Einmalkaufprodukte oder ProductType.SUBS für Abos sein.

Mit Kotlin-Erweiterungen abfragen

Wenn Sie Kotlin-Erweiterungen verwenden, können Sie Details zu Einmalkaufprodukten abfragen, indem Sie die Erweiterungsfunktion queryProductDetails() aufrufen.

queryProductDetails() nutzt Kotlin-Koroutinen, sodass Sie keinen separaten Listener definieren müssen. Stattdessen wird die Funktion angehalten, 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 unterstützen einige Geräte ProductDetails und queryProductDetailsAsync() nicht, was in der Regel auf veraltete Versionen der Google Play-Dienste zurückzuführen ist. Informationen zur ordnungsgemäßen Unterstützung dieses Szenarios findest du im Migrationsleitfaden für die Play Billing Library 7. Dort wird erläutert, wie du die Funktionen zur Abwärtskompatibilität verwendest.

Ergebnis verarbeiten

Die Google Play Billing Library speichert die Abfrageergebnisse in einem QueryProductDetailsResult-Objekt. QueryProductDetailsResult enthält eine List mit ProductDetails-Objekten. Anschließend kannst du für jedes ProductDetails-Objekt in der Liste verschiedene Methoden aufrufen, um relevante Informationen zu einem erfolgreich abgerufenen Einmalkaufprodukt aufzurufen, z. B. den Preis oder die Beschreibung. Eine Liste der verfügbaren Produktdetails finden Sie in der Liste der Methoden in der Klasse ProductDetails.

QueryProductDetailsResult enthält auch ein List von UnfetchedProduct-Objekten. Sie können dann jedes UnfetchedProduct abfragen, um einen Statuscode zu erhalten, der dem Grund für den Fehler beim Abrufen entspricht. Eine Liste der Methoden in der Klasse UnfetchedProduct enthält die verfügbaren nicht abgerufenen Produktinformationen.

Bevor du einen Artikel zum Verkauf anbietest, solltest du prüfen, ob der Nutzer den Artikel nicht bereits besitzt. Wenn der Nutzer einen Verbrauchsartikel hat, der sich noch in seiner Artikelbibliothek befindet, muss er ihn verbrauchen, bevor er ihn wieder kaufen kann.

Bevor du ein Abo anbietest, solltest du prüfen, ob der Nutzer bereits ein Abo hat. Beachten Sie außerdem Folgendes:

  • Bei Abos gibt die Methode queryProductDetailsAsync() Details zum Aboprodukt und maximal 50 Angebote pro Abo zurück, die für den Nutzer infrage kommen. Wenn der Nutzer versucht, ein Angebot zu kaufen, für das er nicht berechtigt ist (z. B. wenn die App eine veraltete Liste von Angeboten anzeigt, für die er berechtigt ist), wird er von Google Play darüber informiert, dass er nicht berechtigt ist, und kann stattdessen das Basis-Abo kaufen.

  • Bei Einmalkaufprodukten gibt die Methode queryProductDetailsAsync() nur die Angebote zurück, die für den Nutzer infrage kommen. Wenn der Nutzer versucht, ein Angebot zu kaufen, für das er nicht berechtigt ist (z. B. weil er das Limit für die Kaufmenge erreicht hat), wird er von Google Play darüber informiert, dass er nicht berechtigt ist, und kann stattdessen das Angebot mit Kaufoption erwerben.

Kaufvorgang starten

Wenn Sie eine Kaufanfrage über Ihre App starten möchten, rufen Sie die Methode launchBillingFlow() im Hauptthread Ihrer App auf. Diese Methode verwendet einen Verweis 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)
        // 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);

Die Methode launchBillingFlow() gibt einen der Antwortcodes zurück, die in BillingClient.BillingResponseCode aufgeführt sind. Prüfen Sie dieses Ergebnis, um sicherzustellen, dass beim Starten des Kaufvorgangs keine Fehler aufgetreten sind. Ein BillingResponseCode-Wert von OK weist auf einen erfolgreichen Start hin.

Bei einem erfolgreichen Aufruf von launchBillingFlow() wird der Google Play-Kaufbildschirm angezeigt. Abbildung 1 zeigt einen Kaufbildschirm für ein Abo:

Auf dem Google Play-Kaufbildschirm wird ein Abo angezeigt, das zum Kauf verfügbar ist.
Abbildung 1. Auf dem Google Play-Kaufbildschirm wird ein Abo angezeigt, das gekauft werden kann.

Google Play ruft onPurchasesUpdated() auf, um das Ergebnis des Kaufvorgangs an einen Listener zu senden, der die PurchasesUpdatedListener-Schnittstelle implementiert. Der Listener wird mit der Methode setListener() angegeben, wenn Sie Ihren Client initialisieren.

Sie müssen onPurchasesUpdated() implementieren, um mögliche Antwortcodes zu verarbeiten. Das folgende Beispiel zeigt, wie Sie onPurchasesUpdated() überschreiben:

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.
  }
}

Bei einem erfolgreichen Kauf wird ein Google Play-Bildschirm wie in Abbildung 2 angezeigt.

Anzeige der Kaufbestätigung bei Google Play.
Abbildung 2: Google Play-Bildschirm für erfolgreichen Kauf.

Bei einem erfolgreichen Kauf wird auch ein Kauftoken generiert. Dies ist eine eindeutige Kennung, die den Nutzer und die Produkt-ID für das gekaufte Einmalkaufprodukt darstellt. Das Kauftoken kann lokal in der App gespeichert werden. Wir empfehlen jedoch dringend, das Token an einen sicheren Backend-Server zu senden. Dort lässt es sich einsetzen, um Käufe zu prüfen und Betrug zu verhindern. Dieser Vorgang wird unter Käufe erkennen und verarbeiten näher beschrieben.

Der Nutzer erhält außerdem per E-Mail einen Beleg für die Transaktion, der eine Bestell-ID oder eine eindeutige ID der Transaktion enthält. Nutzer erhalten für jeden Kauf eines Einmalkaufprodukts sowie für den ersten Abokauf und die nachfolgenden wiederkehrenden automatischen Verlängerungen eine E‑Mail mit einer eindeutigen Bestell-ID. Mit der Bestell-ID kannst du Erstattungen in der Google Play Console verwalten.

Personalisierte Preise angeben

Wenn deine App an Nutzer in der Europäischen Union vertrieben werden kann, verwende die Methode setIsOfferPersonalized(), wenn du launchBillingFlow aufrufst, um Nutzer darüber zu informieren, dass der Preis eines Artikels mithilfe automatisierter Entscheidungsfindung personalisiert wurde.

Der Google Play-Kaufbildschirm, auf dem angezeigt wird, dass der Preis für den Nutzer angepasst wurde.
Abbildung 3: Der Google Play-Kaufbildschirm, auf dem angezeigt wird, dass der Preis für den Nutzer angepasst wurde.

Sie müssen Artikel  6 (1) (ea) der Richtlinie zum Verbraucherrecht 2011/83/EU, um festzulegen, ob der von dir angebotene Preis personalisiert wurde.

setIsOfferPersonalized() verwendet eine boolesche Eingabe. Wenn true, enthält die Play-Benutzeroberfläche die Offenlegung. Wenn false, wird die Offenlegung auf der Benutzeroberfläche weggelassen. Der Standardwert ist false.

Weitere Informationen findest du in der Verbraucherhilfe.

Nutzer-IDs anhängen

Wenn du den Kaufvorgang startest, kann deine App alle Nutzer-IDs, die du für den Nutzer hast, der den Kauf tätigt, mit obfuscatedAccountId oder obfuscatedProfileId anhängen. Eine Beispiel-ID könnte eine verschleierte Version der Anmeldung des Nutzers in Ihrem System sein. Wenn Sie diese Parameter festlegen, kann Google Betrug besser erkennen. Außerdem kannst du so dafür sorgen, dass Käufe dem richtigen Nutzer zugeordnet werden, wie unter Nutzern Berechtigungen gewähren beschrieben.

Käufe erkennen und verarbeiten

Die in diesem Abschnitt beschriebene Erkennung und Verarbeitung eines Kaufs gilt für alle Arten von Käufen, einschließlich Out-of-App-Käufen wie dem Einlösen von Werbeaktionen.

Ihre App erkennt neue Käufe und abgeschlossene ausstehende Käufe auf eine der folgenden Arten:

  1. Wenn onPurchasesUpdated aufgerufen wird, weil deine App launchBillingFlow aufruft (wie im vorherigen Abschnitt beschrieben), oder wenn deine App mit einer aktiven Billing Library-Verbindung ausgeführt wird, wenn ein Kauf außerhalb deiner App getätigt oder ein ausstehender Kauf abgeschlossen wird. Beispiel: Ein Familienmitglied genehmigt einen ausstehenden Kauf auf einem anderen Gerät.
  2. Wenn Ihre App „queryPurchasesAsync“ aufruft, um die Käufe des Nutzers abzufragen.

Für #1 wird onPurchasesUpdated automatisch für neue oder abgeschlossene Käufe aufgerufen, solange deine App ausgeführt wird und eine aktive Verbindung zur Google Play Billing Library besteht. Wenn Ihre Anwendung nicht ausgeführt wird oder Ihre App keine aktive Verbindung zur Google Play Billing Library hat, wird onPurchasesUpdated nicht aufgerufen. Denkt daran, dass eure App eine aktive Verbindung aufrechterhalten sollte, solange sie im Vordergrund ausgeführt wird, damit sie rechtzeitig Kaufupdates erhält.

Für Punkt 2 musst du BillingClient.queryPurchasesAsync() aufrufen, damit deine App alle Käufe verarbeitet. Es wird empfohlen, dies zu tun, wenn Ihre App erfolgreich eine Verbindung mit der Google Play Billing Library herstellt. Dies wird empfohlen, wenn Ihre App gestartet oder in den Vordergrund gebracht wird, wie unter BillingClient initialisieren beschrieben. Dazu rufen Sie „queryPurchasesAsync“ auf, wenn Sie ein erfolgreiches Ergebnis für onServiceConnected erhalten. Die Beachtung dieser Empfehlung ist entscheidend für den Umgang mit Ereignissen und Situationen wie:

  • Netzwerkprobleme während des Kaufs: Ein Nutzer kann einen Kauf erfolgreich abschließen und eine Bestätigung von Google erhalten, aber die Netzwerkverbindung seines Geräts wird unterbrochen, bevor das Gerät und deine App über die PurchasesUpdatedListener eine Benachrichtigung über den Kauf erhalten.
  • Mehrere Geräte: Ein Nutzer kauft einen Artikel auf einem Gerät und erwartet, dass er den Artikel auch sieht, wenn er das Gerät wechselt.
  • Käufe außerhalb deiner App verarbeiten: Einige Käufe, z. B. das Einlösen von Werbeaktionen, können außerhalb deiner App erfolgen.
  • Übergänge des Kaufstatus verarbeiten: Ein Nutzer kann die Zahlung für einen AUSSTEHENDEN Kauf abschließen, während deine App nicht ausgeführt wird. Er erwartet dann, dass er beim Öffnen deiner App eine Bestätigung erhält, dass er den Kauf abgeschlossen hat.
  • Gesperrte Abos: Ein Abo kann während des Abo-Lebenszyklus gesperrt werden. BillingClient.queryPurchasesAsync() gibt nur dann gesperrte Abos zurück, wenn der Parameter includeSuspendedSubscriptions auf QueryPurchasesParams.Builder gesetzt ist. Gesperrte Abos werden in PurchasesUpdatedListener nicht zurückgegeben.

Wenn deine App einen neuen oder abgeschlossenen Kauf erkennt, sollte sie Folgendes tun:

  • Bestätigen Sie den Kauf.
  • Gewähren Sie dem Nutzer Zugriff auf die Inhalte für abgeschlossene Käufe.
  • Benachrichtigen Sie den Nutzer.
  • Google darüber benachrichtigen, dass Ihre App abgeschlossene Käufe verarbeitet hat.

Diese Schritte werden in den folgenden Abschnitten ausführlich beschrieben. Anschließend werden alle Schritte noch einmal zusammengefasst.

Kauf bestätigen

In deiner App sollte immer die Rechtmäßigkeit von Käufen überprüft werden, bevor einem Nutzer Vorteile gewährt werden. Folge dazu der Anleitung unter Käufe vor der Gewährung von Berechtigungen bestätigen. Erst nach der Bestätigung des Kaufs sollte deine App den Kauf weiter verarbeiten und dem Nutzer Berechtigungen erteilen. Dies wird im nächsten Abschnitt erläutert. Wenn ein Kauf die Bestätigung, die Berechtigungsprüfung oder die Missbrauchsprüfung nicht besteht, lesen Sie den Hilfeartikel Abgelehnte oder nicht ausgeführte Käufe verarbeiten.

Nutzer Berechtigung gewähren

Sobald Ihre App einen Kauf bestätigt hat, kann sie dem Nutzer weiterhin die Berechtigung gewähren und ihn benachrichtigen. Bevor du die Berechtigung erteilst, solltest du prüfen, ob deine App den Kaufstatus PURCHASED prüft. Wenn der Kauf den Status „AUSSTEHEND“ hat, sollte deine App den Nutzer darüber informieren, dass er noch Maßnahmen ergreifen muss, um den Kauf abzuschließen, bevor die Berechtigung gewährt wird. Gewähre die Berechtigung nur, wenn der Kauf von „AUSSTEHEND“ zu „GEKAUFT“ wechselt. Weitere Informationen finden Sie unter Ausstehende Transaktionen verarbeiten.

Wenn du dem Kauf Nutzer-IDs hinzugefügt hast, wie unter Nutzer-IDs hinzufügen beschrieben, kannst du sie abrufen und dem richtigen Nutzer in deinem System zuordnen. Diese Methode ist nützlich, wenn du Käufe abgleichen möchtest, bei denen deine App möglicherweise den Kontext verloren hat, für welchen Nutzer ein Kauf bestimmt ist. Zum Schutz vor Missbrauch empfiehlt Google Play, diese Kennungen in Ihrem sicheren Backend zu überprüfen, bevor Sie Berechtigungen erteilen. Weitere Informationen findest du unter Käufe vor dem Gewähren von Berechtigungen bestätigen. Hinweis: Bei Käufen außerhalb Ihrer App werden diese Kennungen nicht festgelegt. In diesem Fall kann deine App entweder dem angemeldeten Nutzer die Berechtigung gewähren oder ihn auffordern, ein bevorzugtes Konto auszuwählen.

Bei Vorbestellungen befindet sich der Kauf vor dem Zeitpunkt der Veröffentlichung im Status AUSSTEHEND. Der Vorbestellungskauf wird zum Zeitpunkt der Veröffentlichung abgeschlossen und der Status ändert sich ohne weitere Maßnahmen zu GEKAUFT.

Nutzer benachrichtigen

Nachdem dem Nutzer die Berechtigung erteilt wurde, sollte in deiner App eine Benachrichtigung angezeigt werden, um den erfolgreichen Kauf zu bestätigen. Dank der Benachrichtigung weiß der Nutzer, dass der Kauf erfolgreich abgeschlossen wurde. Andernfalls könnte er die Nutzung deiner App einstellen, sich an den Nutzersupport wenden oder sich in den sozialen Medien beschweren. Beachte, dass deine App während des gesamten Lebenszyklus jederzeit Kaufaktualisierungen erkennen kann. Beispiel: Ein Elternteil genehmigt einen ausstehenden Kauf auf einem anderen Gerät. In diesem Fall kann es sinnvoll sein, den Nutzer erst zu einem geeigneten Zeitpunkt zu benachrichtigen. Hier einige Beispiele, bei denen eine Verzögerung angemessen wäre:

  • Während der Action-Sequenzen eines Spiels oder während Zwischensequenzen kann das Anzeigen einer Nachricht den Nutzer ablenken. In diesem Fall müssen Sie den Nutzer benachrichtigen, nachdem der Aktionsteil abgeschlossen ist.
  • Während des ersten Tutorials und der Nutzereinrichtung im Spiel. Beispielsweise könnte ein Nutzer vor der Installation Ihrer App einen Kauf außerhalb der App getätigt haben. Wir empfehlen, neue Nutzer sofort nach dem Öffnen des Spiels oder während der Ersteinrichtung über die Prämie zu informieren. Wenn Nutzer in deiner App ein Konto erstellen oder sich anmelden müssen, bevor sie die Berechtigung erhalten, solltest du ihnen mitteilen, welche Schritte sie ausführen müssen, um ihren Kauf in Anspruch zu nehmen. Das ist wichtig, da Käufe nach drei Tagen erstattet werden, wenn sie nicht von deiner App verarbeitet wurden.

Google Play empfiehlt die folgenden Mechanismen, um den Nutzer über einen Kauf zu informieren:

  • Ein Dialogfeld in der App anzeigen.
  • Die Nachricht wird an ein In-App-Postfach gesendet und es wird deutlich darauf hingewiesen, dass sich dort eine neue Nachricht befindet.
  • Verwenden Sie eine Betriebssystem-Benachrichtigung.

In der Benachrichtigung sollte der Nutzer über den erhaltenen Vorteil informiert werden. Beispiel: „Du hast 100 Goldmünzen gekauft!“ Wenn der Kauf im Rahmen eines Programms wie Play Pass erfolgt ist, wird dies dem Nutzer in deiner App mitgeteilt. Beispiel: „Artikel erhalten! Du hast mit dem Play Pass 100 Edelsteine erhalten. Weiter.“ Für jedes Programm gibt es möglicherweise Empfehlungen für den Text, der Nutzern angezeigt werden sollte, um die Vorteile zu kommunizieren.

Google benachrichtigen, dass der Kauf verarbeitet wurde

Nachdem deine App dem Nutzer die Berechtigung erteilt und ihn über die erfolgreiche Transaktion informiert hat, muss sie Google darüber benachrichtigen, dass der Kauf erfolgreich verarbeitet wurde. Dazu muss der Kauf bestätigt werden. Dies muss innerhalb von drei Tagen geschehen, damit der Kauf nicht automatisch erstattet und die Berechtigung widerrufen wird. Der Prozess zum Bestätigen verschiedener Arten von Käufen wird in den folgenden Abschnitten beschrieben.

Verbrauchsgüter

Wenn deine App ein sicheres Backend hat, empfehlen wir dir, für Verbrauchsgüter Purchases.products:consume zu verwenden, um Käufe zuverlässig zu verbrauchen. Prüfe, ob der Kauf bereits verbraucht wurde. Dazu kannst du den consumptionState aus dem Ergebnis des Aufrufs von Purchases.products:get prüfen. Wenn Ihre App nur clientseitig ist und kein Backend hat, verwenden Sie consumeAsync() aus der Google Play Billing Library. Beide Methoden erfüllen die Bestätigungsanforderung und zeigen an, dass Ihre App dem Nutzer die Berechtigung erteilt hat. Mit diesen Methoden kann Ihre App auch das Einmalkaufprodukt, das dem eingegebenen Kaufftoken entspricht, für den erneuten Kauf verfügbar machen. Bei consumeAsync() müssen Sie auch 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 aufgerufen wird, wenn der Vorgang abgeschlossen ist.

Im folgenden Beispiel wird gezeigt, wie ein Produkt mit der Google Play Billing Library und dem zugehörigen Kaufftoken verbraucht wird:

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

Nicht konsumierbare Produkte

Wenn deine App ein sicheres Backend hat, empfehlen wir, nicht verbrauchbare Käufe mit Purchases.products:acknowledge zuverlässig zu bestätigen. Prüfe, ob der Kauf bereits bestätigt wurde. Dazu kannst du den acknowledgementState aus dem Ergebnis des Aufrufs von Purchases.products:get prüfen.

Wenn deine App nur clientseitig ist, verwende BillingClient.acknowledgePurchase() aus der Google Play Billing Library in deiner App. Bevor du einen Kauf bestätigst, sollte deine App mit der Methode isAcknowledged() in der Google Play Billing Library prüfen, ob er bereits bestätigt wurde.

Im folgenden Beispiel wird gezeigt, wie Sie einen Kauf mit der Google Play Billing Library bestätigen:

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.
        });
    }
}

Abos

Abos werden ähnlich wie nicht verbrauchbare Artikel behandelt. Verwende nach Möglichkeit Purchases.subscriptions.acknowledge aus der Google Play Developer API, um den Kauf zuverlässig über dein sicheres Backend zu bestätigen. Prüfe, ob der Kauf bereits bestätigt wurde. Dazu kannst du den acknowledgementState in der Kaufressource von Purchases.subscriptions:get prüfen. Andernfalls können Sie ein Abo mit BillingClient.acknowledgePurchase() aus der Google Play Billing Library bestätigen, nachdem Sie isAcknowledged() geprüft haben. Alle Erstkäufe von Abos müssen bestätigt werden. Aboverlängerungen müssen nicht bestätigt werden. Weitere Informationen dazu, wann Abos bestätigt werden müssen, findest du im Hilfeartikel Abos verkaufen.

Umgang mit abgelehnten oder nicht ausgeführten Käufen

Wenn ein Kauf die Backend-Verifizierung, die Berechtigungsprüfung des Nutzers oder die Betrugs- und Missbrauchsprüfung nicht besteht oder wenn dein System die Berechtigung nicht erfüllen kann, gewähre die Berechtigung nicht und bestätige oder verbrauche den Kauf nicht.

Nicht bestätigte Käufe werden nach Ablauf des Bestätigungszeitraums automatisch erstattet und widerrufen, um Verbraucher zu schützen. Du solltest dich jedoch nicht auf diesen Zeitraum verlassen, um Käufe abzulehnen. Wenn das Bestätigungsfenster abläuft, bleibt die Bestellung in einem unbestätigten Zustand und ist für Google Play mehrdeutig, da nicht zwischen einer absichtlichen Ablehnung durch den Entwickler und einer Zeitüberschreitung bei der Backend-Verarbeitung unterschieden werden kann.

Stattdessen solltest du abgelehnte Käufe sofort über dein Backend mit der Google Play Developer API widerrufen und erstatten:

  • Abos: Rufen Sie purchases.subscriptionsv2.revoke mit "fullRefund": {} in revocationContext auf. Dadurch wird das Abo sofort beendet, der Zugriff widerrufen und eine volle Erstattung veranlasst.
  • Einmalkaufprodukte: Rufe orders.refund mit dem Parameter revoke auf, der auf true festgelegt ist, um eine Bestellung sofort zu erstatten und die Berechtigung zu widerrufen. Wenn Sie diese Methode aufrufen, müssen Sie die Bestell-ID des Kaufs übergeben, die Sie mit Purchase.getOrderId() oder purchases.productsv2.getproductpurchasev2 abrufen können. Rufen Sie bei abgelehnten Käufen niemals consumeAsync(), acknowledgePurchase(), Purchases.products:consume oder Purchases.products:acknowledge auf.
  • Verhalten von RTDN und Voided Purchases API: Vom Entwickler initiierte Widerrufe und Erstattungen (purchases.subscriptionsv2.revoke und orders.refund, wobei revoke auf true gesetzt ist) lösen Entwicklerbenachrichtigungen in Echtzeit aus und werden in der Voided Purchases API aufgezeichnet (purchases.voidedpurchases.list, wobei das Antwortfeld voidedSource für den Entwickler auf 1 gesetzt ist):
    • Abos: Sendet sowohl eine SUBSCRIPTION_REVOKED-Benachrichtigung als auch eine VoidedPurchaseNotification.
    • Einmalkaufprodukte: Sendet eine VoidedPurchaseNotification-Benachrichtigung (und eine ONE_TIME_PRODUCT_CANCELED-Benachrichtigung, wenn Ihre App in der Play Console so konfiguriert ist, dass sie alle Benachrichtigungen zu Einmalkaufprodukten erhält).
    • Wenn Sie orders.refund aufrufen, ohne revoke auf true festzulegen, wird die Bestellung erstattet, ohne dass die Berechtigung widerrufen wird. Es wird keine Benachrichtigung über einen Widerruf oder einen ungültigen Kauf ausgelöst. Weitere Informationen finden Sie unter Abos und einmalige Käufe verwalten.

Zusammenfassung

Im Folgenden finden Sie eine Zusammenfassung dieser Schritte.

  1. Sende den Kauf an dein sicheres Backend, um Käufe zu bestätigen, bevor du Berechtigungen gewährst.

  2. Aktualisieren Sie Ihren Berechtigungsspeicher mit dem Kauf. Wenn der Kauf den Status „AUSSTEHEND“ hat, muss die Berechtigung als ausstehend gekennzeichnet sein und der Nutzer darf noch keine Vorteile erhalten. Es wird empfohlen, diesen Schritt in Ihrem sicheren Backend auszuführen. Er kann mit dem API-Aufruf an Ihr Backend in Schritt 1 kombiniert werden.

  3. Benachrichtigen Sie den Nutzer mit einer entsprechenden Nachricht (verzögern Sie die Benachrichtigung bei Bedarf wie oben beschrieben).

  4. Benachrichtigen Sie Google, dass der Kauf verarbeitet wurde. Folgen Sie dazu den Schritten im Abschnitt „Käufe verarbeiten“.

Wenn Sie prüfen möchten, ob diese Schritte in Ihrer App korrekt implementiert wurden, folgen Sie der Testanleitung.

Ausstehende Transaktionen verarbeiten

Google Play unterstützt ausstehende Transaktionen, also Transaktionen, die einen oder mehrere zusätzliche Schritte zwischen dem Zeitpunkt, an dem ein Nutzer einen Kauf einleitet, und dem Zeitpunkt, an dem die Zahlungsmethode für den Kauf verarbeitet wird, erfordern. Ihre App sollte erst dann eine Berechtigung für diese Art von Käufen gewähren, wenn Google Sie darüber informiert hat, dass die Zahlungsmethode des Nutzers erfolgreich belastet wurde.

Beispielsweise kann ein Nutzer eine Transaktion initiieren, indem er ein Geschäft auswählt, in dem er später bar bezahlt. Der Nutzer erhält einen Code per Benachrichtigung und 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 die Berechtigung erteilen.

Rufe enablePendingPurchases() im Rahmen der Initialisierung von BillingClient auf, um ausstehende Transaktionen für deine App zu aktivieren. Deine App muss ausstehende Transaktionen für Einmalkaufprodukte aktivieren und unterstützen. Bevor du die Unterstützung hinzufügst, solltest du dich mit dem Kauflebenszyklus für ausstehende Transaktionen vertraut machen.

Wenn deine App einen neuen Kauf erhält, entweder über deinen PurchasesUpdatedListener oder als Ergebnis des Aufrufs von queryPurchasesAsync, verwende die Methode getPurchaseState(), um festzustellen, ob der Kaufstatus PURCHASED oder PENDING ist. Sie sollten die Berechtigung nur gewähren, wenn der Status PURCHASED ist.

Wenn deine App ausgeführt wird und du eine aktive Verbindung zur Play Billing Library hast, wenn der Nutzer den Kauf abschließt, wird dein PurchasesUpdatedListener noch einmal aufgerufen und der PurchaseState ist jetzt PURCHASED. An diesem Punkt kann deine App den Kauf mit der Standardmethode zum Erkennen und Verarbeiten von Käufen verarbeiten. Ihre App sollte auch queryPurchasesAsync() in der onResume()-Methode Ihrer App aufrufen, um Käufe zu verarbeiten, die in den Status PURCHASED übergegangen sind, während Ihre App nicht ausgeführt wurde.

Wenn der Kauf von PENDING zu PURCHASED wechselt, erhält dein real_time_developer_notifications-Client eine ONE_TIME_PRODUCT_PURCHASED- oder SUBSCRIPTION_PURCHASED-Benachrichtigung. Wenn der Kauf storniert wird, erhältst du 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. Sie können den aktuellen Status eines Kaufs jederzeit mit der Google Play Developer API prüfen.

Käufe mehrerer Artikel verarbeiten

In Version 4.0 und höher der Google Play Billing Library können Kunden bei Google Play mehrere Einheiten desselben Einmalkaufprodukts in einer Transaktion kaufen, indem sie im Einkaufswagen eine Menge angeben. Deine App muss Käufe mehrerer Artikel verarbeiten und die Berechtigung basierend auf der angegebenen Kaufmenge gewähren können.

Damit Käufe mehrerer Artikel berücksichtigt werden, muss die Bereitstellungslogik Ihrer App die Artikelmenge prüfen. Sie können über eine der folgenden APIs auf ein quantity-Feld zugreifen:

Nachdem du die Logik für den Kauf mehrerer Artikel hinzugefügt hast, musst du die Funktion für den Kauf mehrerer Artikel für das entsprechende Produkt auf der Seite zur Verwaltung von Einmalkaufprodukten 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. Das folgende Code-Snippet zeigt, wie Sie getBillingConfigAsync() aufrufen. Verarbeite die Antwort, indem du BillingConfigResponseListener implementierst. Dieser Listener erhält Updates für alle Abrechnungskonfigurationsabfragen, die von Ihrer App initiiert werden.

Wenn die zurückgegebene BillingResult keine Fehler enthält, können Sie das Feld countryCode im Objekt BillingConfig prüfen, um das Google 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 {
                // 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
            }
        });