ผสานรวม Google Play Billing Library ไว้ในแอปของคุณ

หัวข้อนี้จะอธิบายวิธีผสานรวม Google Play Billing Library เข้ากับแอปเพื่อเริ่มขายผลิตภัณฑ์

วงจรการซื้อ

ขั้นตอนการซื้อทั่วไปสำหรับการซื้อแบบครั้งเดียวหรือการสมัครใช้บริการมีดังนี้

  1. แสดงสิ่งที่ผู้ใช้ซื้อได้
  2. เปิดใช้งานขั้นตอนการซื้อเพื่อให้ผู้ใช้ยอมรับการซื้อ
  3. ยืนยันการซื้อในเซิร์ฟเวอร์
  4. มอบเนื้อหาให้ผู้ใช้
  5. ยอมรับการนำส่งเนื้อหา สำหรับผลิตภัณฑ์ที่ใช้แล้วหมดไป ให้ใช้การซื้อเพื่อให้ผู้ใช้ซื้อไอเทมนั้นอีกครั้งได้

การสมัครใช้บริการจะต่ออายุโดยอัตโนมัติจนกว่าจะยกเลิก การสมัครใช้บริการอาจมีสถานะต่อไปนี้

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

เริ่มต้นการเชื่อมต่อกับ Google Play

ขั้นตอนแรกในการผสานรวมกับระบบการเรียกเก็บเงินของ Google Play คือการเพิ่ม Google Play Billing Library ลงในแอปและเริ่มต้นการเชื่อมต่อ

เพิ่มข้อกำหนดของไลบรารี Google Play Billing

เพิ่มการพึ่งพา Google Play Billing Library ลงในbuild.gradleไฟล์ ของแอปดังที่แสดง

Groovy

dependencies {
    def billing_version = "7.0.0"

    implementation "com.android.billingclient:billing:$billing_version"
}

Kotlin

dependencies {
    val billing_version = "7.0.0"

    implementation("com.android.billingclient:billing:$billing_version")
}

หากคุณใช้ Kotlin โมดูล KTX ของ Google Play Billing Library จะมีส่วนขยาย Kotlin และการสนับสนุน coroutines ซึ่งช่วยให้คุณเขียน Kotlin ได้อย่างเป็นธรรมชาติเมื่อใช้ Google Play Billing Library หากต้องการรวมส่วนขยายเหล่านี้ไว้ในโปรเจ็กต์ ให้เพิ่มการพึ่งพาต่อไปนี้ลงในไฟล์ build.gradle ของแอปดังที่แสดง

Groovy

dependencies {
    def billing_version = "7.0.0"

    implementation "com.android.billingclient:billing-ktx:$billing_version"
}

Kotlin

dependencies {
    val billing_version = "7.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.
    }
});

แสดงผลิตภัณฑ์ที่พร้อมจำหน่าย

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

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

หากต้องการค้นหารายละเอียดผลิตภัณฑ์ในแอป ให้โทรไปที่ queryProductDetailsAsync

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

Kotlin

val queryProductDetailsParams =
    QueryProductDetailsParams.newBuilder()
        .setProductList(
            ImmutableList.of(
                Product.newBuilder()
                    .setProductId("product_id_example")
                    .setProductType(ProductType.SUBS)
                    .build()))
        .build()

billingClient.queryProductDetailsAsync(queryProductDetailsParams) {
    billingResult,
    productDetailsList ->
      // check billingResult
      // process returned productDetailsList
}

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,
                List<ProductDetails> productDetailsList) {
            // check billingResult
            // process returned productDetailsList
        }
    }
)

เมื่อค้นหารายละเอียดผลิตภัณฑ์ ให้ส่งอินสแตนซ์ของ 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 5 เพื่อให้มั่นใจว่าจะได้รับการสนับสนุนที่เหมาะสมสำหรับสถานการณ์นี้

ประมวลผลผลลัพธ์

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

ก่อนเสนอขายสินค้า ให้ตรวจสอบว่าผู้ใช้ไม่ได้เป็นเจ้าของสินค้านั้นอยู่แล้ว หากผู้ใช้มีไอเทมที่บริโภคได้ซึ่งยังอยู่ในคลังไอเทม ผู้ใช้จะต้องบริโภคไอเทมนั้นก่อนจึงจะซื้อไอเทมดังกล่าวได้อีก

ก่อนที่จะเสนอการสมัครใช้บริการ ให้ตรวจสอบว่าผู้ใช้ไม่ได้สมัครใช้บริการแล้ว และโปรดทราบว่า

  • queryProductDetailsAsync() จะแสดงรายละเอียดผลิตภัณฑ์ที่ต้องสมัครใช้บริการและข้อเสนอสูงสุด 50 รายการต่อการสมัครใช้บริการ 1 รายการ
  • 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)
        // For One-time products, "setOfferToken" method shouldn't be called.
        // For subscriptions, to get an offer token, 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)
            // For one-time products, "setOfferToken" method shouldn't be called.
            // For subscriptions, to get an offer token, 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 แสดงการสมัครใช้บริการที่พร้อมให้ซื้อ
รูปที่ 1 หน้าจอการซื้อของ Google Play จะแสดงการสมัครใช้บริการที่พร้อมให้ซื้อ

Google Play จะเรียก onPurchasesUpdated() เพื่อส่งผลลัพธ์ของการดำเนินการซื้อให้กับ Listener ที่ใช้อินเทอร์เฟซ PurchasesUpdatedListener ระบุตัวรับฟังโดยใช้เมธอด 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
รูปที่ 2 หน้าจอการซื้อสำเร็จของ Google Play

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

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

ระบุราคาสำหรับคุณโดยเฉพาะ

หากแอปของคุณเผยแพร่แก่ผู้ใช้ในสหภาพยุโรปได้ ให้ใช้เมธอด setIsOfferPersonalized() เมื่อเรียกใช้ launchBillingFlow เพื่อเปิดเผยให้ผู้ใช้ทราบว่าราคาของสินค้าได้รับการปรับเปลี่ยนในแบบของคุณโดยใช้การตัดสินใจอัตโนมัติ

หน้าจอการซื้อใน Google Play ที่ระบุว่ามีการปรับราคาสำหรับผู้ใช้
รูปที่ 3 หน้าจอการซื้อใน Google Play ที่ระบุว่ามีการปรับแต่งราคาสำหรับผู้ใช้

คุณต้องปรึกษา Art 6 (1) (ea) CRD ของคำสั่งว่าด้วยสิทธิของผู้บริโภค 2011/83/EU เพื่อตรวจสอบว่าราคาที่คุณเสนอให้นั้นมีการปรับเปลี่ยนตามโปรไฟล์ของผู้ใช้หรือไม่

setIsOfferPersonalized() รับอินพุตบูลีน เมื่อเป็น true UI ของ Play จะแสดงการเปิดเผยข้อมูล เมื่อเป็น false ระบบ UI จะละเว้นการเปิดเผย ค่าเริ่มต้นคือ false

ดูข้อมูลเพิ่มเติมได้ที่ศูนย์ช่วยเหลือผู้บริโภค

แนบตัวระบุผู้ใช้

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

ตรวจหาและประมวลผลการซื้อ

การตรวจหาและการประมวลผลการซื้อที่อธิบายในส่วนนี้มีผลกับการซื้อทุกประเภท รวมถึงการซื้อนอกแอป เช่น การแลกรับโปรโมชัน

แอปจะตรวจหาการซื้อใหม่และการซื้อที่รอดำเนินการที่เสร็จสมบูรณ์ด้วยวิธีใดวิธีหนึ่งต่อไปนี้

  1. เมื่อมีการเรียกใช้ onPurchasesUpdated เนื่องจากการเรียกใช้ launchBillingFlow ของแอป (ตามที่ได้อธิบายไว้ในส่วนก่อนหน้า) หรือหากแอปของคุณทํางานโดยมีการเชื่อมต่อ Billing Library ที่ใช้งานอยู่เมื่อมีการซื้อนอกแอปหรือการซื้อที่รอดําเนินการเสร็จสมบูรณ์ เช่น สมาชิกในครอบครัวอนุมัติการซื้อที่รอดำเนินการในอุปกรณ์อื่น
  2. เมื่อแอปเรียก queryPurchasesAsync เพื่อค้นหาการซื้อของผู้ใช้

สำหรับ #1 ระบบจะเรียกใช้ onPurchasesUpdated โดยอัตโนมัติสำหรับการซื้อใหม่หรือการซื้อที่เสร็จสมบูรณ์ ตราบใดที่แอปของคุณทำงานอยู่และมีการเชื่อมต่อกับคลัง Google Play Billing ที่ใช้งานอยู่ หากแอปพลิเคชันไม่ทํางานหรือแอปไม่มีการเชื่อมต่อ Google Play Billing Library ที่ใช้งานอยู่ ระบบจะไม่เรียกใช้ 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 หลังจากที่ตรวจสอบ 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 เวอร์ชัน 4.0 ขึ้นไป แอปของคุณควรจัดการการซื้อหลายรายการและมอบสิทธิ์ตามจำนวนการซื้อที่ระบุ

ตรรกะการจัดสรรของแอปต้องตรวจสอบจำนวนสินค้าเพื่อรองรับการซื้อหลายรายการ คุณสามารถเข้าถึงฟิลด์ quantity จาก 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 (เปิดใช้โดยค่าเริ่มต้น)

สําหรับนักพัฒนาแอปเกมที่สร้างรายได้ผ่าน IAP วิธีหนึ่งในการขายหน่วยสินค้าคงคลัง (SKU) ที่ใช้งานอยู่ใน Google Play Console นอกแอปของคุณคือฟีเจอร์การช่วยเตือนการละทิ้งรถเข็นกลางคัน ซึ่งจะกระตุ้นให้ผู้ใช้ดำเนินการซื้อที่หยุดกลางคันก่อนหน้านี้ให้เสร็จสมบูรณ์ขณะเรียกดู Google Play Store การซื้อเหล่านี้เกิดขึ้นนอกแอปของคุณจากหน้าแรกของ Google Play Games ใน Google Play Store

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

รูปภาพต่อไปนี้แสดงการช่วยเตือนการหยุดกลางคันในรถเข็นที่ปรากฏใน Google Play Store

หน้าจอ Google Play Store แสดงข้อความแจ้งให้ซื้อสำหรับการซื้อที่ยกเลิกไปก่อนหน้านี้
รูปที่ 2 หน้าจอ Google Play Store จะแสดงข้อความแจ้งให้ซื้อสำหรับการซื้อที่ยกเลิกไปก่อนหน้านี้

หน้าจอ Google Play Store แสดงข้อความแจ้งให้ซื้อสำหรับการซื้อที่ยกเลิกไปก่อนหน้านี้
รูปที่ 3 หน้าจอ Google Play Store จะแสดงข้อความแจ้งให้ซื้อสำหรับการซื้อที่ยกเลิกไปก่อนหน้านี้