เมื่อการเรียกใช้ Play Billing Library ทริกเกอร์การดำเนินการ ไลบรารีจะส่งการตอบกลับ BillingResult
เพื่อแจ้งให้นักพัฒนาแอปทราบผลลัพธ์ เช่น หากคุณใช้
queryProductDetailsAsync
เพื่อรับข้อเสนอที่พร้อมให้บริการแก่ผู้ใช้ โค้ดตอบกลับจะมีโค้ด
OK และระบุออบเจ็กต์ 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) }
} finally {
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
}
การตอบกลับ BillingResult ที่ลองใหม่ได้
NETWORK_ERROR (รหัสข้อผิดพลาด 12)
ปัญหา
ข้อผิดพลาดนี้แสดงว่าเกิดปัญหาเกี่ยวกับการเชื่อมต่อเครือข่าย ระหว่างอุปกรณ์กับระบบ Play
การแก้ไขที่เป็นไปได้
หากต้องการกู้คืน ให้ใช้การลองใหม่แบบง่ายหรือ Exponential Backoff ขึ้นอยู่กับว่า การดำเนินการใดที่ทำให้เกิดข้อผิดพลาด
SERVICE_TIMEOUT (รหัสข้อผิดพลาด -3)
ปัญหา
ข้อผิดพลาดนี้บ่งชี้ว่าคำขอถึงระยะหมดเวลาสูงสุดแล้วก่อนที่ Google Play จะตอบกลับได้ ซึ่งอาจเกิดจากความล่าช้า ในการดำเนินการที่เรียกใช้โดย Play Billing Library เป็นต้น
การแก้ไขที่เป็นไปได้
โดยปกติแล้ว ปัญหานี้จะเกิดขึ้นชั่วคราว ลองส่งคำขออีกครั้งโดยใช้กลยุทธ์ Exponential Backoff หรือกลยุทธ์แบบง่าย ขึ้นอยู่กับการดำเนินการที่ทำให้เกิดข้อผิดพลาด
การเชื่อมต่อกับบริการ Google Play Billing จะไม่ถูกตัดขาดเหมือนกับSERVICE_DISCONNECTED
ด้านล่าง และคุณ
เพียงแค่ต้องลองดำเนินการใดก็ตามใน Play Billing Library ที่พยายามทำอีกครั้ง
SERVICE_DISCONNECTED (รหัสข้อผิดพลาด -1)
ปัญหา
ข้อผิดพลาดร้ายแรงนี้บ่งชี้ว่าการเชื่อมต่อของแอปไคลเอ็นต์กับบริการ Google Play
Store ผ่าน BillingClient
ถูกตัดขาด
การแก้ไขที่เป็นไปได้
ขอแนะนำอย่างยิ่ง: เปิดใช้การเชื่อมต่อบริการอีกครั้งโดยอัตโนมัติ
Play Billing Library เวอร์ชัน 8.0.0 ได้เปิดตัวฟีเจอร์
enableAutoServiceReconnection()
เราขอแนะนำอย่างยิ่งให้คุณเปิดใช้ฟีเจอร์นี้เมื่อสร้าง
BillingClient ซึ่งจะช่วยให้ไลบรารีพยายามสร้างการเชื่อมต่อใหม่โดยอัตโนมัติ
เมื่อมีการเรียก API การเรียกเก็บเงินขณะที่บริการ
ถูกตัดการเชื่อมต่อ ซึ่งจะช่วยลดการเกิดข้อผิดพลาดนี้ได้อย่างมาก
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 เมื่อทำการเรียก API แสดงว่าไลบรารีเชื่อมต่อใหม่ไม่ได้หลังจากพยายามโดยอัตโนมัติ
ในกรณีนี้ คุณควรใช้ตรรกะการลองใหม่ในแอป
- สําหรับการกระทําที่ผู้ใช้เริ่มต้น (ในเซสชัน): ใช้การลองใหม่แบบง่ายของ API call ปัญหาที่เกิดขึ้นอาจเป็นปัญหาชั่วคราว
- สำหรับคำขอในเบื้องหลัง: ใช้การลองใหม่ด้วย Exponential Backoff เพื่อ หลีกเลี่ยงการทำให้ระบบทำงานหนักเกินไปหากการตัดการเชื่อมต่อเป็นเวลานาน
หากคุณไม่ได้เปิดใช้การเชื่อมต่อบริการอีกครั้งโดยอัตโนมัติ
หากต้องการหลีกเลี่ยงข้อผิดพลาดนี้ให้ได้มากที่สุด ให้ตรวจสอบการเชื่อมต่อกับบริการ Google
Play เสมอก่อนที่จะทำการเรียกใช้ด้วย 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 Billing
การแก้ไขที่เป็นไปได้
โดยปกติแล้ว ปัญหานี้จะเกิดขึ้นชั่วคราว ลองส่งคำขออีกครั้งโดยใช้กลยุทธ์ Exponential Backoff หรือกลยุทธ์แบบง่าย ขึ้นอยู่กับการดำเนินการที่ทำให้เกิดข้อผิดพลาด
ซึ่งแตกต่างจาก SERVICE_DISCONNECTED ที่การเชื่อมต่อกับบริการ Google Play Billing จะไม่ถูกตัดขาด และคุณต้องลองดำเนินการใดก็ตามที่พยายามทำอีกครั้ง
BILLING_UNAVAILABLE (รหัสข้อผิดพลาด 3)
ปัญหา
ข้อผิดพลาดนี้บ่งชี้ว่าเกิดข้อผิดพลาดในการเรียกเก็บเงินจากผู้ใช้ในระหว่างกระบวนการซื้อ ตัวอย่างของกรณีที่อาจเกิดเหตุการณ์นี้มีดังนี้
- แอป Play Store ในอุปกรณ์ของผู้ใช้เป็นเวอร์ชันเก่า
- ผู้ใช้อยู่ในประเทศที่ไม่รองรับ
- ผู้ใช้เป็นผู้ใช้ระดับองค์กร และผู้ดูแลระบบขององค์กรได้ปิดใช้ไม่ให้ผู้ใช้ ทำการซื้อ
- Google Play เรียกเก็บเงินจากวิธีการชำระเงินของผู้ใช้ไม่ได้ เช่น บัตรเครดิตของผู้ใช้อาจหมดอายุ
การแก้ไขที่เป็นไปได้
การลองอีกครั้งโดยอัตโนมัติไม่น่าจะช่วยได้ในกรณีนี้ อย่างไรก็ตาม การลองอีกครั้งด้วยตนเองอาจช่วยได้หากผู้ใช้แก้ไขเงื่อนไขที่ทำให้เกิดปัญหา ตัวอย่างเช่น หากผู้ใช้อัปเดต Play Store เป็นเวอร์ชันที่รองรับ การลอง ดำเนินการครั้งแรกอีกครั้งด้วยตนเองอาจได้ผล
หากข้อผิดพลาดนี้เกิดขึ้นเมื่อผู้ใช้ไม่ได้อยู่ในเซสชัน การลองอีกครั้งอาจไม่
สมเหตุสมผล
เมื่อคุณได้รับข้อผิดพลาด BILLING_UNAVAILABLE
อันเป็นผลมาจากขั้นตอนการซื้อ มีแนวโน้มสูงที่ผู้ใช้จะได้รับ
ความคิดเห็นจาก Google Play ในระหว่างกระบวนการซื้อและอาจทราบว่า
เกิดข้อผิดพลาดอะไรขึ้น ในกรณีนี้ คุณอาจแสดงข้อความแสดงข้อผิดพลาดที่ระบุว่ามีบางอย่างผิดพลาด และเสนอปุ่ม "ลองอีกครั้ง" เพื่อให้ผู้ใช้มีตัวเลือกในการลองอีกครั้งด้วยตนเองหลังจากแก้ไขปัญหาแล้ว
ข้อผิดพลาด (รหัสข้อผิดพลาด 6)
ปัญหา
นี่เป็นข้อผิดพลาดร้ายแรงที่บ่งบอกถึงปัญหาภายในของ Google Play เอง
การแก้ไขที่เป็นไปได้
บางครั้งปัญหาภายในของ Google Play ที่ทำให้เกิด ERROR อาจเกิดขึ้นชั่วคราว และสามารถลองอีกครั้งโดยใช้ Exponential Backoff เพื่อลดปัญหาได้ เมื่อผู้ใช้อยู่ในเซสชัน การลองอีกครั้งแบบง่ายๆ จะดีกว่า
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 การลองอีกครั้ง
ด้วยกลยุทธ์การลองอีกครั้งอย่างง่ายหลังจากเกิดข้อผิดพลาดควรแก้ไขอินสแตนซ์ชั่วคราวที่เฉพาะเจาะจงนี้ได้ เรียกใช้ BillingClient.queryPurchasesAsync() หลังจากได้รับ ITEM_NOT_OWNED เพื่อตรวจสอบว่าผู้ใช้ได้
ซื้อผลิตภัณฑ์แล้วหรือไม่ หากยังไม่ได้ ให้ใช้ตรรกะการลองใหม่แบบง่ายเพื่อลองซื้ออีกครั้ง
การตอบกลับ BillingResult ที่เรียกคืนไม่ได้
คุณไม่สามารถกู้คืนจากข้อผิดพลาดเหล่านี้ได้โดยใช้ตรรกะการลองใหม่
FEATURE_NOT_SUPPORTED
ปัญหา
ข้อผิดพลาดที่ไม่สามารถลองใหม่นี้บ่งชี้ว่าฟีเจอร์ Google Play Billing ไม่ รองรับในอุปกรณ์ของผู้ใช้ ซึ่งอาจเป็นเพราะ Play Store เวอร์ชันเก่า
เช่น อุปกรณ์ของผู้ใช้บางรายอาจไม่รองรับการรับส่งข้อความในแอป
การผ่อนปรนชั่วคราวที่อาจเกิดขึ้น
ใช้ BillingClient.isFeatureSupported() เพื่อตรวจสอบการรองรับฟีเจอร์ก่อนโทรไปยัง Play Billing
Library
when {
billingClient.isReady -> {
if (billingClient.isFeatureSupported(BillingClient.FeatureType.IN_APP_MESSAGING)) {
// use feature
}
}
}
USER_CANCELED
ปัญหา
ผู้ใช้คลิกออกจาก UI ของขั้นตอนการเรียกเก็บเงิน
การแก้ไขที่เป็นไปได้
ซึ่งเป็นเพียงข้อมูลและอาจล้มเหลวได้
ITEM_UNAVAILABLE
ปัญหา
การสมัครใช้บริการ Google Play Billing หรือผลิตภัณฑ์แบบซื้อครั้งเดียวไม่พร้อมให้ผู้ใช้รายนี้ซื้อ
การผ่อนปรนชั่วคราวที่อาจเกิดขึ้น
ตรวจสอบว่าแอปรีเฟรชรายละเอียดสินค้าผ่าน queryProductDetailsAsync ตามที่แนะนำ พิจารณาความถี่ที่แคตตาล็อกสินค้ามีการเปลี่ยนแปลงในการกำหนดค่า Play Console เพื่อใช้การรีเฟรชเพิ่มเติมหากจำเป็น
พยายามขายผลิตภัณฑ์ใน Google Play Billing ที่แสดงข้อมูลที่ถูกต้องผ่าน queryProductDetailsAsync เท่านั้น
ตรวจสอบการกำหนดค่าการมีสิทธิ์ของผลิตภัณฑ์เพื่อดูความไม่สอดคล้องกัน
เช่น คุณอาจค้นหาผลิตภัณฑ์ที่ใช้ได้เฉพาะใน
ภูมิภาคอื่นที่ไม่ใช่ภูมิภาคที่ผู้ใช้พยายามซื้อ
ผลิตภัณฑ์จะต้องอยู่ในสถานะใช้งานอยู่ จะต้องมีการเผยแพร่แอปของผลิตภัณฑ์นั้น และแอปจะต้องพร้อมให้บริการในประเทศของผู้ใช้เพื่อให้ผลิตภัณฑ์พร้อมจำหน่าย
บางครั้ง โดยเฉพาะอย่างยิ่งในระหว่างการทดสอบ การกำหนดค่าผลิตภัณฑ์อาจถูกต้องทุกอย่าง แต่ผู้ใช้ยังคงเห็นข้อผิดพลาดนี้ ซึ่งอาจเกิดจากความล่าช้าในการเผยแพร่รายละเอียดผลิตภัณฑ์ในเซิร์ฟเวอร์ของ Google โปรดลองอีกครั้ง ในภายหลัง
DEVELOPER_ERROR
ปัญหา
นี่คือข้อผิดพลาดร้ายแรงที่แสดงว่าคุณใช้ API อย่างไม่ถูกต้อง
เช่น การระบุพารามิเตอร์ที่ไม่ถูกต้องให้กับ BillingClient.launchBillingFlow อาจทำให้เกิดข้อผิดพลาดนี้ได้
การแก้ไขที่เป็นไปได้
ตรวจสอบว่าคุณใช้การเรียกใช้ Play Billing Library ที่แตกต่างกันอย่างถูกต้อง นอกจากนี้ ให้ตรวจสอบข้อความแก้ไขข้อบกพร่องเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับข้อผิดพลาด