จัดการโค้ดตอบกลับ Billingผลลัพธ์

เมื่อการเรียก Play Billing Library ทำให้เกิดการดำเนินการ ไลบรารีจะแสดงผล BillingResult ตอบกลับเพื่อแจ้งให้นักพัฒนาซอฟต์แวร์ทราบผลลัพธ์ ตัวอย่างเช่น หากคุณใช้ queryProductDetailsAsync เพื่อรับข้อเสนอที่มีอยู่สำหรับผู้ใช้ โค้ดตอบกลับจะมี โค้ดเหมาะสมและระบุ ProductDetails ที่ถูกต้อง หรือมีคำตอบที่แตกต่างออกไป ซึ่งแสดงเหตุผลว่าทำไม ProductDetails ไม่สามารถระบุออบเจ็กต์

โค้ดตอบกลับบางรายการอาจไม่มีข้อผิดพลาด BillingResponseCode หน้าอ้างอิงจะให้คำอธิบายโดยละเอียดสำหรับคำตอบแต่ละข้อ ที่กล่าวถึงในคู่มือนี้ ตัวอย่างบางส่วนของโค้ดตอบกลับที่ไม่ระบุข้อผิดพลาดมีดังนี้

  • BillingClient.BillingResponseCode.OK : การดำเนินการที่เกิดจากการโทรเสร็จสมบูรณ์
  • BillingClient.BillingResponseCode.USER_CANCELED : สำหรับการดำเนินการที่แสดง UI ของ Play Store ให้แก่ผู้ใช้ คำตอบนี้ ระบุว่าผู้ใช้ออกจากขั้นตอน UI เหล่านั้นโดยไม่ได้ดำเนินการ ขั้นตอนได้

เมื่อโค้ดตอบกลับระบุว่าเกิดข้อผิดพลาด บางครั้งสาเหตุอาจเกิดจาก ภาวะชั่วคราว และด้วยเหตุนี้จึงมีโอกาสที่จะฟื้นตัวได้ เมื่อมีการโทรหา 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) }
        tries++
      }
    } while (tries <= maxTries && !isConnectionEstablished)
  }
  ...
}

ลองใหม่แบบ Exponential Backoff

เราขอแนะนำให้ใช้ Exponential Backoff สำหรับการดำเนินการของ 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
}

การตอบกลับ Billingผลลัพธ์ ที่กู้คืนได้

NETWORK_ERROR (รหัสข้อผิดพลาด 12)

ปัญหา

ข้อผิดพลาดนี้บ่งบอกว่าเกิดปัญหากับการเชื่อมต่อเครือข่าย ระหว่างอุปกรณ์กับระบบ Play

วิธีแก้ปัญหาที่เป็นไปได้

หากต้องการกู้คืน ให้ใช้การลองใหม่อย่างง่ายหรือ Exponential Backoff ทั้งนี้ขึ้นอยู่กับ การดำเนินการที่ทำให้เกิดข้อผิดพลาด

SERVICE_TIMEOUT (รหัสข้อผิดพลาด -3)

ปัญหา

ข้อผิดพลาดนี้แสดงว่าคำขอถึงระยะหมดเวลาสูงสุดก่อน Google Play ตอบกลับได้ ซึ่งอาจเกิดจากความล่าช้า ในการดำเนินการตามคําขอในการเรียก Play Billing Library

วิธีแก้ปัญหาที่เป็นไปได้

ปัญหานี้มักเป็นปัญหาชั่วคราว ลองส่งคำขออีกครั้งโดยใช้ กลยุทธ์ Backoff อย่างง่ายหรือแบบเอ็กซ์โปเนนเชียล ขึ้นอยู่กับว่าการดำเนินการใดแสดงผล

เลิกชอบ SERVICE_DISCONNECTED ด้านล่าง การเชื่อมต่อกับบริการ Google Play Billing จะไม่ถูกตัดขาด และคุณ เพียงแต่ต้องลองดำเนินการใดก็ตามของ Play Billing Library ที่เคยทำไปแล้ว

SERVICE_DISCONNECTED (รหัสข้อผิดพลาด -1)

ปัญหา

ข้อผิดพลาดร้ายแรงนี้บ่งบอกว่าการเชื่อมต่อแอปไคลเอ็นต์กับ Google Play บริการร้านค้าผ่าน BillingClient ถูกตัดขาด

วิธีแก้ปัญหาที่เป็นไปได้

โปรดตรวจสอบการเชื่อมต่อกับ Google ทุกครั้งเพื่อหลีกเลี่ยงข้อผิดพลาดนี้ เล่นบริการก่อนโทรออกด้วย Play Billing Library โดยการโทร BillingClient.isReady()

วิธีพยายามกู้คืนจาก SERVICE_DISCONNECTED แอปไคลเอ็นต์ของคุณควรพยายามทำการเชื่อมต่ออีกครั้งโดยใช้ BillingClient.startConnection

เช่นเดียวกับ SERVICE_TIMEOUT ใช้การลองใหม่อย่างง่ายๆ หรือ Exponential Backoff ขึ้นอยู่กับว่ามีการทำงานใดเกิดขึ้น ข้อผิดพลาด

SERVICE_UNAVAILABLE (รหัสข้อผิดพลาด 2)

หมายเหตุสำคัญ:

ตั้งแต่ Google Play Billing Library 6.0.0 เป็นต้นไป SERVICE_UNAVAILABLE จะไม่มี นานขึ้นเนื่องจากปัญหาเครือข่าย ระบบจะส่งคืนเมื่อบริการการเรียกเก็บเงิน ไม่พร้อมใช้งานและสถานการณ์จำลอง SERVICE_TIMEOUT กรณีที่เลิกใช้งานแล้ว

ปัญหา

ข้อผิดพลาดชั่วคราวนี้แสดงว่าบริการ Google Play Billing อยู่ในขณะนี้ ไม่พร้อมใช้งาน ในกรณีส่วนใหญ่ นั่นหมายถึงมีปัญหาในการเชื่อมต่อเครือข่าย ที่ใดก็ได้ระหว่างอุปกรณ์ไคลเอ็นต์กับบริการเรียกเก็บเงินของ Google Play

วิธีแก้ปัญหาที่เป็นไปได้

ปัญหานี้มักเป็นปัญหาชั่วคราว ลองส่งคำขออีกครั้งโดยใช้ กลยุทธ์ Backoff อย่างง่ายหรือแบบเอ็กซ์โปเนนเชียล ขึ้นอยู่กับว่าการดำเนินการใดแสดงผล

เลิกชอบ SERVICE_DISCONNECTED การเชื่อมต่อกับบริการ Google Play Billing ไม่ได้ถูกตัดขาด และคุณต้อง เพื่อลองการดำเนินการใดก็ตามที่กำลังทำอยู่อีกครั้ง

BILLING_UNAVAILABLE (รหัสข้อผิดพลาด 3)

ปัญหา

ข้อผิดพลาดนี้แสดงว่าเกิดข้อผิดพลาดกับการเรียกเก็บเงินของผู้ใช้ระหว่าง ขั้นตอนการซื้อ ตัวอย่างเช่น

  • แอป Play Store บนอุปกรณ์ของผู้ใช้เป็นเวอร์ชันเก่า
  • ผู้ใช้อยู่ในประเทศที่ไม่รองรับ
  • ผู้ใช้รายนี้เป็นผู้ใช้ขององค์กร และผู้ดูแลระบบขององค์กรได้ปิดใช้ผู้ใช้ จากการซื้อสินค้า
  • Google Play เรียกเก็บเงินจากวิธีการชำระเงินของผู้ใช้ไม่ได้ ตัวอย่างเช่น พารามิเตอร์ บัตรเครดิตของผู้ใช้ อาจหมดอายุ

วิธีแก้ปัญหาที่เป็นไปได้

การลองซ้ำอัตโนมัติไม่น่าจะช่วยได้ในกรณีนี้ อย่างไรก็ตาม การลองอีกครั้งด้วยตนเองอาจ ความช่วยเหลือในกรณีที่ผู้ใช้จะจัดการกับเงื่อนไขที่ทำให้เกิดปัญหา ตัวอย่างเช่น หาก ผู้ใช้อัปเดตเวอร์ชัน Play Store เป็นเวอร์ชันที่รองรับ จากนั้นเป็นคู่มือ ลองดำเนินการเริ่มต้นอีกครั้งอาจได้ผล

ถ้าข้อผิดพลาดนี้เกิดขึ้นขณะที่ผู้ใช้ไม่ได้อยู่ในเซสชัน การลองอีกครั้งอาจไม่ทำให้ ความรู้สึก เมื่อคุณได้รับBILLING_UNAVAILABLE ซึ่งเป็นผลมาจากขั้นตอนการซื้อ มีแนวโน้มสูงว่าผู้ใช้จะได้รับ ความคิดเห็นใดๆ จาก Google Play ระหว่างขั้นตอนการซื้อและอาจทราบว่า มีข้อผิดพลาดเกิดขึ้น ในกรณีนี้ คุณสามารถแสดงข้อความแสดงข้อผิดพลาดโดยระบุบางสิ่ง เกิดข้อผิดพลาดและเสนอปุ่ม "ลองอีกครั้ง" เพื่อให้ผู้ใช้มีตัวเลือก ลองอีกครั้งด้วยตนเองหลังจากที่แก้ไขปัญหาแล้ว

ERROR (รหัสข้อผิดพลาด 6)

ปัญหา

นี่เป็นข้อผิดพลาดร้ายแรงที่บ่งชี้ว่าเกิดปัญหาภายในกับ Google Play โดยตรง

วิธีแก้ปัญหาที่เป็นไปได้

บางครั้งปัญหาภายใน Google Play ที่นำไปสู่ ERROR เกิดขึ้นชั่วคราว และลองใช้ Exponential Backoff อีกครั้ง การผ่อนปรนชั่วคราว เมื่อผู้ใช้อยู่ในเซสชัน ขอแนะนำให้ลองอีกครั้ง ดังนี้

สินค้าที่ซื้อแล้ว

ปัญหา

คำตอบนี้ระบุว่าผู้ใช้ Google Play เป็นเจ้าของ การสมัครใช้บริการหรือผลิตภัณฑ์แบบซื้อครั้งเดียวที่ผู้ใช้พยายามจะซื้อ ในกรณีส่วนใหญ่ ข้อผิดพลาดนี้ไม่ใช่ข้อผิดพลาดชั่วคราว ยกเว้นในกรณีที่เกิดจาก แคชของ Google Play ที่ไม่มีการอัปเดต

วิธีแก้ปัญหาที่เป็นไปได้

เพื่อหลีกเลี่ยงข้อผิดพลาดนี้เมื่อสาเหตุไม่ใช่ปัญหาเกี่ยวกับแคช อย่าเสนอ ผลิตภัณฑ์ที่ต้องการซื้อได้เมื่อผู้ใช้เป็นเจ้าของผลิตภัณฑ์นั้นอยู่แล้ว อย่าลืมตรวจสอบ การให้สิทธิ์ของผู้ใช้เมื่อคุณแสดงผลิตภัณฑ์ที่พร้อมจำหน่าย และ กรองสิ่งที่ผู้ใช้ซื้อตามความเหมาะสม เมื่อแอปไคลเอ็นต์ได้รับข้อผิดพลาดนี้เนื่องจากปัญหาเกี่ยวกับแคช ข้อผิดพลาดจะทริกเกอร์ แคชของ Google Play เพื่ออัปเดตข้อมูลล่าสุดจากแบ็กเอนด์ของ Play การลองซ้ำหลังจากที่เกิดข้อผิดพลาดควรแก้ไขอินสแตนซ์ชั่วคราวนี้ในกรณีนี้ โทร BillingClient.queryPurchasesAsync() หลังจากได้รับ ITEM_ALREADY_OWNED เพื่อตรวจสอบว่าผู้ใช้ได้ผลิตภัณฑ์แล้วหรือยัง และไม่ได้เป็นอย่างนั้น ใช้ตรรกะการลองอีกครั้งอย่างง่ายเพื่อพยายามซื้ออีกครั้ง

สินค้าไม่ใช่สินค้า

ปัญหา

การตอบกลับการซื้อนี้ระบุว่าผู้ใช้ Google Play ไม่ได้เป็นเจ้าของ การสมัครใช้บริการหรือผลิตภัณฑ์ที่ซื้อครั้งเดียวที่ผู้ใช้พยายามเปลี่ยนใหม่ รับทราบหรือใช้งาน นี่ไม่ใช่ข้อผิดพลาดชั่วคราวในกรณีส่วนใหญ่ ยกเว้นในกรณีที่เกิดจาก Google แคชของ Play อยู่ในสถานะไม่มีอัปเดต

วิธีแก้ปัญหาที่เป็นไปได้

เมื่อได้รับข้อผิดพลาดเนื่องจากปัญหาเกี่ยวกับแคช ข้อผิดพลาดจะทริกเกอร์ Google แคชของ Play เพื่ออัปเดตเป็นข้อมูลล่าสุดจากแบ็กเอนด์ของ Play กำลังลองใหม่ ด้วยกลยุทธ์การลองใหม่แบบง่ายๆ หลังจากที่ข้อผิดพลาด ควรแก้ไขปัญหานี้ ชั่วคราว โทรหา BillingClient.queryPurchasesAsync() หลังจากได้รับ ITEM_NOT_OWNED เพื่อตรวจสอบว่าผู้ใช้ ได้รับผลิตภัณฑ์ หากไม่มี ให้ใช้ตรรกะการลองใหม่อย่างง่ายเพื่อพยายาม การซื้อ

การตอบกลับของผลลัพธ์การเรียกเก็บเงินที่ไม่สามารถเรียกคืนได้

คุณไม่สามารถกู้คืนจากข้อผิดพลาดเหล่านี้โดยใช้ตรรกะการลองอีกครั้งได้

ไม่รองรับ

ปัญหา

ข้อผิดพลาดที่ไม่สามารถกู้คืนได้นี้บ่งชี้ว่าฟีเจอร์การเรียกเก็บเงินของ Google Play ได้รับการรองรับในอุปกรณ์ของผู้ใช้ อาจเป็นเพราะ Play Store เวอร์ชันเก่า

ตัวอย่างเช่น ผู้ใช้บางคน อุปกรณ์ไม่รองรับการรับส่งข้อความในแอป

การผ่อนปรนชั่วคราวที่อาจเกิดขึ้น

ใช้ BillingClient.isFeatureSupported() เพื่อตรวจสอบการสนับสนุนเกี่ยวกับฟีเจอร์ก่อนโทรหา Play Billing คลัง

when {
  billingClient.isReady -> {
    if (billingClient.isFeatureSupported(BillingClient.FeatureType.IN_APP_MESSAGING)) {
       // use feature
    }
  }
}

ผู้ใช้ยกเลิกแล้ว

ปัญหา

ผู้ใช้ได้คลิกออกจาก UI ขั้นตอนการเรียกเก็บเงิน

วิธีแก้ปัญหาที่เป็นไปได้

นี่เป็นเพียงการให้ข้อมูลเท่านั้น และอาจล้มเหลวได้อย่างไม่น่าเชื่อ

ไม่มีสินค้าพร้อมจำหน่าย

ปัญหา

การสมัครใช้บริการ Google Play Billing หรือผลิตภัณฑ์แบบครั้งเดียวไม่ได้ ที่สามารถซื้อได้สำหรับผู้ใช้รายนี้

การผ่อนปรนชั่วคราวที่อาจเกิดขึ้น

ตรวจสอบว่าแอปของคุณรีเฟรชรายละเอียดผลิตภัณฑ์ผ่าน queryProductDetailsAsync ตามที่แนะนำ โดยคำนึงถึงความถี่ การเปลี่ยนแปลงแคตตาล็อกผลิตภัณฑ์ในการกำหนดค่า Play Console เพื่อนำไปใช้ รีเฟรชเพิ่มเติมหากจำเป็น พยายามขายผลิตภัณฑ์ใน Google Play Billing ที่ส่งคืนเฉพาะด้านขวาเท่านั้น ผ่าน queryProductDetailsAsync โปรดตรวจสอบการกำหนดค่าการมีสิทธิ์ของผลิตภัณฑ์เพื่อหาความไม่สอดคล้องกัน เช่น คุณอาจกำลังค้นหาผลิตภัณฑ์ที่มีจำหน่ายเฉพาะ ที่ไม่ใช่ภูมิภาคที่ผู้ใช้พยายามซื้อ ผลิตภัณฑ์จะต้องอยู่ในสถานะใช้งานอยู่ แอปของผลิตภัณฑ์นั้นจะต้อง เผยแพร่แล้ว และแอปจะต้องพร้อมให้บริการในประเทศของผู้ใช้

บางครั้งโดยเฉพาะอย่างยิ่ง ในระหว่างการทดสอบ ข้อมูลทุกอย่างถูกต้องในผลิตภัณฑ์ การกำหนดค่า แต่ผู้ใช้ยังคงเห็นข้อผิดพลาดนี้ อาจเกิดจากสาเหตุ ความล่าช้าในการเผยแพร่รายละเอียดผลิตภัณฑ์บนเซิร์ฟเวอร์ของ Google ลองอีกครั้ง ในภายหลัง

ข้อผิดพลาดจากนักพัฒนาซอฟต์แวร์

ปัญหา

นี่เป็นข้อผิดพลาดร้ายแรงที่บ่งชี้ว่าคุณกำลังใช้ API อย่างไม่เหมาะสม ตัวอย่างเช่น การระบุพารามิเตอร์ที่ไม่ถูกต้องให้กับ BillingClient.launchBillingFlow สามารถ ทำให้เกิดข้อผิดพลาดนี้

วิธีแก้ปัญหาที่เป็นไปได้

ตรวจสอบว่าคุณใช้ Play Billing Library อื่นอย่างถูกต้อง นอกจากนี้ ให้ตรวจสอบข้อความแก้ไขข้อบกพร่องเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับข้อผิดพลาด