बिलिंग नतीजे के रिस्पॉन्स कोड मैनेज करना

जब 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 कनेक्शन बनाते समय होने वाली गड़बड़ी को ठीक करने के लिए, फिर से कोशिश करने की एक सामान्य रणनीति दिखाई गई है:

// Initialize the BillingClient.
private val billingClient = BillingClient.newBuilder(context)
    .setListener(this)
    .enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build())
    .build()

private val coroutineScope = kotlinx.coroutines.CoroutineScope(
    kotlinx.coroutines.SupervisorJob() + kotlinx.coroutines.Dispatchers.Main.immediate
)

private var connectionJob: kotlinx.coroutines.Job? = null

// Establish a connection to Google Play.
fun startBillingConnection() {
    connectionJob?.cancel()
    connectionJob = coroutineScope.launch {
        connectWithRetry()
    }
}

// Suspended helper to perform a single connection attempt
private suspend fun connectBilling(): BillingResult =
    kotlinx.coroutines.suspendCancellableCoroutine { continuation ->
        billingClient.startConnection(object : BillingClientStateListener {
            override fun onBillingSetupFinished(billingResult: BillingResult) {
                if (continuation.isActive) {
                    continuation.resume(billingResult)
                }
            }

            override fun onBillingServiceDisconnected() {
                Log.e(TAG, "Google Play Billing Service disconnected")
                if (continuation.isActive) {
                    continuation.resume(
                        BillingResult.newBuilder()
                            .setResponseCode(BillingClient.BillingResponseCode.SERVICE_DISCONNECTED)
                            .setDebugMessage("Service disconnected during connection setup")
                            .build()
                    )
                } else {
                    startBillingConnection()
                }
            }
        })
    }

// Billing connection retry logic. This is a simple max retry pattern
private suspend fun connectWithRetry() {
    val maxTries = 3
    var tries = 1
    var isConnectionEstablished = false
    while (tries <= maxTries && !isConnectionEstablished) {
        val billingResult = connectBilling()
        if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
            isConnectionEstablished = true
            Log.d(TAG, "Billing response OK")
        } else {
            Log.e(TAG, "Billing connection retry failed: ${billingResult.debugMessage}")
            tries++
            if (tries <= maxTries) {
                delay(2000L) // Wait 2 seconds before retrying
            }
        }
    }
}

fun cleanUp() {
    coroutineScope.cancel()
}
// ...

एक्स्पोनेंशियल बैकऑफ़ के साथ फिर से कोशिश करना

हमारा सुझाव है कि Play Billing Library के उन ऑपरेशनों के लिए, एक्सपोनेंशियल बैकऑफ़ का इस्तेमाल करें जो बैकग्राउंड में होते हैं. साथ ही, जब उपयोगकर्ता सेशन में हो, तब उसके अनुभव पर असर नहीं डालते.

उदाहरण के लिए, नई खरीदारी की पुष्टि करते समय इस सुविधा को लागू करना सही होगा. ऐसा इसलिए, क्योंकि यह कार्रवाई बैकग्राउंड में हो सकती है. साथ ही, अगर कोई गड़बड़ी होती है, तो पुष्टि रीयल टाइम में नहीं की जानी चाहिए.

private suspend fun acknowledge(purchaseToken: String): BillingResult =
    kotlinx.coroutines.suspendCancellableCoroutine { continuation ->
        val params = AcknowledgePurchaseParams.newBuilder()
            .setPurchaseToken(purchaseToken)
            .build()
        billingClient.acknowledgePurchase(params) { billingResult ->
            continuation.resumeWith(Result.success(billingResult))
        }
    }

private suspend fun queryPurchases(productType: String): Pair<BillingResult, List<Purchase>> =
    kotlinx.coroutines.suspendCancellableCoroutine { continuation ->
        val params = QueryPurchasesParams.newBuilder()
            .setProductType(productType)
            .build()
        billingClient.queryPurchasesAsync(params) { billingResult, purchaseList ->
            continuation.resumeWith(Result.success(Pair(billingResult, purchaseList)))
        }
    }

suspend fun acknowledgePurchase(purchaseToken: String) {
    val retryDelayMs = 2000L
    val retryFactor = 2
    val maxTries = 3

    var tries = 1
    var currentDelay = retryDelayMs
    var acknowledgePurchaseResult: BillingResult

    do {
        acknowledgePurchaseResult = acknowledge(purchaseToken)
        val playBillingResponseCode = acknowledgePurchaseResult.responseCode

        when (playBillingResponseCode) {
            BillingClient.BillingResponseCode.OK -> {
                Log.i(TAG, "Acknowledgement was successful")
                return
            }

            BillingClient.BillingResponseCode.ITEM_NOT_OWNED -> {
                Log.d(TAG, "Acknowledgement failed with ITEM_NOT_OWNED")
                val (billingResult, purchaseList) = queryPurchases(BillingClient.ProductType.SUBS)
                if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
                    purchaseList.forEach { purchase ->
                        acknowledge(purchase.purchaseToken)
                    }
                }
                return
            }

            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}"
                )
                if (tries < maxTries) {
                    delay(currentDelay)
                    currentDelay *= retryFactor
                    tries++
                } else {
                    break
                }
            }

            else -> {
                Log.e(
                    TAG,
                    "Acknowledgement failed and cannot be retried -- " +
                        "Response Code: ${acknowledgePurchaseResult.responseCode} -- " +
                        "Debug Message: ${acknowledgePurchaseResult.debugMessage}"
                )
                throw Exception("Failed to acknowledge the purchase!")
            }
        }
    } while (tries <= maxTries)

    throw Exception("Failed to acknowledge the purchase after $maxTries attempts!")
}

BillingResult के ऐसे जवाब जिन्हें फिर से आज़माया जा सकता है

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(
        PendingPurchasesParams.newBuilder().enableOneTimeProducts().build()
    )
    .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 ऐप्लिकेशन को सिस्टम ने ब्लॉक किया हो. उदाहरण के लिए, ओईएम के हिसाब से बनाए गए बच्चों के मोड में ऐसा हो सकता है. इस मामले में, BillingResult में Play Store ऐक्सेस नहीं किया जा सकता डीबग मैसेज शामिल है.

समस्या हल होने की संभावना

  • इस मामले में, अपने-आप फिर से कोशिश करने की सुविधा से मदद नहीं मिलेगी. हालांकि, अगर उपयोगकर्ता उस शर्त को पूरा करता है जिसकी वजह से समस्या हुई थी, तो मैन्युअल तरीके से फिर से कोशिश करने से मदद मिल सकती है. उदाहरण के लिए, अगर उपयोगकर्ता Play Store के वर्शन को ऐसे वर्शन पर अपडेट करता है जिस पर यह सुविधा काम करती है, तो शुरुआती कार्रवाई को मैन्युअल तरीके से फिर से आज़माने पर काम हो सकता है.

  • अगर यह गड़बड़ी तब होती है, जब उपयोगकर्ता सेशन में नहीं है, तो फिर से कोशिश करने से कोई फ़ायदा नहीं होगा. अगर आपको खरीदारी के फ़्लो के दौरान BILLING_UNAVAILABLE गड़बड़ी का मैसेज मिलता है, तो ऐसा हो सकता है कि उपयोगकर्ता को खरीदारी के दौरान Google Play से कोई सूचना मिली हो. साथ ही, उसे यह भी पता हो कि क्या गड़बड़ी हुई है. ऐसे में, गड़बड़ी का मैसेज दिखाया जा सकता है. इसमें बताया जा सकता है कि कोई गड़बड़ी हुई है. साथ ही, फिर से कोशिश करें बटन दिया जा सकता है, ताकि उपयोगकर्ता समस्या हल करने के बाद मैन्युअल तरीके से फिर से कोशिश कर सके.

गड़बड़ी (गड़बड़ी कोड 6)

समस्या

यह एक गंभीर गड़बड़ी है. इससे पता चलता है कि Google Play में कोई अंदरूनी समस्या है.

समस्या हल होने की संभावना

कभी-कभी Google Play में ऐसी समस्याएं आ जाती हैं जिनकी वजह से ERROR दिखता है. ये समस्याएं कुछ समय के लिए होती हैं. इन्हें ठीक करने के लिए, एक्सपोनेंशियल बैकऑफ़ के साथ फिर से कोशिश की जा सकती है. जब उपयोगकर्ता सेशन में हों, तब फिर से कोशिश करना बेहतर होता है.

ITEM_ALREADY_OWNED

समस्या

इस जवाब से पता चलता है कि Google Play का उपयोगकर्ता, उस सदस्यता या एक बार खरीदने वाले प्रॉडक्ट का पहले से मालिक है जिसे वह खरीदने की कोशिश कर रहा है. ज़्यादातर मामलों में, यह कुछ समय के लिए होने वाली गड़बड़ी नहीं होती. हालांकि, ऐसा तब हो सकता है, जब Google Play की पुरानी कैश मेमोरी की वजह से यह गड़बड़ी हुई हो.

समस्या हल होने की संभावना

अगर कैश मेमोरी की वजह से यह गड़बड़ी नहीं हो रही है, तो खरीदारी के लिए ऐसा प्रॉडक्ट ऑफ़र न करें जिसे उपयोगकर्ता पहले ही खरीद चुका है. पक्का करें कि खरीदारी के लिए उपलब्ध प्रॉडक्ट दिखाते समय, आपने उपयोगकर्ता के एनटाइटलमेंट की जांच की हो. साथ ही, उपयोगकर्ता के एनटाइटलमेंट के हिसाब से, यह फ़िल्टर किया हो कि वह कौनसे प्रॉडक्ट खरीद सकता है. जब क्लाइंट ऐप्लिकेशन को कैश मेमोरी की समस्या की वजह से यह गड़बड़ी मिलती है, तो गड़बड़ी की वजह से Google Play की कैश मेमोरी अपडेट हो जाती है. इसमें Play के बैकएंड से मिला नया डेटा होता है. गड़बड़ी के बाद फिर से कोशिश करने पर, इस मामले में कुछ समय के लिए होने वाली यह समस्या ठीक हो जानी चाहिए. उपयोगकर्ता ने प्रॉडक्ट खरीदा है या नहीं, यह देखने के लिए BillingClient.queryPurchasesAsync() को कॉल करें. इसके लिए, ITEM_ALREADY_OWNED पाएं. अगर ऐसा नहीं है, तो खरीदारी को फिर से करने के लिए, फिर से कोशिश करने की सामान्य प्रक्रिया लागू करें.

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 -> {
        val billingResult =
            billingClient.isFeatureSupported(BillingClient.FeatureType.IN_APP_MESSAGING)
        if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
            // use Feature
        }
    }
}

USER_CANCELED

समस्या

उपयोगकर्ता ने बिलिंग फ़्लो के यूज़र इंटरफ़ेस (यूआई) से बाहर क्लिक किया है.

समस्या हल होने की संभावना

यह सिर्फ़ जानकारी देने के लिए है और इसमें गड़बड़ी हो सकती है.

ITEM_UNAVAILABLE

समस्या

Google Play Billing की सदस्यता या एक बार खरीदा जाने वाला प्रॉडक्ट, इस उपयोगकर्ता के लिए उपलब्ध नहीं है.

जोखिम कम करने की प्रोसेस

पक्का करें कि आपका ऐप्लिकेशन, सुझाए गए तरीके से queryProductDetailsAsync के ज़रिए प्रॉडक्ट की जानकारी को रीफ़्रेश करता हो. ध्यान रखें कि Play Console कॉन्फ़िगरेशन में आपके प्रॉडक्ट कैटलॉग में कितनी बार बदलाव होता है. इससे आपको यह तय करने में मदद मिलेगी कि ज़रूरत पड़ने पर, आपको कितनी बार रीफ़्रेश करना है. Google Play Billing पर सिर्फ़ ऐसे प्रॉडक्ट बेचें जो queryProductDetailsAsync के ज़रिए सही जानकारी देते हों. देखें कि प्रॉडक्ट की ज़रूरी शर्तों के कॉन्फ़िगरेशन में कोई गड़बड़ी तो नहीं है. उदाहरण के लिए, ऐसा हो सकता है कि आपने किसी ऐसे प्रॉडक्ट के लिए क्वेरी की हो जो सिर्फ़ किसी ऐसे देश/इलाके में उपलब्ध हो जहां से उपयोगकर्ता खरीदारी करने की कोशिश कर रहा है. कोई भी प्रॉडक्ट इस्तेमाल के लिए उपलब्ध होने पर ही खरीदा जा सकेगा. साथ ही, यह भी ज़रूरी है कि जिस ऐप्लिकेशन पर वह उपलब्ध है उसे पब्लिश कर दिया गया हो. इसके अलावा, यह ऐप्लिकेशन उपयोगकर्ता के देश में भी उपलब्ध होना चाहिए.

कभी-कभी, खास तौर पर टेस्टिंग के दौरान, प्रॉडक्ट कॉन्फ़िगरेशन में सब कुछ सही होता है. हालांकि, उपयोगकर्ताओं को अब भी यह गड़बड़ी दिखती है. ऐसा Google के सर्वर पर प्रॉडक्ट की जानकारी अपडेट होने में लगने वाले समय की वजह से हो सकता है. कुछ देर बाद फिर से कोशिश करें.

DEVELOPER_ERROR

समस्या

यह एक गंभीर गड़बड़ी है. इससे पता चलता है कि एपीआई का इस्तेमाल सही तरीके से नहीं किया जा रहा है. उदाहरण के लिए, BillingClient.launchBillingFlow को गलत पैरामीटर देने से यह गड़बड़ी हो सकती है.

समस्या हल होने की संभावना

पक्का करें कि Play Billing Library के अलग-अलग कॉल का सही तरीके से इस्तेमाल किया जा रहा हो. गड़बड़ी के बारे में ज़्यादा जानकारी के लिए, डीबग मैसेज भी देखें.