เอกสารนี้อธิบายวิธีผสานรวม Google Play Billing Library เข้ากับแอปเพื่อเริ่มขายผลิตภัณฑ์
วงจรของการซื้อ
ต่อไปนี้คือขั้นตอนการซื้อทั่วไปสำหรับการซื้อแบบครั้งเดียวหรือการสมัครใช้บริการ
- แสดงให้ผู้ใช้เห็นว่าซื้ออะไรได้บ้าง
- เปิดตัวขั้นตอนการซื้อเพื่อให้ผู้ใช้ยอมรับการซื้อ
- ยืนยันการซื้อในเซิร์ฟเวอร์
- แสดงเนื้อหาต่อผู้ใช้
- รับทราบการนำส่งเนื้อหา สำหรับไอเทมที่ใช้แล้วหมดไป ให้ใช้ การซื้อเพื่อให้ผู้ใช้ซื้อไอเทมนั้นได้อีกครั้ง
การสมัครใช้บริการจะต่ออายุโดยอัตโนมัติจนกว่าจะมีการยกเลิก การสมัครใช้บริการอาจมีสถานะต่อไปนี้
- ใช้งานอยู่: ผู้ใช้มีสถานะดีและมีสิทธิ์เข้าถึงการสมัครใช้บริการ
- ยกเลิกแล้ว: ผู้ใช้ยกเลิกแล้วแต่ยังคงมีสิทธิ์เข้าถึงจนกว่าจะหมดอายุ
- ในระยะเวลาผ่อนผัน: ผู้ใช้พบปัญหาเกี่ยวกับการชำระเงินแต่ยังคงมีสิทธิ์เข้าถึง ขณะที่ Google ลองใช้วิธีการชำระเงินอีกครั้ง
- ระงับ: ผู้ใช้พบปัญหาเกี่ยวกับการชำระเงินและไม่มีสิทธิ์เข้าถึงอีกต่อไปในขณะที่ Google กำลังลองเรียกเก็บเงินจากวิธีการชำระเงินอีกครั้ง
- หยุดชั่วคราว: ผู้ใช้หยุดสิทธิ์เข้าถึงชั่วคราวและจะไม่มีสิทธิ์เข้าถึงจนกว่าจะ กลับมาใช้สิทธิ์อีกครั้ง
- หมดอายุ: ผู้ใช้ยกเลิกและเสียสิทธิ์เข้าถึงการสมัครใช้บริการ ระบบจะถือว่าผู้ใช้เลิกใช้งานเมื่อการสมัครใช้บริการหมดอายุ
เริ่มต้นการเชื่อมต่อกับ Google Play
ขั้นตอนแรกในการผสานรวมกับระบบการเรียกเก็บเงินของ Google Play คือการเพิ่ม Google Play Billing Library ลงในแอปและเริ่มต้นการเชื่อมต่อ
เพิ่มการอ้างอิงไลบรารี Google Play Billing
เพิ่มทรัพยากร Dependency ของ Google Play Billing Library ลงในไฟล์ build.gradle
ของแอปตามที่แสดง
Groovy
dependencies { def billing_version = "8.0.0" implementation "com.android.billingclient:billing:$billing_version" }
Kotlin
dependencies { val billing_version = "8.0.0" implementation("com.android.billingclient:billing:$billing_version") }
หากใช้ Kotlin โมดูล KTX ของ Google Play Billing Library จะมีส่วนขยาย Kotlin และการรองรับ Coroutine ที่ช่วยให้คุณเขียน Kotlin ที่เป็นสำนวนได้เมื่อใช้ Google Play Billing Library
หากต้องการรวมส่วนขยายเหล่านี้ไว้ในโปรเจ็กต์ ให้เพิ่มทรัพยากร Dependency ต่อไปนี้ลงในไฟล์ build.gradle
ของแอปตามที่แสดง
Groovy
dependencies { def billing_version = "8.0.0" implementation "com.android.billingclient:billing-ktx:$billing_version" }
Kotlin
dependencies { val billing_version = "8.0.0" implementation("com.android.billingclient:billing-ktx:$billing_version") }
เริ่มต้น BillingClient
เมื่อเพิ่มการอ้างอิงใน Google Play Billing Library แล้ว คุณจะต้อง
เริ่มต้นอินสแตนซ์ BillingClient
BillingClient
เป็นอินเทอร์เฟซหลัก
สำหรับการสื่อสารระหว่าง Google Play Billing Library กับ
ส่วนอื่นๆ ของแอป BillingClient
มีวิธีการที่สะดวกทั้งแบบซิงโครนัส
และอะซิงโครนัสสำหรับการดำเนินการเรียกเก็บเงินทั่วไปหลายอย่าง ข้อควรทราบมีดังนี้
- เราขอแนะนำให้คุณมีการเชื่อมต่อ
BillingClient
ที่ใช้งานอยู่ 1 รายการ เปิดไว้ในครั้งเดียวเพื่อหลีกเลี่ยงการเรียกกลับPurchasesUpdatedListener
หลายรายการ สำหรับเหตุการณ์เดียว - เราขอแนะนำให้เริ่มการเชื่อมต่อสำหรับ BillingClient เมื่อเปิดแอปหรือนำแอปมาไว้เบื้องหน้าเพื่อให้มั่นใจว่าแอปจะประมวลผลการซื้อได้ทันท่วงที
ซึ่งทำได้โดยใช้
ActivityLifecycleCallbacks
ที่ลงทะเบียนโดยregisterActivityLifecycleCallbacks
และรอ onActivityResumed เพื่อเริ่มต้นการเชื่อมต่อเมื่อตรวจพบว่ามีการกลับมาใช้ กิจกรรมอีกครั้งเป็นครั้งแรก ดูรายละเอียดเพิ่มเติมเกี่ยวกับเหตุผลที่ควรปฏิบัติตามแนวทางปฏิบัติแนะนำนี้ได้ที่ส่วนการประมวลผลการซื้อ นอกจากนี้ อย่าลืม สิ้นสุดการเชื่อมต่อเมื่อปิดแอป
หากต้องการสร้าง BillingClient
ให้ใช้ newBuilder
คุณส่งบริบทใดก็ได้ไปยัง
newBuilder()
และ BillingClient
จะใช้บริบทนั้นเพื่อรับบริบทของแอปพลิเคชัน ซึ่งหมายความว่าคุณไม่ต้องกังวลเรื่องหน่วยความจำรั่ว หากต้องการรับข้อมูลอัปเดตเกี่ยวกับการซื้อ คุณต้องเรียกใช้ setListener
โดยส่งการอ้างอิงไปยัง PurchasesUpdatedListener
ด้วย ผู้ฟังรายนี้จะได้รับการอัปเดตสำหรับการซื้อทั้งหมดในแอปของคุณ
Kotlin
private val purchasesUpdatedListener = PurchasesUpdatedListener { billingResult, purchases -> // To be implemented in a later section. } private var billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) // Configure other settings. .build()
Java
private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() { @Override public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) { // To be implemented in a later section. } }; private BillingClient billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) // Configure other settings. .build();
เชื่อมต่อกับ Google Play
หลังจากสร้าง BillingClient
แล้ว คุณต้องสร้างการเชื่อมต่อกับ
Google Play
หากต้องการเชื่อมต่อกับ Google Play โปรดโทร startConnection
กระบวนการเชื่อมต่อ
เป็นแบบอะซิงโครนัส และคุณต้องใช้ BillingClientStateListener
เพื่อ
รับการเรียกกลับเมื่อการตั้งค่าไคลเอ็นต์เสร็จสมบูรณ์และพร้อมที่จะ
ส่งคำขอเพิ่มเติม
นอกจากนี้ คุณยังต้องใช้ตรรกะการลองใหม่เพื่อจัดการการเชื่อมต่อกับ Google Play ที่ขาดหายไป
หากต้องการใช้ตรรกะการลองใหม่ ให้ลบล้างเมธอดเรียกกลับ onBillingServiceDisconnected()
และตรวจสอบว่า BillingClient
เรียกเมธอด
startConnection()
เพื่อเชื่อมต่อกับ Google Play อีกครั้งก่อนที่จะส่งคำขอเพิ่มเติม
ตัวอย่างต่อไปนี้แสดงวิธีเริ่มการเชื่อมต่อและทดสอบว่าพร้อมใช้งาน แล้ว
Kotlin
billingClient.startConnection(object : BillingClientStateListener { override fun onBillingSetupFinished(billingResult: BillingResult) { if (billingResult.responseCode == BillingResponseCode.OK) { // The BillingClient is ready. You can query purchases here. } } override fun onBillingServiceDisconnected() { // Try to restart the connection on the next request to // Google Play by calling the startConnection() method. } })
Java
billingClient.startConnection(new BillingClientStateListener() { @Override public void onBillingSetupFinished(BillingResult billingResult) { if (billingResult.getResponseCode() == BillingResponseCode.OK) { // The BillingClient is ready. You can query purchases here. } } @Override public void onBillingServiceDisconnected() { // Try to restart the connection on the next request to // Google Play by calling the startConnection() method. } });
สร้างการเชื่อมต่อใหม่โดยอัตโนมัติ
เมื่อเปิดตัวเมธอด enableAutoServiceReconnection()
ในBillingClient.Builder
เวอร์ชัน 8.0.0 ตอนนี้ Play Billing Library สามารถสร้างการเชื่อมต่อบริการใหม่โดยอัตโนมัติได้หากมีการเรียก API ขณะที่บริการไม่ได้เชื่อมต่อ ซึ่งอาจส่งผลให้การตอบกลับของ SERVICE_DISCONNECTED
ลดลงเนื่องจากระบบจัดการการเชื่อมต่อใหม่ภายในก่อนที่จะเรียกใช้ API
วิธีเปิดใช้การเชื่อมต่อใหม่โดยอัตโนมัติ
เมื่อสร้างอินสแตนซ์ BillingClient
ให้ใช้วิธี enableAutoServiceReconnection()
ใน BillingClient.Builder
เพื่อเปิดใช้การเชื่อมต่อใหม่โดยอัตโนมัติ
Kotlin
val billingClient = BillingClient.newBuilder(context)
.setListener(listener)
.enablePendingPurchases()
.enableAutoServiceReconnection() // Add this line to enable reconnection
.build()
Java
BillingClient billingClient = BillingClient.newBuilder(context)
.setListener(listener)
.enablePendingPurchases()
.enableAutoServiceReconnection() // Add this line to enable reconnection
.build();
แสดงผลิตภัณฑ์ที่พร้อมจำหน่าย
หลังจากสร้างการเชื่อมต่อกับ Google Play แล้ว คุณก็พร้อมที่จะค้นหา ผลิตภัณฑ์ที่พร้อมให้บริการและแสดงต่อผู้ใช้
การค้นหารายละเอียดผลิตภัณฑ์เป็นขั้นตอนสำคัญก่อนแสดงผลิตภัณฑ์ต่อผู้ใช้ เนื่องจากจะแสดงข้อมูลผลิตภัณฑ์ที่แปลเป็นภาษาท้องถิ่น สำหรับข้อมูลการสมัครใช้บริการ ให้ตรวจสอบว่าการแสดงผลิตภัณฑ์เป็นไปตามนโยบายทั้งหมดของ Play
หากต้องการค้นหารายละเอียดผลิตภัณฑ์แบบเรียกเก็บเงินครั้งเดียว ให้เรียกใช้เมธอด queryProductDetailsAsync
วิธีนี้จะแสดงข้อเสนอหลายรายการตามการกำหนดค่าผลิตภัณฑ์แบบเรียกเก็บเงินครั้งเดียว
ดูข้อมูลเพิ่มเติมได้ที่ตัวเลือกการซื้อและข้อเสนอหลายรายการ
สำหรับผลิตภัณฑ์แบบเรียกเก็บเงินครั้งเดียว
หากต้องการจัดการผลลัพธ์ของการดำเนินการแบบไม่พร้อมกัน คุณต้องระบุ
เครื่องมือฟังที่ใช้ProductDetailsResponseListener
อินเทอร์เฟซด้วย
จากนั้นคุณจะลบล้าง onProductDetailsResponse
ซึ่งจะแจ้งเตือน
ผู้ฟังเมื่อการค้นหาเสร็จสิ้น ดังที่แสดงในตัวอย่างต่อไปนี้
Kotlin
val queryProductDetailsParams = QueryProductDetailsParams.newBuilder() .setProductList( ImmutableList.of( Product.newBuilder() .setProductId("product_id_example") .setProductType(ProductType.SUBS) .build())) .build() billingClient.queryProductDetailsAsync(queryProductDetailsParams) { billingResult, queryProductDetailsResult -> if (billingResult.getResponseCode() == BillingResponseCode.OK) { for (ProductDetails productDetails : queryProductDetailsResult.getProductDetailsList()) { // Process successfully retrieved product details here. } for (UnfetchedProduct unfetchedProduct : queryproductDetailsResult.getUnfetchedProductList()) { // Handle any unfetched products as appropriate. } } }
Java
QueryProductDetailsParams queryProductDetailsParams = QueryProductDetailsParams.newBuilder() .setProductList( ImmutableList.of( Product.newBuilder() .setProductId("product_id_example") .setProductType(ProductType.SUBS) .build())) .build(); billingClient.queryProductDetailsAsync( queryProductDetailsParams, new ProductDetailsResponseListener() { public void onProductDetailsResponse(BillingResult billingResult, QueryProductDetailsResult queryProductDetailsResult) { if (billingResult.getResponseCode() == BillingResponseCode.OK) { for (ProductDetails productDetails : queryProductDetailsResult().getProductDetailsList()) { // Process success retrieved product details here. } for (UnfetchedProduct unfetchedProduct : queryproductDetailsResult.getUnfetchedProductList()) { // Handle any unfetched products as appropriate. } } } } )
เมื่อค้นหารายละเอียดผลิตภัณฑ์ ให้ส่งอินสแตนซ์ของ
QueryProductDetailsParams
ที่ระบุรายการสตริงรหัสผลิตภัณฑ์
ที่สร้างใน Google Play Console พร้อมกับ ProductType
ProductType
ProductType.INAPP
อาจเป็นสำหรับผลิตภัณฑ์แบบเรียกเก็บเงินครั้งเดียวหรือ
ProductType.SUBS
สำหรับการสมัครใช้บริการ
ค้นหาด้วยส่วนขยาย Kotlin
หากใช้ส่วนขยาย Kotlin คุณจะค้นหารายละเอียดไอเทมแบบเรียกเก็บเงินครั้งเดียวได้
โดยเรียกใช้ฟังก์ชันส่วนขยาย queryProductDetails()
queryProductDetails()
ใช้ประโยชน์จากโครูทีน Kotlin เพื่อให้คุณไม่ต้อง
กำหนด Listener แยกต่างหาก แต่ฟังก์ชันจะระงับจนกว่าการค้นหาจะเสร็จสมบูรณ์ จากนั้นคุณจึงจะประมวลผลผลลัพธ์ได้
suspend fun processPurchases() {
val productList = listOf(
QueryProductDetailsParams.Product.newBuilder()
.setProductId("product_id_example")
.setProductType(BillingClient.ProductType.SUBS)
.build()
)
val params = QueryProductDetailsParams.newBuilder()
params.setProductList(productList)
// leverage queryProductDetails Kotlin extension function
val productDetailsResult = withContext(Dispatchers.IO) {
billingClient.queryProductDetails(params.build())
}
// Process the result.
}
อุปกรณ์บางเครื่องอาจไม่รองรับ ProductDetails
และ
queryProductDetailsAsync()
ซึ่งมักเกิดจากบริการ
Google Play เวอร์ชันเก่า หากต้องการให้การสนับสนุนที่เหมาะสมสำหรับสถานการณ์นี้ โปรดดูวิธีใช้
ฟีเจอร์ความเข้ากันได้แบบย้อนหลังในคู่มือการย้ายข้อมูล Play Billing Library 7
ประมวลผลผลลัพธ์
Google Play Billing Library จะจัดเก็บผลการค้นหาในออบเจ็กต์
QueryProductDetailsResult
QueryProductDetailsResult
มี List
ของออบเจ็กต์ ProductDetails
จากนั้นคุณจะเรียกใช้
วิธีการต่างๆ ในออบเจ็กต์ ProductDetails
แต่ละรายการในรายการเพื่อดูข้อมูลที่เกี่ยวข้อง
เกี่ยวกับผลิตภัณฑ์แบบครั้งเดียวที่ดึงข้อมูลสําเร็จ เช่น
ราคาหรือคําอธิบาย หากต้องการดูข้อมูลรายละเอียดผลิตภัณฑ์ที่มีอยู่ ให้ดูรายการเมธอดในคลาส ProductDetails
QueryProductDetailsResult
ยังมี List
ของ
UnfetchedProduct
ออบเจ็กต์ด้วย จากนั้นคุณจะค้นหา UnfetchedProduct แต่ละรายการ
เพื่อรับรหัสสถานะที่สอดคล้องกับเหตุผลที่ดึงข้อมูลไม่สำเร็จได้
หากต้องการดูข้อมูลผลิตภัณฑ์ที่พร้อมใช้งานซึ่งยังไม่ได้ดึงข้อมูล
ให้ดูรายการเมธอดในคลาส UnfetchedProduct
ก่อนเสนอขายไอเทม ให้ตรวจสอบว่าผู้ใช้ยังไม่มีไอเทมนั้น หากผู้ใช้มีไอเทมที่ใช้แล้วหมดซึ่งยังอยู่ในคลังไอเทม ผู้ใช้ ต้องใช้ไอเทมดังกล่าวให้หมดก่อนจึงจะซื้อได้อีกครั้ง
ก่อนเสนอการสมัครใช้บริการ ให้ตรวจสอบว่าผู้ใช้ยังไม่ได้สมัครใช้บริการ นอกจากนี้ โปรดทราบว่า
สำหรับข้อมูลการสมัครใช้บริการ
queryProductDetailsAsync()
เมธอดจะแสดงรายละเอียดผลิตภัณฑ์การสมัครใช้บริการและข้อเสนอที่มีสิทธิ์สำหรับผู้ใช้สูงสุด 50 รายต่อการสมัครใช้บริการ หากผู้ใช้พยายามซื้อข้อเสนอที่ไม่มีสิทธิ์ (เช่น หากแอปแสดงรายการข้อเสนอที่มีสิทธิ์ที่ล้าสมัย) Play จะแจ้งให้ผู้ใช้ทราบว่าไม่มีสิทธิ์ และผู้ใช้สามารถเลือกซื้อแพ็กเกจเริ่มต้นแทนได้สำหรับผลิตภัณฑ์แบบเรียกเก็บเงินครั้งเดียว เมธอด
queryProductDetailsAsync()
จะแสดงเฉพาะ ข้อเสนอที่ผู้ใช้มีสิทธิ์ หากผู้ใช้พยายามซื้อข้อเสนอที่ไม่มีสิทธิ์ (เช่น หากผู้ใช้ซื้อถึงจำนวนจำกัดแล้ว) Play จะแจ้งให้ผู้ใช้ทราบว่าไม่มีสิทธิ์ และผู้ใช้สามารถเลือกซื้อข้อเสนอตัวเลือกการซื้อแทนได้
เปิดตัวขั้นตอนการซื้อ
หากต้องการเริ่มคำขอซื้อจากแอป ให้เรียกใช้เมธอด launchBillingFlow()
จากเทรดหลักของแอป เมธอดนี้รับการอ้างอิงไปยังออบเจ็กต์
BillingFlowParams
ที่มีออบเจ็กต์
ProductDetails
ที่เกี่ยวข้องซึ่งได้จากการเรียกใช้
queryProductDetailsAsync
หากต้องการสร้างออบเจ็กต์ BillingFlowParams
ให้ใช้คลาส BillingFlowParams.Builder
Kotlin
// An activity reference from which the billing flow will be launched. val activity : Activity = ...; val productDetailsParamsList = listOf( BillingFlowParams.ProductDetailsParams.newBuilder() // retrieve a value for "productDetails" by calling queryProductDetailsAsync() .setProductDetails(productDetails) // Get the offer token: // a. For one-time products, call ProductDetails.getOneTimePurchaseOfferDetailsList() // for a list of offers that are available to the user. // b. For subscriptions, call ProductDetails.subscriptionOfferDetails() // for a list of offers that are available to the user. .setOfferToken(selectedOfferToken) .build() ) val billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList(productDetailsParamsList) .build() // Launch the billing flow val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)
Java
// An activity reference from which the billing flow will be launched. Activity activity = ...; ImmutableList<ProductDetailsParams> productDetailsParamsList = ImmutableList.of( ProductDetailsParams.newBuilder() // retrieve a value for "productDetails" by calling queryProductDetailsAsync() .setProductDetails(productDetails) // Get the offer token: // a. For one-time products, call ProductDetails.getOneTimePurchaseOfferDetailsList() // for a list of offers that are available to the user. // b. For subscriptions, call ProductDetails.subscriptionOfferDetails() // for a list of offers that are available to the user. .setOfferToken(selectedOfferToken) .build() ); BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList(productDetailsParamsList) .build(); // Launch the billing flow BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
เมธอด launchBillingFlow()
จะแสดงผลโค้ดตอบกลับรายการใดรายการหนึ่งที่ระบุไว้ใน
BillingClient.BillingResponseCode
อย่าลืมตรวจสอบผลลัพธ์นี้เพื่อ
ยืนยันว่าไม่มีข้อผิดพลาดในการเปิดตัวขั้นตอนการซื้อ BillingResponseCode
ของ OK
แสดงว่าเปิดตัวเรียบร้อยแล้ว
เมื่อเรียกใช้ launchBillingFlow()
สำเร็จ ระบบจะแสดงหน้าจอการซื้อใน Google
Play รูปที่ 1 แสดงหน้าจอการซื้อสำหรับการสมัครใช้บริการ

Google Play จะเรียกใช้ onPurchasesUpdated()
เพื่อส่งผลลัพธ์ของการดำเนินการซื้อ
ไปยัง Listener ที่ใช้ PurchasesUpdatedListener
อินเทอร์เฟซ โดยระบุ Listener โดยใช้เมธอด setListener()
เมื่อคุณ
เริ่มต้นไคลเอ็นต์
คุณต้องใช้ onPurchasesUpdated()
เพื่อจัดการโค้ดตอบกลับที่อาจเกิดขึ้น
ตัวอย่างต่อไปนี้แสดงวิธีลบล้าง onPurchasesUpdated()
Kotlin
override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List<Purchase>?) { if (billingResult.responseCode == BillingResponseCode.OK && purchases != null) { for (purchase in purchases) { // Process the purchase as described in the next section. } } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) { // Handle an error caused by a user canceling the purchase flow. } else { // Handle any other error codes. } }
Java
@Override void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) { if (billingResult.getResponseCode() == BillingResponseCode.OK && purchases != null) { for (Purchase purchase : purchases) { // Process the purchase as described in the next section. } } else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) { // Handle an error caused by a user canceling the purchase flow. } else { // Handle any other error codes. } }
การซื้อที่สำเร็จจะสร้างหน้าจอการซื้อใน Google Play ที่สำเร็จซึ่งคล้ายกับ รูปที่ 2

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

คุณต้องปรึกษามาตรา 6 (1) (ea) CRD ของคำสั่งว่าด้วยสิทธิของผู้บริโภค 2011/83/EU เพื่อตรวจสอบว่าราคาที่คุณเสนอให้นั้นมีการปรับเปลี่ยนตามโปรไฟล์ของผู้ใช้หรือไม่
setIsOfferPersonalized()
รับอินพุตบูลีน เมื่อ true
UI ของ Play
จะมีการเปิดเผยข้อมูล เมื่อ false
UI จะละเว้นการเปิดเผยข้อมูล ค่าเริ่มต้นคือ false
ดูข้อมูลเพิ่มเติมได้ที่ศูนย์ช่วยเหลือสำหรับผู้บริโภค
แนบตัวระบุผู้ใช้
เมื่อเปิดตัวขั้นตอนการซื้อ แอปจะแนบตัวระบุผู้ใช้ที่คุณมีสำหรับผู้ใช้ที่ทำการซื้อได้โดยใช้ obfuscatedAccountId หรือ obfuscatedProfileId ตัวอย่างตัวระบุอาจเป็นเวอร์ชันที่ผ่านการปกปิด ของการเข้าสู่ระบบของผู้ใช้ในระบบของคุณ การตั้งค่าพารามิเตอร์เหล่านี้จะช่วยให้ Google ตรวจหาการประพฤติมิชอบได้ นอกจากนี้ ยังช่วยให้มั่นใจได้ว่าระบบจะ ระบุแหล่งที่มาของการซื้อไปยังผู้ใช้ที่เหมาะสมตามที่อธิบายไว้ใน การให้สิทธิ์แก่ผู้ใช้
ตรวจหาและประมวลผลการซื้อ
การตรวจหาและการประมวลผลการซื้อที่อธิบายไว้ในส่วนนี้ ใช้ได้กับการซื้อทุกประเภท รวมถึงการซื้อนอกแอป เช่น การแลกรับโปรโมชัน
แอปจะตรวจหาการซื้อใหม่และการซื้อที่รอดำเนินการที่เสร็จสมบูรณ์ด้วยวิธีใดวิธีหนึ่งต่อไปนี้
- เมื่อมีการเรียกใช้
onPurchasesUpdated
อันเป็นผลมาจากการเรียกใช้แอปของคุณlaunchBillingFlow
(ตามที่อธิบายไว้ในส่วนก่อนหน้า) หรือหากแอปของคุณ ทํางานโดยมีการเชื่อมต่อ Billing Library ที่ใช้งานอยู่เมื่อมีการซื้อ ที่ทําภายนอกแอปของคุณหรือการซื้อที่รอดำเนินการเสร็จสมบูรณ์ เช่น สมาชิกในครอบครัวอนุมัติการซื้อที่รอดำเนินการในอุปกรณ์อื่น - เมื่อแอปเรียกใช้ queryPurchasesAsync เพื่อค้นหาการซื้อของผู้ใช้
สำหรับ #1 ระบบจะเรียกใช้ onPurchasesUpdated
โดยอัตโนมัติสำหรับการซื้อใหม่หรือการซื้อที่เสร็จสมบูรณ์
ตราบใดที่แอปของคุณทำงานอยู่และมีการเชื่อมต่อไลบรารีการเรียกเก็บเงินของ Google Play ที่ใช้งานอยู่
หากแอปพลิเคชันไม่ได้ทำงานหรือแอปไม่มีการเชื่อมต่อไลบรารีการเรียกเก็บเงินของ Google Play ที่ใช้งานอยู่ ระบบจะไม่เรียกใช้ onPurchasesUpdated
โปรดทราบว่าเราขอแนะนำให้แอปพยายามรักษาการเชื่อมต่อที่ใช้งานอยู่
ตราบใดที่แอปอยู่เบื้องหน้าเพื่อให้แอปได้รับการอัปเดตการซื้อ
อย่างทันท่วงที
สำหรับข้อ 2 คุณต้องเรียกใช้ BillingClient.queryPurchasesAsync() เพื่อให้แน่ใจว่าแอป ประมวลผลการซื้อทั้งหมด เราขอแนะนำให้คุณทำเช่นนี้เมื่อแอป สร้างการเชื่อมต่อกับ Google Play Billing Library ได้สำเร็จ (ซึ่งแนะนำให้ทำเมื่อแอปเปิดตัวหรือเข้าสู่เบื้องหน้าตามที่อธิบายไว้ในเริ่มต้น BillingClient ซึ่งทำได้โดยการเรียกใช้ queryPurchasesAsync เมื่อได้รับผลลัพธ์ที่สำเร็จไปยัง onServiceConnected การปฏิบัติตามคำแนะนำนี้เป็นสิ่งสำคัญในการจัดการ เหตุการณ์และสถานการณ์ต่างๆ เช่น
- ปัญหาเกี่ยวกับเครือข่ายระหว่างการซื้อ: ผู้ใช้สามารถซื้อได้สำเร็จ
และได้รับการยืนยันจาก Google แต่
อุปกรณ์จะสูญเสียการเชื่อมต่อเครือข่ายก่อนที่อุปกรณ์และแอปของคุณจะได้รับการแจ้งเตือน
เกี่ยวกับการซื้อผ่าน
PurchasesUpdatedListener
- อุปกรณ์หลายเครื่อง: ผู้ใช้อาจซื้อสินค้าในอุปกรณ์เครื่องหนึ่งและคาดหวังว่าจะเห็นสินค้าดังกล่าวเมื่อเปลี่ยนไปใช้อุปกรณ์เครื่องอื่น
- การจัดการการซื้อที่ทำนอกแอป: การซื้อบางอย่าง เช่น การแลกรับโปรโมชัน สามารถทำได้นอกแอป
- การจัดการการเปลี่ยนสถานะการซื้อ: ผู้ใช้อาจชำระเงินสำหรับการซื้อที่ รอดำเนินการจนเสร็จสมบูรณ์ในขณะที่แอปพลิเคชันของคุณไม่ได้ทำงาน และคาดหวังที่จะได้รับการ ยืนยันว่าได้ทำการซื้อเสร็จสมบูรณ์แล้วเมื่อเปิดแอป
เมื่อแอปตรวจพบการซื้อใหม่หรือการซื้อที่เสร็จสมบูรณ์แล้ว แอปควรดำเนินการดังนี้
- ยืนยันการซื้อ
- มอบเนื้อหาให้แก่ผู้ใช้สำหรับการซื้อที่เสร็จสมบูรณ์
- แจ้งให้ผู้ใช้ทราบ
- แจ้งให้ Google ทราบว่าแอปของคุณประมวลผลการซื้อที่เสร็จสมบูรณ์แล้ว
เราจะอธิบายขั้นตอนเหล่านี้โดยละเอียดในส่วนต่อไปนี้ และตามด้วยส่วนสรุปขั้นตอนทั้งหมด
ยืนยันการซื้อ
แอปควรตรวจสอบความถูกต้องของการซื้อก่อนให้สิทธิประโยชน์แก่ผู้ใช้เสมอ โดยทำตามหลักเกณฑ์ที่อธิบายไว้ในหัวข้อยืนยันการซื้อก่อนให้สิทธิ์ หลังจากยืนยันการซื้อแล้วเท่านั้น แอปของคุณจึงควรดำเนินการกับการซื้อต่อและให้สิทธิ์แก่ผู้ใช้ ซึ่งจะกล่าวถึงในส่วนถัดไป
ให้สิทธิ์แก่ผู้ใช้
เมื่อแอปยืนยันการซื้อแล้ว แอปจะให้สิทธิ์แก่ผู้ใช้ต่อไปและแจ้งให้ผู้ใช้ทราบได้
ก่อนให้สิทธิ์ โปรดตรวจสอบว่าแอปของคุณกำลังตรวจสอบว่าสถานะการซื้อเป็น PURCHASED
หากการซื้อมีสถานะเป็น "รอดำเนินการ" แอปของคุณควรแจ้งให้ผู้ใช้ทราบว่ายังคงต้องดำเนินการให้เสร็จสมบูรณ์เพื่อทำการซื้อให้เสร็จสมบูรณ์ก่อนที่จะได้รับสิทธิ์
ให้สิทธิ์เฉพาะเมื่อการซื้อเปลี่ยนจากสถานะ "รอดำเนินการ" เป็น "สำเร็จ"
ดูข้อมูลเพิ่มเติมได้ที่การจัดการธุรกรรมที่รอดำเนินการ
หากคุณแนบตัวระบุผู้ใช้กับการซื้อตามที่อธิบายไว้ในการแนบตัวระบุผู้ใช้ คุณจะเรียกข้อมูลและใช้ตัวระบุเหล่านั้นเพื่อระบุแหล่งที่มาของผู้ใช้ที่ถูกต้องในระบบได้ เทคนิคนี้มีประโยชน์เมื่อต้องกระทบยอดการซื้อ ในกรณีที่แอปอาจสูญเสียบริบทเกี่ยวกับผู้ใช้ที่ทำการซื้อ โปรดทราบว่า การซื้อที่ทำนอกแอปจะไม่มีการตั้งค่าตัวระบุเหล่านี้ ในกรณีนี้ แอปของคุณจะให้สิทธิ์แก่ผู้ใช้ที่เข้าสู่ระบบ หรือแจ้งให้ ผู้ใช้เลือกบัญชีที่ต้องการก็ได้
สำหรับการสั่งจองล่วงหน้า การซื้อจะอยู่ในสถานะรอดำเนินการก่อนถึงเวลาเผยแพร่ ระบบจะดำเนินการซื้อที่สั่งจองล่วงหน้าให้เสร็จสมบูรณ์เมื่อถึงเวลาที่เผยแพร่และเปลี่ยน สถานะเป็น "ซื้อแล้ว" โดยที่คุณไม่ต้องดำเนินการใดๆ เพิ่มเติม
แจ้งให้ผู้ใช้ทราบ
หลังจากให้สิทธิ์แก่ผู้ใช้แล้ว แอปของคุณควรแสดงการแจ้งเตือนเพื่อ รับทราบการซื้อที่สำเร็จ การแจ้งเตือนนี้จะช่วยให้ผู้ใช้ไม่สับสนว่าการซื้อเสร็จสมบูรณ์หรือไม่ ซึ่งอาจส่งผลให้ผู้ใช้หยุดใช้แอปของคุณ ติดต่อทีมสนับสนุนผู้ใช้ หรือร้องเรียนเกี่ยวกับเรื่องนี้บนโซเชียลมีเดีย โปรดทราบว่าแอปอาจตรวจพบการอัปเดตการซื้อได้ทุกเมื่อในวงจรแอปพลิเคชัน เช่น ผู้ปกครอง อนุมัติการซื้อที่รอดำเนินการในอุปกรณ์อื่น ในกรณีนี้แอปของคุณอาจต้องการ เลื่อนการแจ้งเตือนผู้ใช้ไปยังเวลาที่เหมาะสม ตัวอย่างบางส่วนที่ควรใช้การหน่วงเวลา มีดังนี้
- ในระหว่างช่วงการดำเนินการของเกมหรือฉากคัตซีน การแสดงข้อความอาจ รบกวนผู้ใช้ ในกรณีนี้ คุณต้องแจ้งให้ผู้ใช้ทราบหลังจากที่ ส่วนการดำเนินการสิ้นสุดลง
- ในระหว่างบทแนะนำเบื้องต้นและส่วนการตั้งค่าผู้ใช้ของเกม เช่น ผู้ใช้อาจทำการซื้อนอกแอปก่อนที่จะติดตั้ง เราขอแนะนำให้คุณแจ้งให้ผู้ใช้ใหม่ทราบเกี่ยวกับรางวัลทันทีหลังจากที่ผู้ใช้เปิดเกมหรือในระหว่างการตั้งค่าผู้ใช้ครั้งแรก หากแอปกำหนดให้ผู้ใช้สร้างบัญชีหรือเข้าสู่ระบบก่อนที่จะให้สิทธิ์แก่ผู้ใช้ เราขอแนะนำให้แจ้งให้ผู้ใช้ทราบถึงขั้นตอนที่ต้องดำเนินการเพื่อรับสิทธิ์จากการซื้อ ซึ่งเป็นสิ่งสำคัญเนื่องจากระบบจะคืนเงินสำหรับการซื้อหลังจากผ่านไป 3 วัน หากแอปของคุณยังไม่ได้ประมวลผลการซื้อ
เมื่อแจ้งเตือนผู้ใช้เกี่ยวกับการซื้อ Google Play ขอแนะนําให้ใช้กลไกต่อไปนี้
- แสดงกล่องโต้ตอบในแอป
- ส่งข้อความไปยังกล่องข้อความในแอป และระบุอย่างชัดเจนว่ามีข้อความใหม่ในกล่องข้อความในแอป
- ใช้ข้อความการแจ้งเตือนของระบบปฏิบัติการ
การแจ้งเตือนควรแจ้งให้ผู้ใช้ทราบถึงสิทธิประโยชน์ที่ได้รับ เช่น "คุณซื้อเหรียญทอง 100 เหรียญแล้ว" นอกจากนี้ หากการซื้อเป็นผลมาจากสิทธิประโยชน์ของโปรแกรม เช่น Play Pass แอปของคุณจะสื่อสารเรื่องนี้กับผู้ใช้ เช่น "ได้รับสินค้าแล้ว คุณเพิ่งได้รับอัญมณี 100 เม็ดจาก Play Pass ดำเนินการต่อ" แต่ละโปรแกรมอาจมีคำแนะนำเกี่ยวกับข้อความที่แนะนำให้แสดงต่อผู้ใช้เพื่อสื่อสารถึงสิทธิประโยชน์
แจ้งให้ Google ทราบว่ามีการประมวลผลการซื้อแล้ว
หลังจากที่แอปให้สิทธิ์แก่ผู้ใช้และแจ้งให้ผู้ใช้ทราบเกี่ยวกับธุรกรรมที่สำเร็จแล้ว แอปของคุณต้องแจ้งให้ Google ทราบว่าการซื้อได้รับการประมวลผลเรียบร้อยแล้ว โดยการตอบรับการซื้อและต้องดำเนินการภายใน 3 วันเพื่อไม่ให้ระบบคืนเงินโดยอัตโนมัติและเพิกถอนสิทธิ์ กระบวนการรับทราบการซื้อประเภทต่างๆ อธิบายไว้ในส่วนต่อไปนี้
ผลิตภัณฑ์สิ้นเปลือง
สำหรับไอเทมที่ใช้แล้วหมด หากแอปมีแบ็กเอนด์ที่ปลอดภัย เราขอแนะนำให้คุณใช้
Purchases.products:consume
เพื่อใช้ไอเทมที่ซื้อได้อย่างน่าเชื่อถือ ตรวจสอบว่าได้ใช้การซื้อไปแล้วหรือยังโดยดู consumptionState
จาก
ผลลัพธ์ของการเรียก Purchases.products:get
หากแอปของคุณเป็นไคลเอ็นต์เท่านั้น
โดยไม่มีแบ็กเอนด์ ให้ใช้ consumeAsync()
จาก
Google Play Billing Library ทั้ง 2 วิธีเป็นไปตามข้อกำหนดในการรับทราบ
และระบุว่าแอปของคุณได้ให้สิทธิ์แก่ผู้ใช้แล้ว
นอกจากนี้ วิธีการเหล่านี้ยังช่วยให้แอปของคุณทำให้ผลิตภัณฑ์แบบเรียกเก็บเงินครั้งเดียวที่สอดคล้องกับโทเค็นการซื้อที่ป้อนพร้อมสำหรับการซื้อซ้ำ เมื่อใช้ consumeAsync()
คุณ
ต้องส่งออบเจ็กต์ที่ใช้ConsumeResponseListener
อินเทอร์เฟซด้วย ออบเจ็กต์นี้จัดการผลลัพธ์ของการดำเนินการการใช้งาน คุณสามารถ
แทนที่เมธอด onConsumeResponse()
ซึ่ง
Google Play Billing Library จะเรียกใช้เมื่อการดำเนินการเสร็จสมบูรณ์
ตัวอย่างต่อไปนี้แสดงการใช้ผลิตภัณฑ์ด้วย Google Play Billing Library โดยใช้โทเค็นการซื้อที่เกี่ยวข้อง
Kotlin
val consumeParams = ConsumeParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build() val consumeResult = withContext(Dispatchers.IO) { client.consumePurchase(consumeParams) }
Java
ConsumeParams consumeParams = ConsumeParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); ConsumeResponseListener listener = new ConsumeResponseListener() { @Override public void onConsumeResponse(BillingResult billingResult, String purchaseToken) { if (billingResult.getResponseCode() == BillingResponseCode.OK) { // Handle the success of the consume operation. } } }; billingClient.consumeAsync(consumeParams, listener);
ผลิตภัณฑ์ที่ไม่ใช่สินค้าอุปโภคบริโภค
หากแอปมีแบ็กเอนด์ที่ปลอดภัย เราขอแนะนำให้ใช้ Purchases.products:acknowledge
เพื่อตอบรับการซื้อแบบใช้ครั้งเดียวได้อย่างน่าเชื่อถือ
ตรวจสอบว่าคุณยังไม่ได้รับทราบการซื้อดังกล่าวมาก่อนโดย
ดูacknowledgementState
จากผลลัพธ์ของการเรียกใช้
Purchases.products:get
หากแอปเป็นไคลเอ็นต์เท่านั้น ให้ใช้ BillingClient.acknowledgePurchase()
จาก
Google Play Billing Library ในแอป ก่อนรับทราบการ
ซื้อ แอปควรตรวจสอบว่ามีการรับทราบแล้วหรือไม่โดยใช้วิธี isAcknowledged()
ใน Google Play Billing Library
ตัวอย่างต่อไปนี้แสดงวิธีรับทราบการซื้อโดยใช้ Google Play Billing Library
Kotlin
val client: BillingClient = ... val acknowledgePurchaseResponseListener: AcknowledgePurchaseResponseListener = ... val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.purchaseToken) val ackPurchaseResult = withContext(Dispatchers.IO) { client.acknowledgePurchase(acknowledgePurchaseParams.build()) }
Java
BillingClient client = ... AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ... AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);
การติดตาม
ระบบจะจัดการการสมัครใช้บริการในลักษณะเดียวกับไอเทมที่ซื้อครั้งเดียว หากเป็นไปได้ ให้ใช้
Purchases.subscriptions.acknowledge
จาก
Google Play Developer API เพื่อตอบรับการซื้อจากแบ็กเอนด์ที่ปลอดภัย
ได้อย่างน่าเชื่อถือ ยืนยันว่าก่อนหน้านี้ยังไม่มีการรับทราบการซื้อโดย
ตรวจสอบ acknowledgementState
ในแหล่งข้อมูลการซื้อจาก
Purchases.subscriptions:get
หรือคุณจะรับทราบการสมัครใช้บริการโดยใช้ BillingClient.acknowledgePurchase()
จาก
Google Play Billing Library หลังจากตรวจสอบ isAcknowledged()
แล้วก็ได้ การซื้อการสมัครใช้บริการครั้งแรกทั้งหมดต้องได้รับการรับทราบ การต่ออายุการสมัครใช้บริการ
ไม่จำเป็นต้องรับทราบ ดูข้อมูลเพิ่มเติมเกี่ยวกับเวลาที่ต้องรับทราบการสมัครใช้บริการได้ที่หัวข้อขายการสมัครใช้บริการ
สรุป
ข้อมูลโค้ดต่อไปนี้แสดงสรุปขั้นตอนเหล่านี้
Kotlin
fun handlePurchase(Purchase purchase) { // Purchase retrieved from BillingClient#queryPurchasesAsync or your // onPurchasesUpdated. Purchase purchase = ...; // Step 1: Send the purchase to your secure backend to verify the purchase // following // https://developer.android.com/google/play/billing/security#verify . // Step 2: Update your entitlement storage with the purchase. If purchase is // in PENDING state then ensure the entitlement is marked as pending and the // user does not receive benefits yet. It is recommended that this step is // done on your secure backend and can combine in the API call to your // backend in step 1. // Step 3: Notify the user using appropriate messaging (delaying // notification if needed as discussed above). // Step 4: Notify Google the purchase was processed using the steps // discussed in the processing purchases section. }
Java
void handlePurchase(Purchase purchase) { // Purchase retrieved from BillingClient#queryPurchasesAsync or your // onPurchasesUpdated. Purchase purchase = ...; // Step 1: Send the purchase to your secure backend to verify the purchase // following // https://developer.android.com/google/play/billing/security#verify // Step 2: Update your entitlement storage with the purchase. If purchase is // in PENDING state then ensure the entitlement is marked as pending and the // user does not receive benefits yet. It is recommended that this step is // done on your secure backend and can combine in the API call to your // backend in step 1. // Step 3: Notify the user using appropriate messaging (delaying // notification if needed as discussed above). // Step 4: Notify Google the purchase was processed using the steps // discussed in the processing purchases section. }
หากต้องการยืนยันว่าแอปได้ติดตั้งใช้งานขั้นตอนเหล่านี้อย่างถูกต้องหรือไม่ คุณสามารถทำตามคู่มือการทดสอบ
จัดการธุรกรรมที่รอดำเนินการ
Google Play รองรับธุรกรรมที่รอดำเนินการหรือธุรกรรมที่ต้องมีขั้นตอนเพิ่มเติมอย่างน้อย 1 ขั้นตอนระหว่างที่ผู้ใช้เริ่มการซื้อกับเวลาที่ระบบประมวลผลวิธีการชำระเงินสำหรับการซื้อ แอปของคุณไม่ควรมอบสิทธิ์ ให้กับการซื้อประเภทนี้จนกว่า Google จะแจ้งให้คุณทราบว่าระบบเรียกเก็บเงินจากวิธีการชำระเงินของผู้ใช้ได้สำเร็จแล้ว
เช่น ผู้ใช้สามารถเริ่มทำธุรกรรมได้โดยเลือกร้านค้าจริง ซึ่งจะชำระเงินด้วยเงินสดในภายหลัง ผู้ใช้จะได้รับรหัสผ่านทั้งการแจ้งเตือนและอีเมล เมื่อผู้ใช้มาถึงร้านค้าจริง ก็สามารถ แลกรหัสกับแคชเชียร์และชำระเงินด้วยเงินสดได้ จากนั้น Google จะแจ้งให้ทั้งคุณและผู้ใช้ทราบว่าได้รับชำระเงินแล้ว จากนั้นแอปจะให้สิทธิ์ แก่ผู้ใช้ได้
เรียกใช้ enablePendingPurchases()
เป็นส่วนหนึ่งของการเริ่มต้น BillingClient
เพื่อเปิดใช้ธุรกรรมที่รอดำเนินการสำหรับแอปของคุณ แอปต้องเปิดใช้และรองรับธุรกรรมที่รอดำเนินการสำหรับไอเทมแบบเรียกเก็บเงินครั้งเดียว ก่อนเพิ่มการรองรับ โปรดทำความเข้าใจวงจรการซื้อสำหรับธุรกรรมที่รอดำเนินการ
เมื่อแอปได้รับการซื้อใหม่ ไม่ว่าจะผ่านPurchasesUpdatedListener
หรือเป็นผลจากการเรียกใช้ queryPurchasesAsync
ให้ใช้เมธอด getPurchaseState()
เพื่อ
พิจารณาว่าสถานะการซื้อเป็น PURCHASED
หรือ PENDING
คุณควรให้สิทธิ์เฉพาะเมื่อสถานะเป็น PURCHASED
หากแอปของคุณทำงานอยู่และมีการเชื่อมต่อ Play Billing Library ที่ใช้งานอยู่
เมื่อผู้ใช้ทำการซื้อเสร็จสมบูรณ์ ระบบจะเรียกใช้ PurchasesUpdatedListener
อีกครั้ง และตอนนี้ PurchaseState
จะเป็น PURCHASED
ตอนนี้แอปของคุณสามารถประมวลผลการซื้อโดยใช้วิธีมาตรฐานสำหรับการตรวจหาและการประมวลผลการซื้อ แอปของคุณควรเรียกใช้ queryPurchasesAsync()
ใน
เมธอด onResume()
ของแอปเพื่อจัดการการซื้อที่เปลี่ยนไปเป็นสถานะ
PURCHASED
ขณะที่แอปไม่ได้ทำงาน
เมื่อการซื้อเปลี่ยนจากPENDING
เป็นPURCHASED
ไคลเอ็นต์ real_time_developer_notifications จะได้รับการแจ้งเตือน ONE_TIME_PRODUCT_PURCHASED
หรือ SUBSCRIPTION_PURCHASED
หากมีการยกเลิกการซื้อ คุณจะได้รับการแจ้งเตือน ONE_TIME_PRODUCT_CANCELED
หรือ SUBSCRIPTION_PENDING_PURCHASE_CANCELED
ปัญหานี้อาจเกิดขึ้นได้หากลูกค้าชำระเงินไม่เสร็จภายในกรอบเวลาที่กำหนด โปรดทราบว่าคุณใช้ Google Play Developer API เพื่อตรวจสอบสถานะปัจจุบันของการซื้อได้ทุกเมื่อ
จัดการการซื้อหลายรายการ
Google Play อนุญาตให้ลูกค้าซื้อผลิตภัณฑ์แบบเรียกเก็บเงินครั้งเดียวเดียวกันได้มากกว่า 1 รายการในธุรกรรมเดียวโดยการระบุจำนวนจากรถเข็นการซื้อ ซึ่งรองรับใน Google Play Billing Library เวอร์ชัน 4.0 ขึ้นไป ระบบคาดหวังให้แอปของคุณจัดการการซื้อแบบหลายจำนวนและให้สิทธิ์ตามจำนวนการซื้อที่ระบุ
หากต้องการรองรับการซื้อหลายรายการพร้อมกัน ตรรกะการจัดสรรของแอปจะต้องตรวจสอบ
จำนวนสินค้า คุณเข้าถึงquantity
ฟิลด์ได้จาก API ใด API หนึ่งต่อไปนี้
getQuantity()
จาก Google Play Billing LibraryPurchases.products.quantity
จาก Google Play Developer API
หลังจากเพิ่มตรรกะเพื่อจัดการการซื้อหลายรายการแล้ว คุณจะต้อง เปิดใช้ฟีเจอร์หลายรายการสำหรับผลิตภัณฑ์ที่เกี่ยวข้องในหน้าการจัดการผลิตภัณฑ์ แบบเรียกเก็บเงินครั้งเดียวใน Google Play Developer Console
ค้นหาการกำหนดค่าการเรียกเก็บเงินของผู้ใช้
getBillingConfigAsync()
ระบุประเทศที่ผู้ใช้ใช้สำหรับ Google
Play
คุณสามารถค้นหาการกำหนดค่าการเรียกเก็บเงินของผู้ใช้ได้หลังจากสร้าง
BillingClient
ข้อมูลโค้ดต่อไปนี้อธิบายวิธีโทรหา getBillingConfigAsync()
จัดการการตอบกลับโดยการใช้
BillingConfigResponseListener
ผู้ฟังรายนี้จะได้รับการอัปเดตสำหรับการค้นหาการกำหนดค่าการเรียกเก็บเงินทั้งหมดที่เริ่มต้นจากแอปของคุณ
หาก BillingResult
ที่ส่งคืนไม่มีข้อผิดพลาด คุณจะตรวจสอบฟิลด์ countryCode
ในออบเจ็กต์ BillingConfig
เพื่อรับประเทศ Play ของผู้ใช้ได้
Kotlin
// Use the default GetBillingConfigParams. val getBillingConfigParams = GetBillingConfigParams.newBuilder().build() billingClient.getBillingConfigAsync(getBillingConfigParams, object : BillingConfigResponseListener { override fun onBillingConfigResponse( billingResult: BillingResult, billingConfig: BillingConfig? ) { if (billingResult.responseCode == BillingResponseCode.OK && billingConfig != null) { val countryCode = billingConfig.countryCode ... } else { // TODO: Handle errors } } })
Java
// Use the default GetBillingConfigParams. GetBillingConfigParams getBillingConfigParams = GetBillingConfigParams.newBuilder().build(); billingClient.getBillingConfigAsync(getBillingConfigParams, new BillingConfigResponseListener() { public void onBillingConfigResponse( BillingResult billingResult, BillingConfig billingConfig) { if (billingResult.getResponseCode() == BillingResponseCode.OK && billingConfig != null) { String countryCode = billingConfig.getCountryCode(); ... } else { // TODO: Handle errors } } });
การช่วยเตือนการทิ้งรถเข็นในหน้าแรกของ Google Play Games (เปิดใช้โดยค่าเริ่มต้น)
สำหรับนักพัฒนาเกมที่สร้างรายได้ผ่านผลิตภัณฑ์แบบครั้งเดียว วิธีหนึ่งในการขายหน่วยเก็บสินค้า (SKU) ที่ใช้งานอยู่ใน Google Play Console นอกแอปของคุณคือฟีเจอร์การช่วยเตือนการละทิ้งรถเข็นกลางคัน ซึ่งจะกระตุ้นให้ผู้ใช้ดำเนินการซื้อที่หยุดกลางคันก่อนหน้านี้ให้เสร็จสมบูรณ์ขณะเรียกดู Google Play Store การซื้อเหล่านี้เกิดขึ้นภายนอกแอปของคุณจากหน้าแรกของ Google Play Games ใน Google Play Store
ระบบจะเปิดใช้ฟีเจอร์นี้โดยค่าเริ่มต้นเพื่อช่วยให้ผู้ใช้กลับมาทำงานต่อจากที่ค้างไว้ได้ และช่วยให้นักพัฒนาแอปเพิ่มยอดขายได้สูงสุด อย่างไรก็ตาม คุณสามารถเลือกไม่ใช้ฟีเจอร์นี้สำหรับแอปได้โดยส่งแบบฟอร์มการเลือกไม่ใช้ฟีเจอร์การช่วยเตือนการละทิ้งรถเข็นกลางคัน ดูแนวทางปฏิบัติแนะนำในการจัดการ SKU ภายใน Google Play Console ได้ที่สร้างไอเทมที่ซื้อในแอป
รูปภาพต่อไปนี้แสดงการช่วยเตือนให้กลับไปชำระสินค้าในรถเข็นที่ปรากฏใน Google Play Store

