Wenn ein Play Billing Library-Aufruf eine Aktion auslöst, gibt die Bibliothek eine
BillingResult
um die Entwickelnden über das Ergebnis zu informieren. Wenn Sie beispielsweise
queryProductDetailsAsync
um die verfügbaren Angebote für den Nutzer abzurufen, enthält der Antwortcode entweder
OK Code und gibt den richtigen ProductDetails
an
oder eine andere Antwort enthält, mit der der Grund
ProductDetails
Objekt konnte nicht angegeben werden.
Nicht alle Antwortcodes sind Fehler. Die BillingResponseCode
enthält eine detaillierte Beschreibung der einzelnen Antworten,
die in diesem Leitfaden erläutert werden.
Hier einige Beispiele für Antwortcodes, die keine Fehler enthalten:
BillingClient.BillingResponseCode.OK
: Die durch den Aufruf ausgelöste Aktion wurde erfolgreich abgeschlossen.BillingClient.BillingResponseCode.USER_CANCELED
: Bei Aktionen, bei denen dem Nutzer die Play Store-Benutzeroberfläche angezeigt wird, wird diese Antwort zeigt an, dass Nutzende diese UI-Abläufe verlassen haben, ohne den .
Wenn der Antwortcode einen Fehler anzeigt, ist die Ursache manchmal
vorübergehenden Erkrankungen, sodass eine Wiederherstellung möglich ist. Wenn ein Aufruf von Google Play
Billing Library-Methode gibt BillingResponseCode
zurück.
angegeben ist, der auf einen wiederherstellbaren Zustand hinweist, sollten Sie den Aufruf wiederholen. In
In anderen Fällen gelten Bedingungen nicht als vorübergehend.
wird nicht empfohlen.
Vorübergehende Fehler erfordern unterschiedliche Wiederholungsstrategien, die von Faktoren wie
Ob der Fehler auftritt, wenn sich Nutzer in einer Sitzung befinden, z. B. wenn ein Nutzer
die einen Kaufvorgang durchlaufen – oder der Fehler tritt im Hintergrund auf –
Das ist beispielsweise der Fall, wenn Sie die vorhandenen Käufe des Nutzers im Zeitraum onResume
abfragen.
Im Abschnitt zu Wiederholungsstrategien unten finden Sie Beispiele für
diese verschiedenen Strategien und das Tool „Retriable“ BillingResult
Abschnitt zu Antworten
empfiehlt, welche Strategie für den jeweiligen Antwortcode am besten funktioniert.
Neben dem Antwortcode enthalten einige Fehlermeldungen auch Meldungen für Debugging- und Logging-Zwecken.
Wiederholungsstrategien
Einfache Wiederholung
In Situationen, in denen sich der Nutzer in einer Sitzung befindet, ist es besser, eine einfache Wiederholungsstrategie so, dass der Fehler die Nutzererfahrung nur so wenig möglich. In diesem Fall empfehlen wir eine einfache Wiederholungsstrategie mit einem Anzahl der Versuche als Exit-Bedingung.
Das folgende Beispiel zeigt eine einfache Wiederholungsstrategie zur Fehlerbehandlung
beim Einrichten eines BillingClient
Verbindung:
class BillingClientWrapper(context: Context) : PurchasesUpdatedListener {
// Initialize the BillingClient.
private val billingClient = BillingClient.newBuilder(context)
.setListener(this)
.enablePendingPurchases()
.build()
// Establish a connection to Google Play.
fun startBillingConnection() {
billingClient.startConnection(object : BillingClientStateListener {
override fun onBillingSetupFinished(billingResult: BillingResult) {
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
Log.d(TAG, "Billing response OK")
// The BillingClient is ready. You can now query Products Purchases.
} else {
Log.e(TAG, billingResult.debugMessage)
retryBillingServiceConnection()
}
}
override fun onBillingServiceDisconnected() {
Log.e(TAG, "GBPL Service disconnected")
retryBillingServiceConnection()
}
})
}
// Billing connection retry logic. This is a simple max retry pattern
private fun retryBillingServiceConnection() {
val maxTries = 3
var tries = 1
var isConnectionEstablished = false
do {
try {
billingClient.startConnection(object : BillingClientStateListener {
override fun onBillingSetupFinished(billingResult: BillingResult) {
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
isConnectionEstablished = true
Log.d(TAG, "Billing connection retry succeeded.")
} else {
Log.e(
TAG,
"Billing connection retry failed: ${billingResult.debugMessage}"
)
}
}
})
} catch (e: Exception) {
e.message?.let { Log.e(TAG, it) }
tries++
}
} while (tries <= maxTries && !isConnectionEstablished)
}
...
}
Exponentieller Backoff-Wiederholung
Wir empfehlen die Verwendung des exponentiellen Backoffs für Play Billing Library-Vorgänge, die erfolgen im Hintergrund und haben keine Auswirkungen auf die User Experience, in der Sitzung.
Diese Vorgehensweise wäre beispielsweise sinnvoll, wenn Sie neue Käufe tätigen, weil dieser Vorgang im Hintergrund erfolgen kann Bestätigung muss nicht in Echtzeit erfolgen, wenn ein Fehler auftritt.
private fun acknowledge(purchaseToken: String): BillingResult {
val params = AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchaseToken)
.build()
var ackResult = BillingResult()
billingClient.acknowledgePurchase(params) { billingResult ->
ackResult = billingResult
}
return ackResult
}
suspend fun acknowledgePurchase(purchaseToken: String) {
val retryDelayMs = 2000L
val retryFactor = 2
val maxTries = 3
withContext(Dispatchers.IO) {
acknowledge(purchaseToken)
}
AcknowledgePurchaseResponseListener { acknowledgePurchaseResult ->
val playBillingResponseCode =
PlayBillingResponseCode(acknowledgePurchaseResult.responseCode)
when (playBillingResponseCode) {
BillingClient.BillingResponseCode.OK -> {
Log.i(TAG, "Acknowledgement was successful")
}
BillingClient.BillingResponseCode.ITEM_NOT_OWNED -> {
// This is possibly related to a stale Play cache.
// Querying purchases again.
Log.d(TAG, "Acknowledgement failed with ITEM_NOT_OWNED")
billingClient.queryPurchasesAsync(
QueryPurchasesParams.newBuilder()
.setProductType(BillingClient.ProductType.SUBS)
.build()
)
{ billingResult, purchaseList ->
when (billingResult.responseCode) {
BillingClient.BillingResponseCode.OK -> {
purchaseList.forEach { purchase ->
acknowledge(purchase.purchaseToken)
}
}
}
}
}
in setOf(
BillingClient.BillingResponseCode.ERROR,
BillingClient.BillingResponseCode.SERVICE_DISCONNECTED,
BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE,
) -> {
Log.d(
TAG,
"Acknowledgement failed, but can be retried --
Response Code: ${acknowledgePurchaseResult.responseCode} --
Debug Message: ${acknowledgePurchaseResult.debugMessage}"
)
runBlocking {
exponentialRetry(
maxTries = maxTries,
initialDelay = retryDelayMs,
retryFactor = retryFactor
) { acknowledge(purchaseToken) }
}
}
in setOf(
BillingClient.BillingResponseCode.BILLING_UNAVAILABLE,
BillingClient.BillingResponseCode.DEVELOPER_ERROR,
BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED,
) -> {
Log.e(
TAG,
"Acknowledgement failed and cannot be retried --
Response Code: ${acknowledgePurchaseResult.responseCode} --
Debug Message: ${acknowledgePurchaseResult.debugMessage}"
)
throw Exception("Failed to acknowledge the purchase!")
}
}
}
}
private suspend fun <T> exponentialRetry(
maxTries: Int = Int.MAX_VALUE,
initialDelay: Long = Long.MAX_VALUE,
retryFactor: Int = Int.MAX_VALUE,
block: suspend () -> T
): T? {
var currentDelay = initialDelay
var retryAttempt = 1
do {
runCatching {
delay(currentDelay)
block()
}
.onSuccess {
Log.d(TAG, "Retry succeeded")
return@onSuccess;
}
.onFailure { throwable ->
Log.e(
TAG,
"Retry Failed -- Cause: ${throwable.cause} -- Message: ${throwable.message}"
)
}
currentDelay *= retryFactor
retryAttempt++
} while (retryAttempt < maxTries)
return block() // last attempt
}
Retriable BillingResult-Antworten
NETWORK_ERROR (Fehlercode 12)
Problem
Dieser Fehler weist auf ein Problem mit der Netzwerkverbindung hin. zwischen dem Gerät und den Play-Systemen.
Mögliche Lösung
Verwenden Sie zur Wiederherstellung einfache Wiederholungsversuche oder einen exponentiellen Backoff, je nachdem, Aktion hat den Fehler ausgelöst.
SERVICE_TIMEOUT (Fehlercode -3)
Problem
Dieser Fehler gibt an, dass die Anfrage das maximale Zeitlimit erreicht hat vor Google Play kann Ihnen antworten. Das kann z. B. an einer Verzögerung der vom Play Billing Library-Aufruf angeforderten Aktion ausgeführt wird.
Mögliche Lösung
Dies ist in der Regel ein vorübergehendes Problem. Wiederholen Sie die Anfrage entweder mit einem einfache oder exponentielle Backoff-Strategie, je nachdem, welche Aktion den Fehler.
„Gefällt mir“-Angabe für SERVICE_DISCONNECTED
entfernen
ist die Verbindung zum Google Play Billing-Dienst nicht getrennt und Sie
Sie müssen nur den versuchten Play Billing Library-Vorgang wiederholen.
SERVICE_DISCONNECTED (Fehlercode -1)
Problem
Dieser schwerwiegende Fehler weist darauf hin, dass die Verbindung der Client-App mit Google Play
Store-Dienst über die BillingClient
abgegrenzt wurde.
Mögliche Lösung
Überprüfen Sie immer die Verbindung zu Google, um diesen Fehler so gut wie möglich zu vermeiden.
Google Play-Dienste aktivieren, bevor du Anrufe über die Play Billing Library tätigst, indem du folgenden Befehl aufrufst:
BillingClient.isReady()
Wiederherstellung ab SERVICE_DISCONNECTED
festgelegt ist, sollte Ihre Client-App versuchen, die Verbindung mithilfe von
BillingClient.startConnection
Genau wie bei SERVICE_TIMEOUT
, einfache Wiederholungsversuche oder exponentiellen Backoff verwenden, je nachdem, welche Aktion ausgelöst wurde
Fehler.
SERVICE_UNAVAILABLE (Fehlercode 2)
Wichtiger Hinweis:
Ab Google Play Billing Library 6.0.0 ist SERVICE_UNAVAILABLE
keine
bei Netzwerkproblemen länger zurückgeliefert. Sie wird zurückgegeben, wenn der Abrechnungsdienst
nicht verfügbar und die eingestellten SERVICE_TIMEOUT
-Fallszenarien.
Problem
Dieser vorübergehende Fehler weist darauf hin, dass der Google Play Billing-Dienst derzeit nicht verfügbar. In den meisten Fällen liegt ein Problem mit der Netzwerkverbindung vor. irgendwo zwischen dem Clientgerät und den Google Play Billing-Diensten.
Mögliche Lösung
Dies ist in der Regel ein vorübergehendes Problem. Wiederholen Sie die Anfrage entweder mit einem einfache oder exponentielle Backoff-Strategie, je nachdem, welche Aktion den Fehler.
„Gefällt mir“-Angabe für SERVICE_DISCONNECTED
entfernen
ist die Verbindung zum Google Play Billing-Dienst nicht getrennt und Sie benötigen
um den gerade auszuführenden Vorgang zu wiederholen.
BILLING_UNAVAILABLE (Fehlercode 3)
Problem
Dieser Fehler gibt an, dass während der Kaufprozess. Das kann unter anderem in folgenden Fällen passieren:
- Die Play Store App auf dem Gerät des Nutzers ist veraltet.
- Der Nutzer befindet sich in einem nicht unterstützten Land.
- Der Nutzer ist Unternehmensnutzer und sein Unternehmensadministrator hat Nutzer deaktiviert von Käufen zu verhindern.
- Google Play kann die Zahlungsmethode des Nutzers nicht belasten. Beispiel: Der Parameter Die Kreditkarte des Nutzers ist möglicherweise abgelaufen.
Mögliche Lösung
In diesem Fall sind automatische Wiederholungsversuche wahrscheinlich nicht hilfreich. Ein manueller Wiederholungsversuch kann jedoch Hilfe, wenn der Nutzer die Ursache des Problems behoben hat. Wenn beispielsweise der Nutzer seine Play Store-Version auf eine unterstützte Version aktualisiert, wenn Sie den ersten Vorgang wiederholen.
Wenn dieser Fehler auftritt, während sich der Nutzer nicht in einer Sitzung befindet, führt ein neuer Versuch möglicherweise nicht dazu,
Sinn.
Wenn Sie eine BILLING_UNAVAILABLE
erhalten,
Fehler infolge des Kaufvorgangs verursacht hat, ist es sehr wahrscheinlich, dass der Nutzer
Feedback von Google Play während des Kaufvorgangs erhalten und möglicherweise wissen,
ist schiefgelaufen. In diesem Fall wird möglicherweise eine Fehlermeldung
ist ein Fehler aufgetreten. Dem Nutzer wurde die Schaltfläche „Erneut versuchen“ angeboten, über die er
noch einmal versuchen, nachdem sie
das Problem behoben haben.
ERROR (Fehlercode 6)
Problem
Dies ist ein schwerwiegender Fehler, der auf ein internes Problem mit Google Play hinweist selbst.
Mögliche Lösung
Manchmal treten interne Google Play-Probleme auf, die zu ERROR
führen.
sind vorübergehend und ein Wiederholungsversuch mit einem exponentiellen Backoff kann für
und Risikominderung. Während einer Sitzung empfiehlt sich eine einfache Wiederholung.
ARTIKEL_BEREITS_EINGESTELLT
Problem
Diese Antwort gibt an, dass der Google Play-Nutzer bereits Eigentümer des ein Produkt abonnieren oder einen einmaligen Kauf tätigen möchten. In den meisten Fällen ist dies kein vorübergehender Fehler, es sei denn, er wird durch einen veralteter Google Play-Cache.
Mögliche Lösung
Um zu vermeiden, dass dieser Fehler auftritt, wenn die Ursache kein Cache-Problem ist, sollten Sie keinen
das Produkt zum Kauf anbieten,
wenn es der Nutzenden bereits gehört. Stellen Sie sicher, dass die
Nutzerberechtigungen, wenn Sie die zum Kauf verfügbaren Produkte anzeigen
filtern, was Nutzende entsprechend kaufen können.
Wenn die Client-App diesen Fehler aufgrund eines Cache-Problems erhält, wird der Fehler ausgelöst.
den Cache von Google Play, um mit den neuesten Daten aus dem Google Play-Backend aktualisiert zu werden.
Durch einen neuen Versuch nach dem Fehler sollte diese vorübergehende Instanz
Fall. BillingClient.queryPurchasesAsync()
anrufen
nachdem ein ITEM_ALREADY_OWNED
ob die Nutzenden das Produkt erworben haben
Implementieren Sie eine einfache Wiederholungslogik, um den Kauf erneut zu versuchen.
NICHT_EIGENEN ARTIKEL
Problem
Diese Kaufantwort gibt an, dass der Google Play-Nutzer nicht der Inhaber des Abo- oder Einmalkaufprodukt, das der Nutzer ersetzen möchte, zu bestätigen oder zu konsumieren. Dies ist in den meisten Fällen kein vorübergehender Fehler, es sei denn, er wird von Google verursacht Der Cache von Google Play ist veraltet.
Mögliche Lösung
Wenn der Fehler aufgrund eines Cache-Problems auftritt, löst der Fehler Google aus
Google Play-Cache, um mit den neuesten Daten aus dem Google Play-Backend aktualisiert zu werden. Wird wiederholt
mit einer einfachen Wiederholungsstrategie
nach dem Fehler beheben,
vorübergehende Instanz. Rufen Sie BillingClient.queryPurchasesAsync()
auf, nachdem Sie eine ITEM_NOT_OWNED
erhalten haben, um zu prüfen, ob der Nutzer
das Produkt erworben hat. Ist dies nicht der Fall, verwenden Sie eine einfache Wiederholungslogik, um den
kaufen.
Nicht abrufbare BillingResult-Antworten
Diese Fehler können nicht mithilfe einer Wiederholungslogik behoben werden.
NICHT_UNTERSTÜTZTE_FUNKTION
Problem
Dieser nicht wiederholbare Fehler weist darauf hin, dass die Google Play Billing-Funktion nicht wird auf dem Gerät des Nutzers unterstützt, wahrscheinlich aufgrund einer alten Play Store-Version.
Zum Beispiel könnten die Geräte unterstützen In-App-Messaging nicht.
Mögliche Abhilfe
Verwende BillingClient.isFeatureSupported()
, um die unterstützten Funktionen zu prüfen, bevor du Play Billing anrufst
Mediathek.
when {
billingClient.isReady -> {
if (billingClient.isFeatureSupported(BillingClient.FeatureType.IN_APP_MESSAGING)) {
// use feature
}
}
}
NUTZER_ABGEBROCHEN
Problem
Der Nutzer hat die Benutzeroberfläche des Abrechnungsvorgangs verlassen.
Mögliche Lösung
Dies dient nur zur Information und kann ordnungsgemäß fehlschlagen.
ARTIKEL_NICHT VERFÜGBAR
Problem
Das Google Play Billing-Abo oder das Produkt für einmaligen Kauf ist nicht für diesen Nutzer zum Kauf verfügbar.
Mögliche Abhilfe
Achten Sie darauf, dass die Produktdetails in Ihrer App wie empfohlen über queryProductDetailsAsync
aktualisiert werden. Berücksichtigen Sie, wie oft
Änderungen am Produktkatalog an der Play Console-Konfiguration,
zusätzliche Aktualisierungen.
Versuchen Sie nur, Produkte über Google Play Billing zu verkaufen, die das Recht zurückgeben,
Informationen über queryProductDetailsAsync
.
Prüfen Sie die Konfiguration der Produkteignung auf Inkonsistenzen.
Sie könnten z. B. nach einem Produkt suchen, das nur für eine
die der Nutzer kaufen möchte.
Damit ein Produkt gekauft werden kann, muss es aktiv und die zugehörige App
veröffentlicht wurden und die App im Land des Nutzers verfügbar sein muss.
Manchmal, insbesondere während der Tests, ist im Produkt alles korrekt. Konfiguration, aber Nutzern wird dieser Fehler weiterhin angezeigt. Mögliche Gründe die Übertragung der Produktdetails auf den Google-Servern verzögert. Noch einmal versuchen .
ENTWICKLERFEHLER
Problem
Dies ist ein schwerwiegender Fehler, der darauf hinweist, dass Sie eine API nicht ordnungsgemäß verwenden.
Beispielsweise kann die Angabe falscher Parameter für BillingClient.launchBillingFlow
diesen Fehler verursacht.
Mögliche Lösung
Prüfe, ob du die andere Play Billing Library korrekt verwendest Anrufe. Weitere Informationen zum Fehler finden Sie in der Debug-Meldung.