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

เมื่อการเรียกใช้ไลบรารี Play Billing ทริกเกอร์การดำเนินการ ไลบรารีจะแสดงผลตอบกลับ 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

เราขอแนะนำให้ใช้การลดจำนวนการทำงานแบบทวีคูณสำหรับการดำเนินการของ 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 เสมอก่อนที่จะเรียกใช้คลังการเรียกเก็บเงินของ Play โดยเรียกใช้ 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 Billing

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

ปัญหานี้มักเป็นปัญหาชั่วคราว ลองส่งคําขออีกครั้งโดยใช้กลยุทธ์ Exponential Backoff หรือ Simple 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 เกิดขึ้นนั้นอาจเกิดขึ้นชั่วคราว และคุณอาจลองดำเนินการอีกครั้งโดยลดจำนวนครั้งลงแบบทวีคูณเพื่อบรรเทาปัญหาได้ เมื่อผู้ใช้อยู่ในเซสชัน ขอแนะนำให้ลองอีกครั้ง ดังนี้

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

ปัญหา

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

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

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

ITEM_NOT_OWNED

ปัญหา

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

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

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

คำตอบ BillingResult ที่ดึงข้อมูลไม่ได้

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

FEATURE_NOT_SUPPORTED

ปัญหา

ข้อผิดพลาดที่ดึงข้อมูลไม่ได้นี้บ่งบอกว่าอุปกรณ์ของผู้ใช้ไม่รองรับฟีเจอร์ Google Play Billing ซึ่งอาจเกิดจาก 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 สามารถ ทำให้เกิดข้อผิดพลาดนี้

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

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