Play Faturalandırma Kitaplığı çağrısı bir işlemi tetiklediğinde kitaplık, geliştiricileri sonucu hakkında bilgilendirmek için bir BillingResult
yanıtı döndürür. Örneğin,
queryProductDetailsAsync
kullanıcıya sunulan teklifleri almak için yanıt kodu
Tamam kodu ve doğru ProductDetails
değerini sağlar
ya da hatanın nedenini belirten farklı bir yanıt içeriyorsa
ProductDetails
nesne sağlanamadı.
Tüm yanıt kodları hata değildir. Bu kılavuzda ele alınan yanıtların her biri BillingResponseCode
referans sayfasında ayrıntılı olarak açıklanmaktadır.
Hata belirtmeyen yanıt kodu örneklerinden bazıları şunlardır:
BillingClient.BillingResponseCode.OK
: Arama tarafından tetiklenen işlem başarıyla tamamlandı.BillingClient.BillingResponseCode.USER_CANCELED
: Kullanıcıya Play Store kullanıcı arayüzü akışlarını gösteren işlemler için bu yanıt, kullanıcının işlemi tamamlamadan bu kullanıcı arayüzü akışlarından ayrıldığını gösterir.
Yanıt kodu bir hata belirttiğinde, bunun nedeni bazen
geçici koşullar olduğunu ve dolayısıyla iyileşmenin mümkün olduğunu unutmayın. Play Billing Library yöntemine yapılan bir çağrı, kurtarılabilir bir durumu belirten bir BillingResponseCode
değeri döndürdüğünde çağrıyı yeniden denemeniz gerekir. Diğer durumlarda, koşullar geçici olarak kabul edilmez ve bu nedenle yeniden deneme önerilmez.
Geçici hatalar, deneme gibi unsurlara bağlı olarak farklı yeniden deneme stratejileri gerektirir.
hatanın, kullanıcılar oturumdayken mi (örneğin, kullanıcı oturumundaki
devam ederken (veya hata arka planda gerçekleşirse)
Örneğin, onResume
sırasında kullanıcının mevcut satın alma işlemlerini sorguladığınızda.
Aşağıdaki yeniden deneme stratejileri bölümünde,
Bu farklı stratejiler ve Retriable BillingResult
Yanıtlar bölümü
Her yanıt kodu için en uygun stratejinin hangisi olduğunu önerir.
Bazı hata yanıtları, yanıt koduna ek olarak hata ayıklama ve günlük kaydı amacıyla mesajlar içerir.
Yeniden deneme stratejileri
Basit yeniden deneme
Kullanıcının oturumda olduğu durumlarda, basit bir kesintiye uğratmasını sağlamak için yeniden deneme yapmasını sağlar. Bu durumda, çıkış koşulu olarak maksimum deneme sayısı içeren basit bir yeniden deneme stratejisi kullanmanızı öneririz.
Aşağıdaki örnekte, bir hatayı işlemek için basit bir yeniden deneme stratejisi gösterilmektedir
BillingClient
oluştururken
bağlantı:
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)
}
...
}
Üstel geri yüklemeyi yeniden deneme
Şu özelliklere sahip Play Faturalandırma Kitaplığı işlemleri için eksponansiyel geri yükleme kullanmanızı öneririz: arka planda gerçekleştiğinden ve kullanıcı işlem yaparken kullanıcı deneyimini devam ediyor.
Örneğin, yeni müşterileri kabul ederken bunu uygulamak uygun olur. gerçekleşebilir. Bu işlem arka planda gerçekleşebileceği için, bir hata oluşursa onayın gerçek zamanlı olarak gerçekleşmesi gerekmez.
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
}
Yeniden Kullanılabilir BillingResult yanıtları
NETWORK_ERROR (Hata Kodu 12)
Sorun
Bu hata, ağ bağlantısında bir sorun olduğunu gösterir Google Play sistemleri arasında.
Olası çözüm
Kurtarmak için, hangisinin bağlı olduğuna bağlı olarak basit yeniden deneme veya eksponansiyel geri yükleme yöntemini kullanın. işlemi hatayı tetiklemiştir.
SERVICE_TIMEOUT (Hata Kodu -3)
Sorun
Bu hata, Google Play yanıt vermeden önce isteğin maksimum zaman aşımına ulaştığını gösterir. Bu durum, örneğin bir gecikme nedeniyle .
Olası çözüm
Bu genellikle geçici bir sorundur. Aşağıdakilerden birini kullanarak isteği yeniden deneyin: hangi işlemin sonucu döndürdüğüne bağlı olarak, basit veya eksponansiyel geri yükleme stratejisidir. hatası.
Aşağıdaki SERVICE_DISCONNECTED
durumundan farklı olarak, Google Play Faturalandırma hizmetine olan bağlantı kesilmez. Tek yapmanız gereken, denenen Play Faturalandırma Kitaplığı işlemini tekrar denemektir.
SERVICE_DISCONNECTED (Hata Kodu: -1)
Sorun
Bu önemli hata, istemci uygulamasının BillingClient
üzerinden Google Play Store hizmetine olan bağlantısının kesildiğini gösterir.
Olası çözüm
Bu hatadan mümkün olduğunca kaçınmak için her zaman Google ile bağlantınızı kontrol edin
Şu telefon numarasını arayarak Play Faturalandırma Kitaplığı ile arama yapmadan önce Play Hizmetleri:
BillingClient.isReady()
.
SERVICE_DISCONNECTED
hesabından kurtarmayı denemek için
istemci uygulamanız
BillingClient.startConnection
.
Aynı SERVICE_TIMEOUT
'de olduğu gibi
kullanıyorsanız, hangi işlemin tetiklendiğine bağlı olarak basit yeniden deneme veya üstel geri yükleme yöntemini kullanın.
gösterir.
SERVICE_UNAVAILABLE (Hata Kodu 2)
Önemli Not:
Google Play Faturalandırma Kitaplığı 6.0.0 sürümünden itibaren SERVICE_UNAVAILABLE
,
daha uzun süre döndürüldü. Faturalandırma hizmeti şu olduğunda döndürülür:
ve desteği sonlandırılan SERVICE_TIMEOUT
senaryo senaryoları.
Sorun
Bu geçici hata, Google Play Faturalandırma hizmetinin şu anda kullanıldığını gösterir kullanılamıyor. Çoğu durumda bu, istemci cihaz ile Google Play Faturalandırma Hizmetleri arasında bir ağ bağlantısı sorunu olduğu anlamına gelir.
Olası çözüm
Bu genellikle geçici bir sorundur. Aşağıdakilerden birini kullanarak isteği yeniden deneyin: hangi işlemin sonucu döndürdüğüne bağlı olarak, basit veya eksponansiyel geri yükleme stratejisidir. hatası.
SERVICE_DISCONNECTED
durumundan farklı olarak, Google Play Faturalandırma hizmetine olan bağlantı kesilmez ve denenen işlemi tekrarlamanız gerekir.
BILLING_UNAVAILABLE (Hata Kodu 3)
Sorun
Bu hata, satın alma işlemi sırasında kullanıcı faturalandırması hatası oluştuğunu gösterir. Bu durumun yaşanabileceği durumlara örnek olarak aşağıdakiler verilebilir:
- Kullanıcının cihazındaki Play Store uygulaması güncel değil.
- Kullanıcı desteklenmeyen bir ülkede.
- Kullanıcı, kurumsal bir kullanıcı ve kurumsal yöneticisi bazı kullanıcıları devre dışı bıraktı engeller.
- Google Play, kullanıcının ödeme yönteminden ödeme alamıyor. Örneğin, kullanıcının kredi kartının süresi dolmuş olabilir.
Olası çözüm
Bu durumda otomatik yeniden denemelerin işe yarama olasılığı düşüktür. Ancak kullanıcı, soruna neden olan durumu giderirse manuel olarak tekrar denemek faydalı olabilir. Örneğin, Kullanıcı Play Store sürümünü desteklenen bir sürüme günceller ve ardından manuel olarak tekrar deneyebilirsiniz.
Bu hata, kullanıcı oturumda değilken oluşursa yeniden denemek başarısız olabilir
olması gerekir.
Satın alma akışı sonucunda BILLING_UNAVAILABLE
hatası aldığınızda, kullanıcının satın alma işlemi sırasında Google Play'den geri bildirim almış olması ve hatanın neyle ilgili olduğunu bilmesi muhtemeldir. Bu durumda, kullanıcı arabirimi için bir hata mesajı
ve kullanıcıya deneme veya kontrol ekleme seçeneği sunan bir "Tekrar dene" düğmesi
manuel olarak yeniden deneyin.
ERROR (Hata Kodu 6)
Sorun
Bu, Google Play'in kendisiyle ilgili dahili bir sorunu gösteren önemli bir hatadır.
Olası çözüm
Bazen ERROR
'e neden olan dahili Google Play sorunları
geri yükleme işlemi geçicidir ve eksponansiyel geri yükleme ile yeniden deneme
olabilir. Kullanıcılar oturumdayken basit bir yeniden deneme tercih edilir.
ITEM_ALREADY_OWNED
Sorun
Bu yanıt, Google Play kullanıcısının satın almaya çalıştığı aboneliğe veya tek seferlik satın alma işlemine tabi ürüne zaten sahip olduğunu gösterir. Çoğu durumda bu geçici bir hata değildir. Google Play’in önbelleğini kullanır.
Olası çözüm
Nedeni önbellek sorunu olmadığında bu hatanın oluşmasını önlemek için, kullanıcının zaten sahip olduğu bir ürünü satın almak üzere sunmayın. Şunu kontrol ettiğinizden emin olun:
satın alınabilecek ürünleri gösterdiğinizde kullanıcının yararlanma hakları ve
uygun şekilde filtreleyerek kullanıcının satın alabileceği ürünlere göre filtre uygulayabilirsiniz.
İstemci uygulaması, önbellek sorunu nedeniyle bu hatayı aldığında hata, Google Play'in arka ucundaki en son verilerle güncellenmesi için Google Play'in önbelleğini tetikler.
Hatadan sonra yeniden deneme, bu geçici örneği şu şekilde çözecektir:
dava açın. Kullanıcının ürünü alıp almadığını kontrol etmek için ITEM_ALREADY_OWNED
aldıktan sonra BillingClient.queryPurchasesAsync()
'i arayın. Kullanıcı ürünü satın almadıysa satın alma işlemini yeniden denemek için basit bir yeniden deneme mantığı uygulayın.
ITEM_NOT_OWNED
Sorun
Bu satın alma yanıtı, Google Play kullanıcısının değiştirmeye, onaylamaya veya kullanmaya çalıştığı aboneliğin ya da tek seferlik satın alma ürününün sahibi olmadığını gösterir. Bu, Google'dan kaynaklanmadığı durumlar dışında çoğu durumda geçici bir hata değildir Play’in önbelleği eski durumuna geçiyor.
Olası çözüm
Hata, önbellek sorunu nedeniyle alındığında Google Play'in önbelleği, Play'in arka ucundaki en son verilerle güncellenir. Hata oluştuktan sonra basit bir yeniden deneme stratejisiyle yeniden denemek, bu geçici durumu çözecektir. ITEM_NOT_OWNED
aldıktan sonra BillingClient.queryPurchasesAsync()
adlı kişiyi arayarak kullanıcının şu olup olmadığını kontrol edin:
kararlaştırdık. Aksi halde, basit yeniden deneme mantığını kullanarak
değeri için teklif verirsiniz.
Yeniden Kullanılabilir Olmayan Faturalandırma Sonucu yanıtları
Yeniden deneme mantığını kullanarak bu hataları düzeltemezsiniz.
FEATURE_NOT_SUPPORTED
Sorun
Yeniden alınamayan bu hata, Google Play Faturalandırma özelliğinin kullanıcının cihazında desteklenmediğini gösterir. Bunun nedeni muhtemelen eski bir Play Store sürümü olabilir.
Örneğin bazı kullanıcılarınızın cihaz uygulama içi mesajlaşmayı desteklemiyor.
Olası çözüm
Play Faturalandırma Kitaplığı'na telefon etmeden önce özellik desteğini kontrol etmek için BillingClient.isFeatureSupported()
simgesini kullanın.
when {
billingClient.isReady -> {
if (billingClient.isFeatureSupported(BillingClient.FeatureType.IN_APP_MESSAGING)) {
// use feature
}
}
}
USER_CANCELED
Sorun
Kullanıcı, faturalandırma akışı kullanıcı arayüzünü tıkladı.
Olası çözüm
Bu yalnızca bilgilendirme amaçlıdır ve sorunsuz bir şekilde başarısız olabilir.
ITEM_UNAVAILABLE
Sorun
Google Play Faturalandırma aboneliği veya tek seferlik satın alma ürünü bu kullanıcı tarafından satın alınamaz.
Olası çözüm
Uygulamanızın, ürün ayrıntılarını önerilen şekilde queryProductDetailsAsync
üzerinden yenilediğinden emin olun. Gerekirse ek yenilemeler uygulamak için ürün kataloğunuzun Play Console yapılandırmasında ne sıklıkta değiştiğini göz önünde bulundurun.
Google Play Faturalandırma'da yalnızca queryProductDetailsAsync
üzerinden doğru bilgileri döndüren ürünleri satmaya çalışın.
Tutarsızlık olup olmadığını kontrol etmek için ürün uygunluk yapılandırmasını kontrol edin.
Örneğin, yalnızca belirli bir tarihte satılan bir ürünü sorguluyor olabilirsiniz.
satın almaya çalıştığı bölgeden farklı bir bölge olabilir.
Bir ürünün satın alınabilmesi için etkin olması, uygulamasının
yayınlanmış ve uygulamasının kullanıcının ülkesinde kullanılabilir olması gerekir.
Bazen, özellikle de test sırasında üründeki her şey doğru yapılandırmaya devam ediyor, ancak kullanıcılar bu hatayı görmeye devam ediyor. Bu durum, ürün ayrıntılarının Google sunucularına dağıtılmasındaki gecikmeyle ilgili olabilir. Tekrar dene daha sonra.
GELİŞTİRİCİ_HATASI
Sorun
Bu, bir API'yi yanlış kullandığınızı belirten önemli bir hatadır.
Örneğin, BillingClient.launchBillingFlow
öğesine yanlış parametreler sağlanması,
bu hataya neden olur.
Olası çözüm
Farklı Play Faturalandırma Kitaplığı çağrılarını doğru şekilde kullandığınızdan emin olun. Hatayla ilgili daha fazla bilgi için hata ayıklama mesajını da kontrol edin.