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 sehen Sie einen typischen Kaufvorgang für einen Einmalkauf oder ein Abo.

  1. Zeigen Sie dem Nutzer, was er kaufen kann.
  2. Starten Sie den Kaufvorgang, damit der Nutzer den Kauf bestätigen kann.
  3. Bestätigen Sie den Kauf auf Ihrem Server.
  4. Stelle dem Nutzer Inhalte zur Verfügung.
  5. Bestätigen Sie die Zustellung der Inhalte. Verbrauchen Sie Verbrauchsgüter, 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 durchlaufen:

  • Aktiv: Der Nutzer ist in gutem Zustand und hat Zugriff auf das Abo.
  • Gekündigt: Der Nutzer hat gekündigt, hat aber bis zum Ablaufdatum weiterhin Zugriff.
  • Kulanzzeitraum: Beim Nutzer ist ein Zahlungsproblem aufgetreten, er hat aber weiterhin Zugriff, während Google die Zahlungsmethode noch einmal versucht.
  • Ausgesetzt: Der Nutzer hatte ein Zahlungsproblem und hat keinen Zugriff mehr, während Google die Zahlungsmethode noch einmal belastet.
  • Pausiert: Der Nutzer hat seinen Zugriff pausiert und hat erst wieder Zugriff, wenn er ihn fortsetzt.
  • Abgelaufen: Der Nutzer hat das Abo gekündigt und den Zugriff darauf verloren. Der Nutzer gilt bei Ablauf als abgewandert.

Verbindung zu Google Play initialisieren

Als Erstes müssen Sie die Google Play Billing Library in Ihre App einbinden und eine Verbindung initialisieren.

Google Play Billing Library-Abhängigkeit hinzufügen

Fügen Sie die Abhängigkeit der Google Play Billing Library der build.gradle-Datei Ihrer App hinzu, wie unten dargestellt:

Groovy

dependencies {
    def billing_version = "8.0.0"

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

Kotlin

dependencies {
    val billing_version = "8.0.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 Coroutines-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 = "8.0.0"

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

Kotlin

dependencies {
    val billing_version = "8.0.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 sowohl synchrone als auch asynchrone Convenience-Methoden für viele gängige Abrechnungsvorgänge. Beachten Sie Folgendes:

  • Es wird empfohlen, jeweils nur eine aktive BillingClient-Verbindung geöffnet zu haben, um mehrere PurchasesUpdatedListener-Rückrufe für ein einzelnes Ereignis zu vermeiden.
  • Es wird empfohlen, eine Verbindung für den BillingClient zu initiieren, wenn Ihre App gestartet oder in den Vordergrund gebracht wird, damit Käufe in Ihrer App zeitnah verarbeitet werden. Dazu können Sie ActivityLifecycleCallbacks verwenden, das von registerActivityLifecycleCallbacks registriert wird. Außerdem können Sie auf onActivityResumed warten, um eine Verbindung zu initialisieren, wenn Sie zum ersten Mal erkennen, dass eine Aktivität fortgesetzt wird. Weitere Informationen dazu, warum diese Best Practice befolgt werden sollte, finden Sie im Abschnitt Käufe verarbeiten. Denken Sie auch daran, die Verbindung zu beenden, wenn Ihre App geschlossen wird.

Verwenden Sie zum Erstellen einer BillingClient newBuilder. Sie können einen beliebigen Kontext an newBuilder() übergeben. BillingClient verwendet ihn, um einen Anwendungskontext abzurufen. Sie müssen sich also keine Sorgen um Speicherlecks machen. Wenn Sie Updates zu Käufen erhalten möchten, müssen Sie auch setListener aufrufen und eine Referenz zu einem PurchasesUpdatedListener übergeben. Dieser Listener erhält 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 ein 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 an. Der Verbindungsprozess ist asynchron. Sie müssen ein BillingClientStateListener implementieren, um einen Callback zu erhalten, sobald die Einrichtung des Clients abgeschlossen ist und er bereit ist, weitere Anfragen zu stellen.

Sie müssen außerdem eine Wiederholungslogik implementieren, um verlorene Verbindungen zu Google Play zu verarbeiten. Wenn Sie die Logik für Wiederholungsversuche implementieren möchten, überschreiben Sie die Callback-Methode onBillingServiceDisconnected() und sorgen Sie dafür, dass BillingClient die Methode startConnection() aufruft, 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.
    }
});

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 der Dienst getrennt ist. Dies kann zu einer Verringerung der SERVICE_DISCONNECTED-Antworten führen, da die erneute Verbindung intern erfolgt, bevor der API-Aufruf erfolgt.

Automatische Wiederverbindung aktivieren

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

Kotlin

val billingClient = BillingClient.newBuilder(context)
    .setListener(listener)
    .enablePendingPurchases()
    .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();

Verfügbare Produkte zum Kauf präsentieren

Nachdem Sie eine Verbindung zu Google Play hergestellt haben, können Sie Ihre verfügbaren Produkte abfragen und Ihren Nutzern präsentieren.

Das Abrufen von Produktdetails ist ein wichtiger Schritt, bevor Sie Ihren Nutzern Ihre Produkte präsentieren, da dadurch lokalisierte Produktinformationen zurückgegeben werden. Prüfen Sie bei Abos, ob die Darstellung Ihrer Produkte allen Play-Richtlinien entspricht.

Wenn Sie Details zu Einmalkaufprodukten abfragen möchten, rufen Sie die Methode queryProductDetailsAsync auf. Diese Methode kann basierend auf Ihrer Konfiguration für Einmalkaufprodukte 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. Das folgende Beispiel zeigt, wie das geht:

Kotlin

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

billingClient.queryProductDetailsAsync(queryProductDetailsParams) {
    billingResult,
    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.
               }
            }
}

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 success 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 enthält, die in der Google Play Console erstellt wurden, sowie eine ProductType. Die ProductType kann entweder ProductType.INAPP für Einmalkaufprodukte oder ProductType.SUBS für Abos sein.

Abfrage mit Kotlin-Erweiterungen

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

queryProductDetails() verwendet Kotlin-Coroutinen, sodass Sie keinen separaten Listener definieren müssen. Stattdessen wird die Funktion angehalten, bis die Abfrage abgeschlossen ist. Danach 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 werden ProductDetails und queryProductDetailsAsync() auf einigen Geräten nicht unterstützt, in der Regel aufgrund veralteter Versionen der Google Play-Dienste. Informationen zur Unterstützung dieses Szenarios finden Sie im Migrationsleitfaden für die Play Billing Library 7.

Ergebnis verarbeiten

Die Google Play Billing Library speichert die Abfrageergebnisse in einem QueryProductDetailsResult-Objekt. QueryProductDetailsResult enthält ein List von ProductDetails-Objekten. Anschließend können Sie für jedes ProductDetails-Objekt in der Liste verschiedene Methoden aufrufen, um relevante Informationen zu einem erfolgreich abgerufenen Einmalprodukt aufzurufen, z. B. den Preis oder die Beschreibung. Die verfügbaren Produktdetailinformationen finden Sie in der Liste der Methoden in der Klasse ProductDetails.

QueryProductDetailsResult enthält auch ein List mit UnfetchedProduct-Objekten. Anschließend können Sie für jedes UnfetchedProduct einen Statuscode abfragen, der dem Grund für den Abruffehler entspricht. Die verfügbaren, nicht abgerufenen Produktinformationen finden Sie in der Liste der Methoden in der Klasse UnfetchedProduct.

Bevor Sie ein Element zum Verkauf anbieten, prüfen Sie, ob der Nutzer es nicht bereits besitzt. Wenn der Nutzer einen verbrauchbaren Artikel hat, der sich noch in seiner Artikelbibliothek befindet, muss er ihn verwenden, bevor er ihn noch einmal kaufen kann.

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

  • Für Abos gibt die Methode queryProductDetailsAsync() Details zum Abo-Produkt und maximal 50 für den Nutzer infrage kommende Angebote pro Abo zurück. Wenn der Nutzer versucht, ein nicht berechtigtes Angebot zu kaufen (z. B. wenn in der App eine veraltete Liste mit berechtigten Angeboten angezeigt wird), informiert Play den Nutzer darüber, dass er nicht berechtigt ist. Der Nutzer kann dann stattdessen das Basis-Abo kaufen.

  • Bei Einmalkaufprodukten gibt die Methode queryProductDetailsAsync() nur die für den Nutzer infrage kommenden Angebote zurück. Wenn der Nutzer versucht, ein Angebot zu kaufen, für das er nicht berechtigt ist (z. B. wenn er das Kaufmengenlimit erreicht hat), informiert Play ihn darüber. Der Nutzer kann dann stattdessen das Angebot für die Kaufoption kaufen.

Kaufvorgang starten

Rufen Sie die Methode launchBillingFlow() im Hauptthread Ihrer App auf, um eine Kaufanfrage zu starten. Diese Methode akzeptiert einen Verweis auf ein BillingFlowParams-Objekt, das das relevante ProductDetails-Objekt enthält, das durch Aufrufen von queryProductDetailsAsync abgerufen wurde. Verwenden Sie die Klasse BillingFlowParams.Builder, um ein BillingFlowParams-Objekt zu erstellen.

Kotlin

// An activity reference from which the billing flow will be launched.
val activity : Activity = ...;

val productDetailsParamsList = listOf(
    BillingFlowParams.ProductDetailsParams.newBuilder()
        // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
        .setProductDetails(productDetails)
        // Get the offer token:
        // a. For one-time products, call ProductDetails.getOneTimePurchaseOfferDetailsList()
        // for a list of offers that are available to the user.
        // b. For subscriptions, call ProductDetails.subscriptionOfferDetails()
        // for a list of offers that are available to the user.
        .setOfferToken(selectedOfferToken)
        .build()
)

val billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build()

// Launch the billing flow
val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

Java

// An activity reference from which the billing flow will be launched.
Activity activity = ...;

ImmutableList<ProductDetailsParams> productDetailsParamsList =
    ImmutableList.of(
        ProductDetailsParams.newBuilder()
             // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
            .setProductDetails(productDetails)
            // Get the offer token:
            // a. For one-time products, call ProductDetails.getOneTimePurchaseOfferDetailsList()
            // for a list of offers that are available to the user.
            // b. For subscriptions, call ProductDetails.subscriptionOfferDetails()
            // for a list of offers that are available to the user.
            .setOfferToken(selectedOfferToken)
            .build()
    );

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build();

// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

Die Methode launchBillingFlow() gibt einen von mehreren 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 von OK gibt an, dass der Start erfolgreich war.

Wenn der Aufruf von launchBillingFlow() erfolgreich ist, 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 gekauft werden kann.
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 initialisiert haben.

Sie müssen onPurchasesUpdated() implementieren, um mögliche Antwortcodes zu verarbeiten. Im folgenden Beispiel wird gezeigt, wie onPurchasesUpdated() überschrieben wird:

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 eine Bestätigung des Google Play-Kaufs angezeigt, die Abbildung 2 ähnelt.

Bildschirm für erfolgreiche Käufe bei Google Play
Abbildung 2. Bildschirm für erfolgreiche Käufe bei Google Play.

Bei einem erfolgreichen Kauf wird auch ein Kauftoken generiert. Das ist eine eindeutige Kennung, die den Nutzer und die Produkt-ID des gekauften Einmalkaufprodukts angibt. Das Kauftoken kann lokal in der App gespeichert werden. Wir empfehlen jedoch dringend, das Token an Ihren sicheren Back-End-Server zu senden, damit Sie den Kauf prüfen und Betrug verhindern können. Dieser Vorgang wird unter Käufe erkennen und verarbeiten ausführlicher beschrieben.

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

Personalisierten Preis angeben

Wenn Ihre App an Nutzer in der Europäischen Union verteilt werden kann, verwenden Sie die Methode setIsOfferPersonalized() beim Aufrufen von launchBillingFlow, um Nutzern mitzuteilen, dass der Preis eines Artikels durch automatisierte Entscheidungsfindung personalisiert wurde.

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

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

setIsOfferPersonalized() akzeptiert eine boolesche Eingabe. Wenn true, wird die Offenlegung in der Play-Benutzeroberfläche angezeigt. Wenn false, wird die Offenlegung in der Benutzeroberfläche ausgelassen. Der Standardwert ist false.

Weitere Informationen finden Sie in der Verbraucherhilfe.

Nutzerkennungen anhängen

Wenn Sie den Kaufvorgang starten, kann Ihre App alle Nutzer-IDs anhängen, die Sie für den Nutzer haben, der den Kauf tätigt. Verwenden Sie dazu obfuscatedAccountId oder obfuscatedProfileId. Eine Beispiel-ID könnte eine verschleierte Version der Anmeldung des Nutzers in Ihrem System sein. Durch Festlegen dieser Parameter kann Google Betrug erkennen. Außerdem können Sie 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 Käufen außerhalb der App wie Einlösungen von Angeboten.

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

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

Bei #1 wird onPurchasesUpdated automatisch für neue oder abgeschlossene Käufe aufgerufen, sofern Ihre 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. Es wird empfohlen, dass Ihre App versucht, eine aktive Verbindung aufrechtzuerhalten, solange sie im Vordergrund ist, damit sie zeitnah Kaufaktualisierungen erhält.

Für Schritt 2 müssen Sie BillingClient.queryPurchasesAsync() aufrufen, damit Ihre App alle Käufe verarbeitet. Es wird empfohlen, dies zu tun, wenn Ihre App eine Verbindung zur Google Play Billing Library herstellt (was beim Starten oder im Vordergrund der App empfohlen wird, wie unter BillingClient initialisieren beschrieben). Dies kann erreicht werden, indem queryPurchasesAsync aufgerufen wird, wenn ein erfolgreiches Ergebnis für onServiceConnected empfangen wird. Es ist wichtig, dieser Empfehlung zu folgen, um Ereignisse und Situationen wie die folgenden zu bewältigen:

  • Netzwerkprobleme während des Kaufs: Ein Nutzer kann einen Kauf erfolgreich abschließen und eine Bestätigung von Google erhalten, aber sein Gerät verliert die Netzwerkverbindung, bevor sein Gerät und Ihre App über die PurchasesUpdatedListener eine Benachrichtigung über den Kauf erhalten.
  • Mehrere Geräte: Ein Nutzer kauft möglicherweise einen Artikel auf einem Gerät und erwartet dann, dass er den Artikel sieht, wenn er das Gerät wechselt.
  • Käufe außerhalb Ihrer App verarbeiten: Einige Käufe, z. B. das Einlösen von Angeboten, können außerhalb Ihrer App erfolgen.
  • Übergänge des Kaufstatus verarbeiten: Ein Nutzer kann die Zahlung für einen PENDING-Kauf abschließen, während Ihre Anwendung nicht ausgeführt wird. Er erwartet dann, dass er beim Öffnen Ihrer App eine Bestätigung erhält, dass er den Kauf abgeschlossen hat.

Wenn in Ihrer App ein neuer oder abgeschlossener Kauf erkannt wird, sollte sie Folgendes tun:

  • Bestätige den Kauf.
  • Gewähren Sie dem Nutzer Zugriff auf Inhalte, die er gekauft hat.
  • Benachrichtigen Sie den Nutzer.
  • Google darüber informieren, dass Ihre App abgeschlossene Käufe verarbeitet hat

Diese Schritte werden in den folgenden Abschnitten ausführlich beschrieben. Danach folgt ein Abschnitt, in dem alle Schritte zusammengefasst werden.

Kauf bestätigen

Ihre App sollte immer die Rechtmäßigkeit von Käufen überprüfen, bevor sie einem Nutzer Vorteile gewährt. Dazu können Sie die Richtlinien unter Käufe vor dem Gewähren von Berechtigungen bestätigen befolgen. Erst nach der Bestätigung des Kaufs sollte Ihre App den Kauf weiter verarbeiten und dem Nutzer Berechtigungen gewähren. Dies wird im nächsten Abschnitt erläutert.

Dem Nutzer ein Recht gewähren

Nachdem Ihre App einen Kauf bestätigt hat, kann sie dem Nutzer weiterhin die Berechtigung gewähren und ihn benachrichtigen. Bevor du eine Berechtigung gewährst, musst du prüfen, ob deine App den Kaufstatus PURCHASED prüft. Wenn sich der Kauf im Status „AUSSTEHEND“ befindet, sollte Ihre App den Nutzer darüber informieren, dass er noch Aktionen ausführen muss, um den Kauf abzuschließen, bevor die Berechtigung gewährt wird. Gewähre die Berechtigung erst, wenn der Kauf von „PENDING“ zu „SUCCESS“ wechselt. Weitere Informationen finden Sie unter Ausstehende Transaktionen verarbeiten.

Wenn Sie dem Kauf Nutzer-IDs angehängt haben, wie unter Nutzer-IDs anhängen beschrieben, können Sie sie abrufen und verwenden, um den Kauf dem richtigen Nutzer in Ihrem System zuzuordnen. Diese Methode ist nützlich, wenn Sie Käufe abgleichen, bei denen Ihre App möglicherweise den Kontext verloren hat, für welchen Nutzer ein Kauf erfolgt ist. Hinweis: Bei Käufen, die außerhalb Ihrer App getätigt werden, werden diese Kennzeichnungen nicht festgelegt. In diesem Fall kann Ihre App entweder dem angemeldeten Nutzer die Berechtigung gewähren oder den Nutzer auffordern, ein bevorzugtes Konto auszuwählen.

Bei Vorbestellungen hat der Kauf vor dem Veröffentlichungszeitpunkt den Status „AUSSTEHEND“. Der Vorbestellungskauf wird zum Veröffentlichungszeitpunkt abgeschlossen und der Status ändert sich ohne zusätzliche Maßnahmen zu „GEKAUFT“.

Nutzer benachrichtigen

Nachdem die Berechtigung für den Nutzer erteilt wurde, sollte in Ihrer App eine Benachrichtigung angezeigt werden, um den erfolgreichen Kauf zu bestätigen. Durch die Benachrichtigung wird der Nutzer nicht darüber im Unklaren gelassen, ob der Kauf erfolgreich abgeschlossen wurde. Andernfalls könnte er die Nutzung Ihrer App einstellen, sich an den Kundensupport wenden oder sich in den sozialen Medien darüber beschweren. Ihre App kann Kaufaktualisierungen jederzeit während des Lebenszyklus der Anwendung erkennen. Wenn beispielsweise ein Elternteil einen ausstehenden Kauf auf einem anderen Gerät genehmigt, sollte Ihre App den Nutzer möglicherweise erst zu einem geeigneten Zeitpunkt benachrichtigen. Hier einige Beispiele, in denen eine Verzögerung angemessen wäre:

  • Während des Action-Teils eines Spiels oder bei Zwischensequenzen kann eine Nachricht den Nutzer ablenken. In diesem Fall müssen Sie den Nutzer nach dem Aktionsabschnitt benachrichtigen.
  • Während des ersten Tutorials und der Einrichtung des Nutzers im Spiel. Ein Nutzer hat beispielsweise einen Kauf außerhalb Ihrer App getätigt, bevor er sie installiert hat. Wir empfehlen, neue Nutzer sofort nach dem Öffnen des Spiels oder während der Ersteinrichtung über die Prämie zu informieren. Wenn der Nutzer in Ihrer App ein Konto erstellen oder sich anmelden muss, bevor er Anspruch auf den Kauf erhält, sollten Sie ihm mitteilen, welche Schritte er ausführen muss, um den Kauf zu beanspruchen. Das ist wichtig, da Käufe nach drei Tagen erstattet werden, wenn der Kauf nicht von Ihrer App verarbeitet wurde.

Wenn Sie den Nutzer über einen Kauf benachrichtigen, empfiehlt Google Play die folgenden Mechanismen:

  • Ein In-App-Dialogfeld wird angezeigt.
  • Die Nachricht wird in einem In-App-Nachrichtenfeld angezeigt. Es wird deutlich darauf hingewiesen, dass sich eine neue Nachricht im In-App-Nachrichtenfeld befindet.
  • Verwenden Sie eine Betriebssystembenachrichtigung.

In der Benachrichtigung sollte der Nutzer über den erhaltenen Vorteil informiert werden. Beispiel: „Du hast 100 Goldmünzen gekauft.“ Außerdem wird dem Nutzer mitgeteilt, wenn der Kauf auf einem Vorteil eines Programms wie Play Pass beruht. Beispiel: „Artikel erhalten! Du hast gerade 100 Juwelen mit Play Pass erhalten. Weiter“. Für jedes Programm gibt es möglicherweise Richtlinien zum empfohlenen Text, der Nutzern angezeigt werden soll, um Vorteile zu kommunizieren.

Google benachrichtigen, dass der Kauf verarbeitet wurde

Nachdem Ihre App dem Nutzer die Berechtigung erteilt und ihn über die erfolgreiche Transaktion informiert hat, muss sie Google benachrichtigen, dass der Kauf erfolgreich verarbeitet wurde. Dazu müssen Sie den Kauf bestätigen. Das muss innerhalb von drei Tagen erfolgen, damit der Kauf nicht automatisch erstattet und die Berechtigung widerrufen wird. Der Vorgang zum Bestätigen verschiedener Arten von Käufen wird in den folgenden Abschnitten beschrieben.

Verbrauchsprodukte

Wenn Ihre App ein sicheres Backend hat, empfehlen wir für Verbrauchsmaterialien die Verwendung von Purchases.products:consume, um Käufe zuverlässig zu verbrauchen. Prüfen Sie, ob der Kauf bereits verbraucht wurde. Rufen Sie dazu Purchases.products:get auf und prüfen Sie das Ergebnis auf consumptionState. Wenn Ihre App nur clientseitig ohne Backend ist, verwenden Sie consumeAsync() aus der Google Play Billing Library. Beide Methoden erfüllen die Bestätigungsanforderung und geben an, dass Ihrer App dem Nutzer ein Recht gewährt hat. Mit diesen Methoden kann Ihre App das Einmalkaufprodukt, das dem eingegebenen Kauf-Token entspricht, auch für einen erneuten Kauf verfügbar machen. Bei consumeAsync() müssen Sie auch ein Objekt übergeben, das die ConsumeResponseListener-Schnittstelle implementiert. Dieses Objekt enthält das Ergebnis des Verbrauchsvorgangs. Sie können die Methode onConsumeResponse() überschreiben, die von der Google Play Billing Library aufgerufen wird, wenn der Vorgang abgeschlossen ist.

Das folgende Beispiel veranschaulicht die Nutzung eines Produkts mit der Google Play Billing Library mithilfe des zugehörigen Kauf-Tokens:

Kotlin

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

Java

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

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

    billingClient.consumeAsync(consumeParams, listener);

Nicht konsumierbare Produkte

Wenn Ihre App ein sicheres Backend hat, empfehlen wir, nicht verbrauchbare Käufe mit Purchases.products:acknowledge zu bestätigen. Prüfen Sie, ob der Kauf bereits bestätigt wurde, indem Sie das acknowledgementState im Ergebnis des Aufrufs von Purchases.products:get prüfen.

Wenn Ihre App nur auf dem Client ausgeführt wird, verwenden Sie BillingClient.acknowledgePurchase() aus der Google Play Billing Library in Ihrer App. Bevor Sie einen Kauf bestätigen, sollte Ihre App mit der Methode isAcknowledged() in der Google Play Billing Library prüfen, ob er bereits bestätigt wurde.

Das folgende Beispiel zeigt, wie ein Kauf mit der Google Play Billing Library bestätigt wird:

Kotlin

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

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

Java

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

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

Abos

Abos werden ähnlich wie nicht verbrauchbare Produkte behandelt. Verwenden Sie nach Möglichkeit Purchases.subscriptions.acknowledge aus der Google Play Developer API, um den Kauf zuverlässig über Ihr sicheres Backend zu bestätigen. Prüfe, ob der Kauf bereits bestätigt wurde. Sieh dazu in der Kaufressource unter Purchases.subscriptions:get nach, ob acknowledgementState vorhanden ist. Andernfalls können Sie ein Abo mit BillingClient.acknowledgePurchase() aus der Google Play Billing Library bestätigen, nachdem Sie isAcknowledged() geprüft haben. Alle ersten Abo-Kä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 Abos verkaufen.

Zusammenfassung

Das folgende Code-Snippet fasst diese Schritte zusammen.

Kotlin

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

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

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

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

Java

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

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

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

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

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

Hier finden Sie eine Anleitung zum Testen, mit der Sie überprüfen können, ob diese Schritte in Ihrer App korrekt implementiert wurden.

Ausstehende Transaktionen verarbeiten

Google Play unterstützt ausstehende Transaktionen. Das sind Transaktionen, bei denen zwischen dem Zeitpunkt, zu dem ein Nutzer einen Kauf initiiert, und dem Zeitpunkt, zu dem die Zahlungsmethode für den Kauf verarbeitet wird, ein oder mehrere zusätzliche Schritte erforderlich sind. Ihre App sollte erst dann Zugriff auf diese Arten von Käufen gewähren, wenn Google Sie darüber informiert, dass die Zahlungsmethode des Nutzers erfolgreich belastet wurde.

Ein Nutzer kann beispielsweise eine Transaktion starten, indem er ein Ladengeschäft auswählt, in dem er später bar bezahlen möchte. Der Nutzer erhält einen Code sowohl per 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 Sie und den Nutzer dann, dass die Zahlung eingegangen ist. Ihre App kann dem Nutzer dann das Recht gewähren.

Rufen Sie enablePendingPurchases() im Rahmen der Initialisierung von BillingClient auf, um ausstehende Transaktionen für Ihre App zu aktivieren. Ihre App muss ausstehende Transaktionen für Einmalkaufprodukte aktivieren und unterstützen. Bevor Sie Unterstützung hinzufügen, sollten Sie sich mit dem Kauflebenszyklus für ausstehende Transaktionen vertraut machen.

Wenn Ihre App einen neuen Kauf erhält, entweder über Ihre PurchasesUpdatedListener oder als Ergebnis des Aufrufs von queryPurchasesAsync, verwenden Sie die Methode getPurchaseState(), um festzustellen, ob der Kaufstatus PURCHASED oder PENDING ist. Du solltest die Berechtigung nur erteilen, wenn der Status PURCHASED ist.

Wenn Ihre App ausgeführt wird und Sie eine aktive Play Billing Library-Verbindung haben, wenn der Nutzer den Kauf abschließt, wird PurchasesUpdatedListener noch einmal aufgerufen und PurchaseState ist jetzt PURCHASED. An diesem Punkt kann Ihre App den Kauf mit der Standardmethode zum Erkennen und Verarbeiten von Käufen verarbeiten. Ihre App sollte außerdem die Methode queryPurchasesAsync() in der Methode onResume() 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 Ihr Echtzeit-Entwicklerbenachrichtigungen-Client eine ONE_TIME_PRODUCT_PURCHASED- oder SUBSCRIPTION_PURCHASED-Benachrichtigung. Wenn der Kauf storniert wird, erhalten Sie eine Benachrichtigung ONE_TIME_PRODUCT_CANCELED oder SUBSCRIPTION_PENDING_PURCHASE_CANCELED. Das kann passieren, wenn Ihr Kunde die Zahlung nicht innerhalb des erforderlichen Zeitrahmens abschließt. Sie können jederzeit die Google Play Developer API verwenden, um den aktuellen Status eines Kaufs zu prüfen.

Käufe in variabler Stückzahl verarbeiten

In Version 4.0 und höher der Google Play Billing Library können Kunden bei Google Play mehr als ein Einmalkaufprodukt in einer Transaktion kaufen, indem sie im Einkaufswagen eine Menge angeben. Ihre App muss Käufe mit mehreren Artikeln verarbeiten und Berechtigungen basierend auf der angegebenen Kaufmenge gewähren.

Damit Käufe mit mehreren Artikeln berücksichtigt werden, muss in der Bereitstellungslogik Ihrer App die Artikelmenge geprüft werden. Sie können über eine der folgenden APIs auf ein quantity-Feld zugreifen:

Nachdem Sie die Logik für den Umgang mit Käufen in mehreren Mengen hinzugefügt haben, müssen Sie die Funktion für das entsprechende Produkt auf der Seite zur Verwaltung einmaliger Produkte in der Google Play 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 ein BillingClient erstellt haben. Das folgende Code-Snippet zeigt, wie ein Aufruf an getBillingConfigAsync() erfolgt. Verarbeiten Sie die Antwort, indem Sie BillingConfigResponseListener implementieren. Dieser Listener empfängt 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 Play-Land des Nutzers zu ermitteln.

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

Erinnerungen an abgebrochene Einkäufe auf der Startseite von Google Play Spiele (standardmäßig aktiviert)

Für Spieleentwickler, die ihre Inhalte über Einmalkäufe monetarisieren, ist die Erinnerungsfunktion an abgebrochene Einkäufe eine Möglichkeit, Artikelnummern (Stock-Keeping Units, SKUs), die in der Google Play Console aktiv sind, außerhalb der App zu verkaufen. Mit dieser Funktion werden Nutzer daran erinnert, zuvor abgebrochene Käufe abzuschließen, während sie im Google Play Store nach Inhalten suchen. Diese Käufe erfolgen außerhalb Ihrer App über die Google Play Spiele-Startseite im Google Play Store.

Diese Funktion ist standardmäßig aktiviert, damit Nutzer dort weitermachen können, wo sie aufgehört haben, und Entwickler ihren Umsatz maximieren können. Sie können die Funktion jedoch für Ihre App deaktivieren, indem Sie das Deaktivierungsformular für die Erinnerungsfunktion an abgebrochene Einkäufe einreichen. Best Practices für die Verwaltung von Artikelnummern in der Google Play Console finden Sie unter In-App-Produkte erstellen.

Die folgenden Bilder zeigen die Erinnerung an abgebrochene Einkäufe im Google Play Store:

Auf dem Google Play Store-Bildschirm wird eine Kaufaufforderung für einen zuvor abgebrochenen Kauf angezeigt.
Abbildung 2. Auf dem Google Play Store-Bildschirm wird eine Kaufaufforderung für einen zuvor abgebrochenen Kauf angezeigt.

Auf dem Google Play Store-Bildschirm wird eine Kaufaufforderung für einen zuvor abgebrochenen Kauf angezeigt.
Abbildung 3. Auf dem Google Play Store-Bildschirm wird eine Kaufaufforderung für einen zuvor abgebrochenen Kauf angezeigt.