जब Play Billing Library का कोई कॉल किसी कार्रवाई को ट्रिगर करता है, तो लाइब्रेरी डेवलपर को नतीजे के बारे में बताने के लिए BillingResult रिस्पॉन्स देती है. उदाहरण के लिए, अगर आपको उपयोगकर्ता के लिए उपलब्ध ऑफ़र पाने के लिए queryProductDetailsAsync का इस्तेमाल करना है, तो रिस्पॉन्स कोड में या तो OK कोड शामिल होगा और सही ProductDetails ऑब्जेक्ट मिलेगा या इसमें एक अलग रिस्पॉन्स शामिल होगा. इससे यह पता चलेगा कि ProductDetails ऑब्जेक्ट क्यों नहीं दिया जा सका.
सभी रिस्पॉन्स कोड, गड़बड़ियां नहीं होते हैं. BillingResponseCode
रेफ़रंस पेज पर, इस गाइड में बताए गए हर जवाब के बारे में पूरी जानकारी दी गई है.
ऐसे रिस्पॉन्स कोड के कुछ उदाहरण यहां दिए गए हैं जिनसे गड़बड़ियों का पता नहीं चलता:
BillingClient.BillingResponseCode.OK: कॉल से ट्रिगर की गई कार्रवाई पूरी हो गई है.BillingClient.BillingResponseCode.USER_CANCELED: यह जवाब उन कार्रवाइयों के लिए होता है जो उपयोगकर्ता को Play Store के यूज़र इंटरफ़ेस (यूआई) फ़्लो दिखाती हैं. इससे पता चलता है कि उपयोगकर्ता ने प्रोसेस पूरी किए बिना ही उन यूज़र इंटरफ़ेस (यूआई) फ़्लो से बाहर निकल गया.
जब रिस्पॉन्स कोड से गड़बड़ी का पता चलता है, तो इसकी वजह कभी-कभी कुछ समय के लिए होने वाली समस्याएं होती हैं. इसलिए, इसे ठीक किया जा सकता है. जब Play Billing Library के किसी तरीके को कॉल करने पर, BillingResponseCode वैल्यू मिलती है, तो इसका मतलब है कि समस्या को ठीक किया जा सकता है. ऐसे में, आपको कॉल को फिर से आज़माना चाहिए. अन्य मामलों में, स्थितियों को अस्थायी नहीं माना जाता. इसलिए, फिर से कोशिश करने का सुझाव नहीं दिया जाता.
अस्थायी गड़बड़ियों को ठीक करने के लिए, फिर से कोशिश करने की अलग-अलग रणनीतियां अपनाई जाती हैं. ये रणनीतियां इन बातों पर निर्भर करती हैं:
क्या गड़बड़ी तब हुई, जब उपयोगकर्ता सेशन में थे. उदाहरण के लिए, जब कोई उपयोगकर्ता खरीदारी कर रहा था या क्या गड़बड़ी बैकग्राउंड में हुई. उदाहरण के लिए, जब onResume के दौरान उपयोगकर्ता की मौजूदा खरीदारी के बारे में क्वेरी की जा रही थी.
नीचे दिए गए फिर से कोशिश करने की रणनीतियों वाले सेक्शन में, इन अलग-अलग रणनीतियों के उदाहरण दिए गए हैं. साथ ही, BillingResult सेक्शन में, यह सुझाव दिया गया है कि हर रिस्पॉन्स कोड के लिए कौनसी रणनीति सबसे सही काम करती है.
जवाब के कोड के अलावा, गड़बड़ी वाले कुछ जवाबों में डीबग करने और लॉग करने के लिए मैसेज शामिल होते हैं.
फिर से कोशिश करने की रणनीतियां
फिर से कोशिश करने की सुविधा
अगर उपयोगकर्ता सेशन में है, तो फिर से कोशिश करने की रणनीति लागू करना बेहतर है. इससे, गड़बड़ी से उपयोगकर्ता अनुभव पर कम से कम असर पड़ेगा. ऐसे मामले में, हमारा सुझाव है कि फिर से कोशिश करने की रणनीति लागू करें. इसमें कोशिश करने की ज़्यादा से ज़्यादा संख्या को एग्ज़िट की शर्त के तौर पर इस्तेमाल करें.
यहां दिए गए उदाहरण में, BillingClient कनेक्शन बनाते समय होने वाली गड़बड़ी को ठीक करने के लिए, फिर से कोशिश करने की एक सामान्य रणनीति दिखाई गई है:
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) }
} finally {
tries++
}
} while (tries <= maxTries && !isConnectionEstablished)
}
...
}
एक्स्पोनेंशियल बैकऑफ़ के साथ फिर से कोशिश करना
हमारा सुझाव है कि Play Billing Library के उन ऑपरेशनों के लिए, एक्सपोनेंशियल बैकऑफ़ का इस्तेमाल करें जो बैकग्राउंड में होते हैं. साथ ही, जब उपयोगकर्ता सेशन में हो, तब उसके अनुभव पर असर नहीं डालते.
उदाहरण के लिए, नई खरीदारी की पुष्टि करते समय इस सुविधा को लागू करना सही होगा. ऐसा इसलिए, क्योंकि यह कार्रवाई बैकग्राउंड में हो सकती है. साथ ही, अगर कोई गड़बड़ी होती है, तो पुष्टि रीयल टाइम में नहीं की जानी चाहिए.
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 responses
NETWORK_ERROR (गड़बड़ी कोड 12)
समस्या
इस गड़बड़ी का मतलब है कि डिवाइस और Play सिस्टम के बीच नेटवर्क कनेक्शन में कोई समस्या हुई.
समस्या हल होने की संभावना
इस गड़बड़ी को ठीक करने के लिए, सामान्य तौर पर फिर से कोशिश करें या एक्स्पोनेंशियल बैकऑफ़ का इस्तेमाल करें. यह इस बात पर निर्भर करता है कि किस कार्रवाई की वजह से गड़बड़ी हुई है.
SERVICE_TIMEOUT (गड़बड़ी कोड -3)
समस्या
इस गड़बड़ी का मतलब है कि Google Play की ओर से जवाब देने से पहले, अनुरोध का टाइम आउट हो गया है. उदाहरण के लिए, ऐसा Play Billing Library कॉल के ज़रिए किए गए अनुरोध को पूरा करने में देरी की वजह से हो सकता है.
समस्या हल होने की संभावना
आम तौर पर, यह समस्या कुछ समय के लिए होती है. अनुरोध को फिर से भेजें. इसके लिए, सामान्य या एक्स्पोनेंशियल बैकऑफ़ रणनीति का इस्तेमाल करें. यह इस बात पर निर्भर करता है कि किस कार्रवाई से गड़बड़ी हुई है.
नीचे दिए गए SERVICE_DISCONNECTED से अलग, Google Play Billing सेवा से कनेक्शन नहीं टूटता है. साथ ही, आपको सिर्फ़ Play Billing Library के उस ऑपरेशन को फिर से आज़माना होगा जिसे पूरा करने की कोशिश की गई थी.
SERVICE_DISCONNECTED (गड़बड़ी का कोड -1)
समस्या
इस गंभीर गड़बड़ी से पता चलता है कि क्लाइंट ऐप्लिकेशन का Google Play Store सेवा से कनेक्शन, BillingClient के ज़रिए बंद कर दिया गया है.
समस्या हल होने की संभावना
हमारा सुझाव है: अपने-आप सेवा से फिर से कनेक्ट होने की सुविधा चालू करें
Play Billing Library के 8.0.0 वर्शन में, enableAutoServiceReconnection() सुविधा जोड़ी गई है.
हमारा सुझाव है कि BillingClient बनाते समय, इस सुविधा को चालू करें. इससे लाइब्रेरी को यह अनुमति मिलती है कि सेवा के डिसकनेक्ट होने के दौरान बिलिंग एपीआई कॉल किए जाने पर, वह कनेक्शन को अपने-आप फिर से जोड़ने की कोशिश करे. इससे इस गड़बड़ी के होने की संभावना काफ़ी कम हो जाती है.
Kotlin
val billingClient = BillingClient.newBuilder(context)
.setListener(listener)
.enablePendingPurchases()
.enableAutoServiceReconnection() // Enable automatic service reconnection
.build()
Java
BillingClient billingClient = BillingClient.newBuilder(context)
.setListener(listener)
.enablePendingPurchases()
.enableAutoServiceReconnection() // Enable automatic service reconnection
.build();
अगर आपने सेवा से अपने-आप फिर से कनेक्ट होने की सुविधा चालू की है
Play Billing Library अपने-आप फिर से कनेक्ट होने की कोशिश करेगी. अगर एपीआई कॉल करने पर आपको अब भी SERVICE_DISCONNECTED रिस्पॉन्स कोड मिलता है, तो इसका मतलब है कि लाइब्रेरी, अपने-आप फिर से कनेक्ट नहीं हो पाई.
इस स्थिति में, आपको अपने ऐप्लिकेशन में फिर से कोशिश करने का लॉजिक लागू करना चाहिए:
- उपयोगकर्ता की ओर से शुरू की गई कार्रवाइयों (सेशन के दौरान) के लिए: एपीआई कॉल को फिर से आज़माएं. यह समस्या कुछ समय के लिए हो सकती है.
- बैकग्राउंड अनुरोधों के लिए: एक्स्पोनेंशियल बैकऑफ़ के साथ फिर से कोशिश करने की सुविधा लागू करें. इससे, कनेक्शन लंबे समय तक न होने पर सिस्टम पर ज़्यादा असर नहीं पड़ेगा.
अगर आपने सेवा के अपने-आप फिर से कनेक्ट होने की सुविधा चालू नहीं की है
इस गड़बड़ी से बचने के लिए, Play Billing Library का इस्तेमाल करके कॉल करने से पहले, हमेशा Google Play सेवाओं से कनेक्शन की जांच करें. इसके लिए, BillingClient.isReady() को कॉल करें.
SERVICE_DISCONNECTED से रिकवर करने के लिए
, आपके क्लाइंट ऐप्लिकेशन को BillingClient.startConnection का इस्तेमाल करके, कनेक्शन को फिर से स्थापित करने की कोशिश करनी चाहिए.
SERVICE_TIMEOUT की तरह ही, गड़बड़ी को ट्रिगर करने वाली कार्रवाई के आधार पर, फिर से कोशिश करने की सामान्य सुविधा या एक्स्पोनेंशियल बैकऑफ़ का इस्तेमाल करें.
SERVICE_UNAVAILABLE (गड़बड़ी कोड 2)
अहम जानकारी:
Google Play Billing Library 6.0.0 से, नेटवर्क की समस्याओं के लिए SERVICE_UNAVAILABLE अब नहीं दिखाया जाता. यह तब दिखता है, जब बिलिंग सेवा उपलब्ध नहीं होती और SERVICE_TIMEOUT के इस्तेमाल के उदाहरणों को बंद कर दिया जाता है.
समस्या
यह कुछ समय के लिए होने वाली गड़बड़ी है. इससे पता चलता है कि फ़िलहाल, Google Play Billing सेवा उपलब्ध नहीं है. ज़्यादातर मामलों में, इसका मतलब है कि क्लाइंट डिवाइस और Google Play Billing सेवाओं के बीच नेटवर्क कनेक्शन में कोई समस्या है.
समस्या हल होने की संभावना
आम तौर पर, यह समस्या कुछ समय के लिए होती है. अनुरोध को फिर से भेजें. इसके लिए, सामान्य या एक्स्पोनेंशियल बैकऑफ़ रणनीति का इस्तेमाल करें. यह इस बात पर निर्भर करता है कि किस कार्रवाई से गड़बड़ी हुई है.
SERVICE_DISCONNECTED के उलट, Google Play Billing सेवा से कनेक्शन नहीं टूटता है. इसलिए, आपको उस कार्रवाई को फिर से आज़माना होगा जिसे पूरा करने की कोशिश की जा रही है.
BILLING_UNAVAILABLE (गड़बड़ी का कोड 3)
समस्या
इस गड़बड़ी का मतलब है कि खरीदारी की प्रोसेस के दौरान, उपयोगकर्ता के बिलिंग खाते में कोई गड़बड़ी हुई है. ऐसा इन स्थितियों में हो सकता है:
- उपयोगकर्ता के डिवाइस पर Play Store ऐप्लिकेशन का पुराना वर्शन है.
- उपयोगकर्ता किसी ऐसे देश में है जहां यह सुविधा काम नहीं करती.
- उपयोगकर्ता एंटरप्राइज़ उपयोगकर्ता है और उसके एंटरप्राइज़ एडमिन ने उपयोगकर्ताओं के लिए खरीदारी करने की सुविधा बंद कर दी है.
- Google Play, उपयोगकर्ता के पेमेंट के तरीके से शुल्क नहीं ले पा रहा है. उदाहरण के लिए, ऐसा हो सकता है कि उपयोगकर्ता के क्रेडिट कार्ड की समयसीमा खत्म हो गई हो.
समस्या हल होने की संभावना
इस मामले में, अपने-आप फिर से कोशिश करने की सुविधा से मदद नहीं मिलेगी. हालांकि, अगर उपयोगकर्ता उस शर्त को पूरा करता है जिसकी वजह से समस्या हुई थी, तो मैन्युअल तरीके से फिर से कोशिश करने से मदद मिल सकती है. उदाहरण के लिए, अगर उपयोगकर्ता Play Store के वर्शन को ऐसे वर्शन पर अपडेट करता है जिस पर यह सुविधा काम करती है, तो शुरुआती कार्रवाई को मैन्युअल तरीके से फिर से आज़माने पर काम हो सकता है.
अगर यह गड़बड़ी तब होती है, जब उपयोगकर्ता सेशन में नहीं है, तो फिर से कोशिश करने से कोई फ़ायदा नहीं होगा.
अगर खरीदारी के फ़्लो के दौरान आपको BILLING_UNAVAILABLE गड़बड़ी मिलती है, तो ऐसा हो सकता है कि उपयोगकर्ता को खरीदारी के दौरान Google Play से सुझाव मिला हो. साथ ही, उसे यह भी पता हो कि क्या गड़बड़ी हुई है. ऐसे में, गड़बड़ी का मैसेज दिखाया जा सकता है. इसमें बताया जा सकता है कि कुछ गड़बड़ी हुई है. साथ ही, “फिर से कोशिश करें” बटन दिया जा सकता है, ताकि उपयोगकर्ता समस्या हल करने के बाद, मैन्युअल तरीके से फिर से कोशिश कर सके.
गड़बड़ी (गड़बड़ी कोड 6)
समस्या
यह एक गंभीर गड़बड़ी है. इससे पता चलता है कि Google Play में कोई अंदरूनी समस्या है.
समस्या हल होने की संभावना
कभी-कभी Google Play में ऐसी समस्याएं आ जाती हैं जिनकी वजह से ERROR दिखता है. ये समस्याएं कुछ समय के लिए होती हैं. इसलिए, इन्हें ठीक करने के लिए, एक्सपोनेंशियल बैकऑफ़ के साथ फिर से कोशिश की जा सकती है. जब उपयोगकर्ता सेशन में हों, तब फिर से कोशिश करना बेहतर होता है.
ITEM_ALREADY_OWNED
समस्या
इस जवाब से पता चलता है कि Google Play का उपयोगकर्ता, उस सदस्यता या वन-टाइम खरीदारी वाले प्रॉडक्ट का पहले से मालिक है जिसे वह खरीदने की कोशिश कर रहा है. ज़्यादातर मामलों में, यह कुछ समय के लिए होने वाली गड़बड़ी नहीं होती. हालांकि, ऐसा तब हो सकता है, जब Google Play की पुरानी कैश मेमोरी की वजह से यह गड़बड़ी हुई हो.
समस्या हल होने की संभावना
अगर कैश मेमोरी की वजह से यह गड़बड़ी नहीं हो रही है, तो खरीदारी के लिए ऐसा प्रॉडक्ट ऑफ़र न करें जो उपयोगकर्ता के पास पहले से मौजूद है. पक्का करें कि खरीदारी के लिए उपलब्ध प्रॉडक्ट दिखाते समय, आपने उपयोगकर्ता के एनटाइटलमेंट की जांच की हो. साथ ही, उपयोगकर्ता के एनटाइटलमेंट के हिसाब से, यह फ़िल्टर किया हो कि वह कौनसे प्रॉडक्ट खरीद सकता है.
जब क्लाइंट ऐप्लिकेशन को कैश मेमोरी की समस्या की वजह से यह गड़बड़ी मिलती है, तो गड़बड़ी की वजह से Google Play की कैश मेमोरी अपडेट हो जाती है. इसमें Play के बैकएंड से मिला नया डेटा शामिल होता है.
गड़बड़ी के बाद फिर से कोशिश करने पर, इस मामले में कुछ समय के लिए होने वाली यह गड़बड़ी ठीक हो जानी चाहिए. ITEM_ALREADY_OWNED मिलने के बाद, BillingClient.queryPurchasesAsync() को कॉल करें. इससे यह पता चलेगा कि उपयोगकर्ता ने प्रॉडक्ट खरीदा है या नहीं. अगर ऐसा नहीं है, तो खरीदारी को फिर से करने के लिए, फिर से कोशिश करने की सुविधा लागू करें.
ITEM_NOT_OWNED
समस्या
खरीदारी के इस जवाब से पता चलता है कि Google Play के उपयोगकर्ता के पास, उस सदस्यता या वन-टाइम खरीदारी वाले प्रॉडक्ट का मालिकाना हक नहीं है जिसे उपयोगकर्ता बदलने, स्वीकार करने या इस्तेमाल करने की कोशिश कर रहा है. ज़्यादातर मामलों में, यह गड़बड़ी कुछ समय के लिए नहीं होती. हालांकि, ऐसा तब हो सकता है, जब Google Play की कैश मेमोरी पुरानी हो गई हो.
समस्या हल होने की संभावना
कैश मेमोरी की वजह से गड़बड़ी होने पर, Google Play की कैश मेमोरी अपडेट हो जाती है. इसमें Play के बैकएंड से मिला नया डेटा शामिल होता है. गड़बड़ी होने के बाद, फिर से कोशिश करने की सामान्य रणनीति का इस्तेमाल करने से, इस खास अस्थायी इंस्टेंस की समस्या हल हो जानी चाहिए. ITEM_NOT_OWNED मिलने के बाद, BillingClient.queryPurchasesAsync() को कॉल करें. इससे यह पता चलेगा कि उपयोगकर्ता ने प्रॉडक्ट खरीदा है या नहीं. अगर ऐसा नहीं होता है, तो खरीदारी को फिर से करने के लिए, फिर से कोशिश करने के सामान्य लॉजिक का इस्तेमाल करें.
Non-Retriable BillingResult responses
फिर से कोशिश करने के लॉजिक का इस्तेमाल करके, इन गड़बड़ियों को ठीक नहीं किया जा सकता.
FEATURE_NOT_SUPPORTED
समस्या
इस गड़बड़ी को ठीक नहीं किया जा सकता. इससे पता चलता है कि उपयोगकर्ता के डिवाइस पर Google Play Billing की सुविधा काम नहीं करती. ऐसा शायद Play Store के पुराने वर्शन की वजह से होता है.
उदाहरण के लिए, ऐसा हो सकता है कि आपके कुछ उपयोगकर्ताओं के डिवाइसों पर, ऐप्लिकेशन में मैसेज भेजने की सुविधा काम न करे.
समस्या को ठीक करने का तरीका
Play Billing Library को कॉल करने से पहले, BillingClient.isFeatureSupported() का इस्तेमाल करके यह देखें कि सुविधा काम करती है या नहीं.
when {
billingClient.isReady -> {
if (billingClient.isFeatureSupported(BillingClient.FeatureType.IN_APP_MESSAGING)) {
// use feature
}
}
}
USER_CANCELED
समस्या
उपयोगकर्ता ने बिलिंग फ़्लो के यूज़र इंटरफ़ेस (यूआई) से बाहर क्लिक किया हो.
समस्या हल होने की संभावना
यह सिर्फ़ जानकारी देने के लिए है और इसमें गड़बड़ी हो सकती है.
ITEM_UNAVAILABLE
समस्या
Google Play Billing की सदस्यता या वन-टाइम खरीदारी वाला प्रॉडक्ट, इस उपयोगकर्ता के लिए उपलब्ध नहीं है.
समस्या को ठीक करने का तरीका
पक्का करें कि आपका ऐप्लिकेशन, प्रॉडक्ट की जानकारी को queryProductDetailsAsync के ज़रिए रीफ़्रेश करता हो. ध्यान रखें कि Play Console कॉन्फ़िगरेशन में आपके प्रॉडक्ट कैटलॉग में कितनी बार बदलाव होता है. इससे आपको यह तय करने में मदद मिलेगी कि ज़रूरत पड़ने पर, आपको कितनी बार रीफ़्रेश करना है.
Google Play Billing पर सिर्फ़ ऐसे प्रॉडक्ट बेचें जिनकी सही जानकारी queryProductDetailsAsync के ज़रिए मिलती हो.
यह देखने के लिए कि प्रॉडक्ट की ज़रूरी शर्तों के कॉन्फ़िगरेशन में कोई गड़बड़ी तो नहीं है.
उदाहरण के लिए, ऐसा हो सकता है कि आपने किसी ऐसे प्रॉडक्ट के लिए क्वेरी की हो जो सिर्फ़ किसी ऐसे देश/इलाके में उपलब्ध हो जहां से उपयोगकर्ता खरीदारी करने की कोशिश कर रहा है.
कोई भी प्रॉडक्ट इस्तेमाल के लिए उपलब्ध होने पर ही खरीदा जा सकेगा. साथ ही, यह भी ज़रूरी है कि जिस ऐप्लिकेशन पर वह उपलब्ध है उसे पब्लिश कर दिया गया हो. इसके अलावा, यह ऐप्लिकेशन उपयोगकर्ता के देश में भी उपलब्ध होना चाहिए.
कभी-कभी, खास तौर पर टेस्टिंग के दौरान, प्रॉडक्ट कॉन्फ़िगरेशन में सब कुछ सही होता है. हालांकि, उपयोगकर्ताओं को अब भी यह गड़बड़ी दिखती है. ऐसा Google के सर्वर पर, प्रॉडक्ट की जानकारी अपडेट होने में लगने वाले समय की वजह से हो सकता है. कुछ देर बाद फिर से कोशिश करें.
DEVELOPER_ERROR
समस्या
यह एक गंभीर गड़बड़ी है. इससे पता चलता है कि एपीआई का गलत तरीके से इस्तेमाल किया जा रहा है.
उदाहरण के लिए, BillingClient.launchBillingFlow को गलत पैरामीटर देने से यह गड़बड़ी हो सकती है.
समस्या हल होने की संभावना
पक्का करें कि Play Billing Library के अलग-अलग कॉल का सही तरीके से इस्तेमाल किया जा रहा हो. गड़बड़ी के बारे में ज़्यादा जानकारी के लिए, डीबग मैसेज भी देखें.