Mengintegrasikan Google Play Billing Library ke aplikasi Anda

Topik ini menjelaskan cara mengintegrasikan Library Layanan Penagihan Google Play ke aplikasi Anda untuk mulai menjual produk.

Umur pembelian

Berikut ini alur pembelian yang biasa untuk pembelian satu kali atau langganan.

  1. Menunjukkan kepada pengguna apa yang dapat mereka beli.
  2. Meluncurkan alur pembelian bagi pengguna untuk menerima pembelian.
  3. Memverifikasi pembelian di server Anda.
  4. Memberikan konten kepada pengguna.
  5. Mengonfirmasi pengiriman konten. Untuk produk habis pakai, pakai item yang telah dibeli agar pengguna dapat membeli item itu lagi.

Langganan diperpanjang secara otomatis hingga dibatalkan. Langganan dapat melalui status berikut:

  • Aktif: Pengguna memiliki reputasi baik dan memiliki akses ke langganan.
  • Dibatalkan: Pengguna telah membatalkan langganan, tetapi masih memiliki akses hingga masa berlakunya berakhir.
  • Dalam masa tenggang: Pengguna mengalami masalah pembayaran, tetapi masih dapat mengakses saat Google mencoba kembali metode pembayaran.
  • Ditangguhkan: Pengguna mengalami masalah pembayaran dan tidak lagi memiliki akses saat Google mencoba kembali metode pembayaran.
  • Dijeda: Pengguna menjeda aksesnya dan tidak memiliki akses hingga mereka melanjutkan.
  • Berakhir: Pengguna telah membatalkan dan kehilangan akses ke langganan. Pengguna dianggap churn out (berhenti menggunakan aplikasi) saat masa berlaku habis.

Melakukan inisialisasi pada koneksi ke Google Play

Langkah pertama untuk berintegrasi dengan sistem penagihan Google Play adalah menambahkan Library Layanan Penagihan Google Play ke aplikasi Anda dan melakukan inisialisasi koneksi.

Menambahkan dependensi Library Layanan Penagihan Google Play

Tambahkan dependensi Library Layanan Penagihan Google Play ke file build.gradle aplikasi Anda seperti yang ditunjukkan:

Groovy

dependencies {
    def billing_version = "7.1.1"

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

Kotlin

dependencies {
    val billing_version = "7.1.1"

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

Jika Anda menggunakan Kotlin, modul KTX Library Layanan Penagihan Google Play berisi ekstensi Kotlin dan dukungan coroutine yang memungkinkan Anda menulis Kotlin idiomatis saat menggunakan Library Layanan Penagihan Google Play. Untuk menyertakan ekstensi ini dalam project Anda, tambahkan dependensi berikut ke file build.gradle aplikasi Anda seperti yang ditunjukkan:

Groovy

dependencies {
    def billing_version = "7.1.1"

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

Kotlin

dependencies {
    val billing_version = "7.1.1"

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

Melakukan inisialisasi pada BillingClient

Setelah menambahkan dependensi pada Google Play Billing Library, Anda perlu melakukan inisialisasi instance BillingClient. BillingClient adalah antarmuka utama untuk komunikasi antara Library Layanan Penagihan Google Play dan bagian lain aplikasi Anda. BillingClient menyediakan metode praktis, baik sinkron maupun asinkron, untuk berbagai operasi penagihan umum. Perhatikan hal-hal berikut:

  • Sebaiknya Anda memiliki satu koneksi BillingClient aktif yang terbuka pada satu waktu untuk menghindari beberapa callback PurchasesUpdatedListener untuk satu peristiwa.
  • Sebaiknya mulai koneksi untuk BillingClient saat aplikasi diluncurkan atau muncul di latar depan untuk memastikan aplikasi memproses pembelian secara tepat waktu. Hal ini dapat dilakukan dengan menggunakan ActivityLifecycleCallbacks yang terdaftar oleh registerActivityLifecycleCallbacks dan memproses onActivityResumed untuk melakukan inisialisasi koneksi saat Anda pertama kali mendeteksi aktivitas yang dilanjutkan. Lihat bagian tentang memproses pembelian untuk mengetahui detail selengkapnya tentang alasan praktik terbaik ini harus diikuti. Ingat juga untuk mengakhiri koneksi saat aplikasi ditutup.

Untuk membuat BillingClient, gunakan newBuilder. Anda dapat meneruskan konteks ke newBuilder(), dan BillingClient akan menggunakannya untuk mendapatkan konteks aplikasi. Artinya, Anda tidak perlu mengkhawatirkan kebocoran memori. Untuk menerima update tentang pembelian, Anda juga harus memanggil setListener, yang meneruskan referensi ke PurchasesUpdatedListener. Pemroses ini menerima update untuk semua pembelian di aplikasi Anda.

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();

Menghubungkan ke Google Play

Setelah membuat BillingClient, Anda harus membuat koneksi ke Google Play.

Agar terhubung ke Google Play, panggil startConnection. Proses koneksi bersifat asinkron, dan Anda harus menerapkan BillingClientStateListener untuk menerima callback setelah penyiapan klien selesai dan siap membuat permintaan lebih lanjut.

Anda juga harus menerapkan logika mencoba ulang untuk menangani koneksi yang terputus ke Google Play. Untuk menerapkan logika mencoba ulang, ganti metode callback onBillingServiceDisconnected(), dan pastikan BillingClient memanggil metode startConnection() untuk terhubung kembali ke Google Play sebelum membuat permintaan lebih lanjut.

Contoh berikut menunjukkan cara memulai koneksi dan menguji apakah koneksi siap digunakan:

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.
    }
});

Menampilkan produk yang tersedia untuk dibeli

Setelah terhubung ke Google Play, Anda siap membuat kueri untuk produk yang tersedia dan menampilkannya kepada pengguna.

Kueri untuk detail produk merupakan langkah penting sebelum menampilkan produk kepada pengguna, karena proses ini akan menampilkan informasi produk yang dilokalkan. Untuk langganan, pastikan tampilan produk Anda mengikuti semua kebijakan Play.

Untuk membuat kueri detail produk dalam aplikasi, panggil queryProductDetailsAsync.

Untuk menangani hasil operasi asinkron, Anda juga harus menentukan pemroses yang menerapkan antarmuka ProductDetailsResponseListener. Anda kemudian dapat mengganti onProductDetailsResponse, yang memberi tahu pemroses ketika kueri selesai, seperti yang ditunjukkan dalam contoh berikut:

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
        }
    }
)

Saat membuat kueri untuk detail produk, teruskan instance QueryProductDetailsParams yang menentukan daftar string ID produk yang dibuat di Konsol Google Play bersama dengan ProductType. ProductType dapat berupa ProductType.INAPP untuk produk sekali beli, atau ProductType.SUBS untuk langganan.

Membuat kueri dengan ekstensi Kotlin

Jika menggunakan ekstensi Kotlin, Anda dapat membuat kueri untuk detail produk dalam aplikasi dengan memanggil fungsi ekstensi queryProductDetails().

queryProductDetails() memanfaatkan coroutine Kotlin sehingga Anda tidak perlu menentukan pemroses terpisah. Sebagai gantinya, fungsi tersebut akan ditangguhkan hingga kueri selesai, setelah itu Anda dapat memproses hasilnya:

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.
}

Meskipun jarang terjadi, beberapa perangkat mungkin tidak dapat mendukung ProductDetails dan queryProductDetailsAsync(), biasanya karena versi Layanan Google Play yang sudah tidak berlaku. Untuk memastikan dukungan yang tepat untuk skenario ini, pelajari cara menggunakan fitur kompatibilitas mundur dalam panduan migrasi Library Layanan Penagihan Play 5.

Memproses hasil

Library Layanan Penagihan Google Play menyimpan hasil kueri dalam List objek ProductDetails. Anda kemudian dapat memanggil berbagai metode pada setiap objek ProductDetails dalam daftar untuk melihat informasi yang relevan tentang produk dalam aplikasi, seperti harga atau deskripsinya. Untuk melihat informasi detail produk yang tersedia, lihat daftar metode dalam class ProductDetails.

Sebelum menawarkan item untuk dijual, pastikan pengguna belum memiliki item tersebut. Jika pengguna memiliki item habis pakai yang masih ada dalam library item, mereka harus memakai item tersebut sebelum dapat membelinya lagi.

Sebelum menawarkan langganan, verifikasi bahwa pengguna belum berlangganan. Selain itu, perhatikan hal-hal berikut:

  • queryProductDetailsAsync() menampilkan detail produk langganan dan maksimum 50 penawaran per langganan.
  • queryProductDetailsAsync() hanya menampilkan penawaran bagi pengguna yang memenuhi syarat. Jika pengguna mencoba membeli penawaran sedangkan mereka tidak memenuhi syarat (misalnya, jika aplikasi menampilkan daftar yang tidak berlaku lagi tentang penawaran yang memenuhi syarat), Play akan memberi tahu pengguna bahwa mereka tidak memenuhi syarat, dan sebagai gantinya, pengguna dapat memilih untuk membeli paket dasar.

Meluncurkan alur pembelian

Untuk memulai permintaan pembelian dari aplikasi Anda, panggil metode launchBillingFlow() dari thread utama aplikasi Anda. Metode ini mengambil referensi ke objek BillingFlowParams yang berisi objek ProductDetails yang relevan dan diperoleh dari panggilan queryProductDetailsAsync. Untuk membuat objek BillingFlowParams, gunakan class 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);

Metode launchBillingFlow() menampilkan salah satu dari beberapa kode respons yang tercantum dalam BillingClient.BillingResponseCode. Pastikan Anda memeriksa hasil ini untuk memastikan tidak ada error saat meluncurkan alur pembelian. BillingResponseCode yang menyatakan OK menunjukkan peluncuran yang berhasil.

Jika panggilan ke launchBillingFlow() berhasil, sistem akan menampilkan layar pembelian Google Play. Gambar 1 menunjukkan layar pembelian untuk langganan:

layar pembelian Google Play menampilkan langganan
            yang tersedia untuk dibeli
Gambar 1. Layar pembelian Google Play menampilkan langganan yang tersedia untuk dibeli.

Google Play memanggil onPurchasesUpdated() untuk mengirimkan hasil operasi pembelian ke pemroses yang menerapkan antarmuka PurchasesUpdatedListener. Pemroses ditentukan menggunakan metode setListener() saat Anda melakukan inisialisasi klien.

Anda harus menerapkan onPurchasesUpdated() untuk menangani kode respons yang mungkin diberikan. Contoh berikut menunjukkan cara mengganti 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.
    }
}

Pembelian yang berhasil akan memunculkan layar keberhasilan melakukan pembelian di Google Play yang serupa dengan gambar 2.

layar keberhasilan melakukan pembelian di google play
Gambar 2. Layar keberhasilan melakukan pembelian di Google Play.

Pembelian yang berhasil juga akan memunculkan token pembelian, yakni ID unik yang mewakili pengguna dan ID produk untuk produk dalam aplikasi yang mereka beli. Aplikasi Anda dapat menyimpan token pembelian secara lokal, meskipun sebaiknya Anda meneruskan token ke server backend yang aman, tempat Anda dapat memverifikasi pembelian dan melindungi dari penipuan. Proses ini dijelaskan lebih lanjut di Mendeteksi dan Memproses Pembelian.

Pengguna juga akan menerima melalui email tanda terima transaksi yang berisi ID Pesanan atau ID unik transaksi. Pengguna menerima email yang berisi ID Pesanan unik untuk setiap pembelian produk sekali beli, juga untuk pembelian langganan awal dan perpanjangan otomatis berulang berikutnya. Anda dapat menggunakan ID Pesanan ini untuk mengelola pengembalian dana di Konsol Google Play.

Menunjukkan harga yang dipersonalisasi

Jika aplikasi Anda dapat didistribusikan kepada pengguna di Uni Eropa, gunakan metode setIsOfferPersonalized() saat memanggil launchBillingFlow untuk mengungkapkan kepada pengguna bahwa harga item dipersonalisasi menggunakan pengambilan keputusan otomatis.

Layar pembelian Google Play yang menunjukkan bahwa harga disesuaikan untuk pengguna.
Gambar 3. Layar pembelian Google Play yang menunjukkan bahwa harga disesuaikan untuk pengguna.

Anda harus membaca Seni. 6 (1) (ea) CRD dari Pedoman Hak Konsumen 2011/83/EU untuk menentukan apakah harga yang Anda tawarkan kepada pengguna dipersonalisasi.

setIsOfferPersonalized() akan mengambil input boolean. Saat true, UI Play akan menyertakan pengungkapan. Saat false, UI akan menghilangkan pengungkapan. Nilai default-nya adalah false.

Lihat Pusat Bantuan Konsumen untuk informasi selengkapnya.

Melampirkan ID pengguna

Saat Anda meluncurkan alur pembelian, aplikasi dapat melampirkan ID pengguna apa pun yang Anda miliki untuk pengguna yang melakukan pembelian menggunakan obfuscatedAccountId atau obfuscatedProfileId. Contoh ID dapat berupa versi login pengguna yang di-obfuscate di sistem Anda. Menetapkan parameter ini dapat membantu Google mendeteksi penipuan. Selain itu, hal ini dapat membantu Anda memastikan pembelian diatribusikan ke pengguna yang tepat seperti yang dibahas dalam memberikan hak kepada pengguna.

Mendeteksi dan memproses pembelian

Deteksi dan pemrosesan pembelian yang dijelaskan di bagian ini berlaku untuk semua jenis pembelian, termasuk pembelian di luar aplikasi seperti penukaran promosi.

Aplikasi Anda mendeteksi pembelian baru dan menyelesaikan pembelian tertunda dengan salah satu cara berikut:

  1. Saat onPurchasesUpdated dipanggil sebagai hasil dari aplikasi Anda yang memanggil launchBillingFlow (seperti yang dibahas di bagian sebelumnya) atau jika aplikasi Anda berjalan dengan koneksi Library Penagihan yang aktif saat ada pembelian yang dilakukan di luar aplikasi Anda atau pembelian tertunda selesai. Misalnya, anggota keluarga menyetujui pembelian yang tertunda di perangkat lain.
  2. Saat aplikasi Anda memanggil queryPurchasesAsync untuk mengkueri pembelian pengguna.

Untuk #1, onPurchasesUpdated akan otomatis dipanggil untuk pembelian baru atau selesai selama aplikasi Anda berjalan dan memiliki koneksi Library Layanan Penagihan Google Play yang aktif. Jika aplikasi tidak berjalan atau aplikasi tidak memiliki koneksi library Layanan Penagihan Google Play yang aktif, onPurchasesUpdated tidak akan dipanggil. Ingat, sebaiknya aplikasi Anda mencoba mempertahankan koneksi aktif selama aplikasi berada di latar depan untuk memastikan aplikasi mendapatkan update pembelian yang tepat waktu.

Untuk #2, Anda harus memanggil BillingClient.queryPurchasesAsync() untuk memastikan aplikasi Anda memproses semua pembelian. Sebaiknya lakukan ini saat aplikasi Anda berhasil membuat koneksi dengan Library Layanan Penagihan Google Play (yang direkomendasikan saat aplikasi diluncurkan atau muncul di latar depan seperti yang dibahas dalam melakukan inisialisasi BillingClient. Hal ini dapat dilakukan dengan memanggil queryPurchasesAsync saat menerima hasil yang berhasil ke onServiceConnected. Mengikuti rekomendasi ini sangat penting untuk menangani peristiwa dan situasi seperti:

  • Masalah Jaringan selama pembelian: Pengguna dapat melakukan pembelian yang berhasil dan menerima konfirmasi dari Google, tetapi perangkat mereka kehilangan konektivitas jaringan sebelum perangkat mereka dan aplikasi Anda menerima notifikasi pembelian melalui PurchasesUpdatedListener.
  • Beberapa perangkat: Pengguna dapat membeli item di satu perangkat, lalu mengharapkan untuk melihat item tersebut saat beralih perangkat.
  • Menangani pembelian yang dilakukan di luar aplikasi: Beberapa pembelian, seperti penukaran promosi, dapat dilakukan di luar aplikasi Anda.
  • Menangani transisi status pembelian: Pengguna dapat menyelesaikan pembayaran untuk pembelian PENDING saat aplikasi Anda tidak berjalan dan berharap menerima konfirmasi bahwa mereka telah menyelesaikan pembelian saat membuka aplikasi Anda.

Setelah aplikasi mendeteksi pembelian baru atau yang telah selesai, aplikasi harus:

  • Memverifikasi pembelian.
  • Memberikan konten kepada pengguna untuk pembelian yang telah selesai.
  • Beri tahu pengguna.
  • Memberi tahu Google bahwa aplikasi Anda memproses pembelian yang telah selesai.

Langkah-langkah ini dibahas secara mendetail di bagian berikut, diikuti dengan bagian untuk merangkum semua langkah.

Memverifikasi pembelian

Aplikasi Anda harus selalu memverifikasi pembelian untuk memastikan pembelian tersebut sah sebelum memberikan manfaat kepada pengguna. Hal ini dapat dilakukan dengan mengikuti panduan yang dijelaskan dalam Memverifikasi pembelian sebelum memberikan hak. Hanya setelah memverifikasi pembelian, aplikasi Anda harus terus memproses pembelian dan memberikan hak kepada pengguna, yang akan dibahas di bagian berikutnya.

Memberikan Hak kepada Pengguna

Setelah memverifikasi pembelian, aplikasi Anda dapat terus memberikan hak kepada pengguna dan memberi tahu pengguna. Sebelum memberikan hak, pastikan aplikasi Anda memeriksa apakah status pembelian adalah PURCHASED. Jika pembelian dalam status TERTUNDA, aplikasi Anda harus memberi tahu pengguna bahwa mereka masih perlu menyelesaikan tindakan untuk menyelesaikan pembelian sebelum hak diberikan. Hanya berikan hak saat pembelian bertransisi dari PENDING ke SUCCESS. Informasi tambahan dapat ditemukan di Menangani transaksi yang tertunda.

Jika telah melampirkan ID pengguna ke pembelian seperti yang dibahas dalam melampirkan ID pengguna, Anda dapat mengambil dan menggunakannya untuk mengatribusikan ke pengguna yang benar di sistem Anda. Teknik ini berguna saat merekonsiliasi pembelian saat aplikasi Anda mungkin kehilangan konteks tentang pengguna mana yang melakukan pembelian. Perhatikan bahwa pembelian yang dilakukan di luar aplikasi Anda tidak akan menetapkan ID ini. Dalam hal ini, aplikasi Anda dapat memberikan hak kepada pengguna yang login, atau meminta pengguna untuk memilih akun yang diinginkan.

Memberi tahu Pengguna

Setelah memberikan hak kepada pengguna, aplikasi Anda harus menampilkan notifikasi untuk mengonfirmasi pembelian yang berhasil. Hal ini memastikan pengguna tidak bingung apakah pembelian berhasil diselesaikan, yang dapat menyebabkan pengguna berhenti menggunakan aplikasi Anda, menghubungi dukungan pengguna, atau mengeluhkannya di media sosial. Perhatikan bahwa aplikasi Anda dapat mendeteksi update pembelian kapan saja selama siklus proses aplikasi. Misalnya, orang tua menyetujui pembelian yang tertunda di perangkat lain. Dalam hal ini, aplikasi Anda mungkin ingin menunda notifikasi kepada pengguna hingga waktu yang sesuai. Beberapa contoh saat penundaan diperlukan adalah:

  • Selama bagian tindakan dalam game atau cutscene, menampilkan pesan dapat mengganggu perhatian pengguna. Dalam hal ini, Anda harus memberi tahu pengguna setelah bagian tindakan berakhir.
  • Selama tutorial awal dan bagian penyiapan pengguna dalam game. Misalnya, pengguna mungkin telah melakukan pembelian di luar aplikasi Anda sebelum menginstalnya. Sebaiknya beri tahu pengguna baru tentang reward segera setelah mereka membuka game atau selama penyiapan pengguna awal. Jika aplikasi Anda mewajibkan pengguna membuat akun atau login sebelum memberikan hak kepada pengguna, sebaiknya komunikasikan kepada pengguna langkah-langkah yang harus diselesaikan untuk mengklaim pembelian mereka. Hal ini penting karena pembelian akan dikembalikan dananya setelah 3 hari jika aplikasi Anda belum memproses pembelian.

Saat memberi tahu pengguna tentang pembelian, Google Play merekomendasikan mekanisme berikut:

  • Menampilkan dialog dalam aplikasi.
  • Mengirim pesan ke kotak pesan dalam aplikasi, dan menyatakan dengan jelas bahwa ada pesan baru di kotak pesan dalam aplikasi.
  • Menggunakan pesan notifikasi OS.

Notifikasi harus memberi tahu pengguna tentang manfaat yang mereka terima. Misalnya, "Anda telah membeli 100 Koin Emas". Selain itu, jika pembelian merupakan akibat dari manfaat program seperti Play Pass, aplikasi Anda akan menyampaikan hal ini kepada pengguna. Misalnya "Item diterima! Anda baru saja mendapatkan 100 Permata dengan Play Pass. Lanjutkan.". Setiap program mungkin memiliki panduan tentang teks yang direkomendasikan untuk ditampilkan kepada pengguna guna menyampaikan manfaat.

Memberi tahu Google bahwa pembelian telah diproses

Setelah aplikasi Anda memberikan hak kepada pengguna dan memberi tahu mereka tentang transaksi yang berhasil, aplikasi Anda harus memberi tahu Google bahwa pembelian berhasil diproses. Hal ini dilakukan dengan mengonfirmasi pembelian dan harus dilakukan dalam waktu tiga hari untuk memastikan pembelian tidak otomatis dikembalikan dananya dan hak dicabut. Proses untuk mengonfirmasi berbagai jenis pembelian dijelaskan di bagian berikut.

Produk consumable

Untuk produk habis pakai, jika aplikasi Anda memiliki backend aman, sebaiknya gunakan Purchases.products:consume untuk memakai pembelian dengan andal. Pastikan pembelian belum dipakai dengan memeriksa consumptionState dari hasil panggilan Purchases.products:get. Jika aplikasi Anda hanya untuk klien tanpa backend, gunakan consumeAsync() dari Library Layanan Penagihan Google Play. Kedua metode tersebut memenuhi persyaratan konfirmasi dan menunjukkan bahwa aplikasi Anda telah memberikan hak kepada pengguna. Metode ini juga memungkinkan aplikasi Anda membuat produk sekali beli yang sesuai dengan token pembelian input yang bisa dibeli kembali. Dengan consumeAsync(), Anda juga harus meneruskan objek yang menerapkan antarmuka ConsumeResponseListener. Objek ini menangani hasil operasi pemakaian. Anda dapat mengganti metode onConsumeResponse(), yang dipanggil oleh Library Layanan Penagihan Google Play saat operasi selesai.

Contoh berikut menggambarkan pemakaian produk dengan Library Layanan Penagihan Google Play menggunakan token pembelian yang terkait:

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);

Produk non-consumable

Untuk mengonfirmasi pembelian produk tidak habis pakai, jika aplikasi Anda memiliki backend aman, sebaiknya gunakan Purchases.products:acknowledge untuk mengonfirmasi pembelian dengan andal. Pastikan pembelian belum pernah dikonfirmasi dengan memeriksa acknowledgementState dari hasil panggilan Purchases.products:get.

Jika aplikasi Anda hanya untuk klien, gunakan BillingClient.acknowledgePurchase() dari Library Layanan Penagihan Google Play di aplikasi Anda. Sebelum mengonfirmasi pembelian, aplikasi Anda harus memeriksa apakah pembelian itu sudah dikonfirmasi dengan menggunakan metode isAcknowledged() di Library Layanan Penagihan Google Play.

Contoh berikut menunjukkan cara mengonfirmasi pembelian menggunakan Library Layanan Penagihan Google Play:

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);

Langganan

Langganan ditangani dengan cara yang sama seperti item yang tidak habis pakai. Jika memungkinkan, gunakan Purchases.subscriptions.acknowledge dari Google Play Developer API untuk mengonfirmasi pembelian dari backend aman Anda dengan andal. Pastikan bahwa pembelian belum pernah dikonfirmasi sebelumnya dengan memeriksa acknowledgementState di resource pembelian dari Purchases.subscriptions:get. Jika tidak, Anda dapat mengonfirmasi langganan menggunakan BillingClient.acknowledgePurchase() dari Library Layanan Penagihan Google Play setelah memeriksa isAcknowledged(). Semua pembelian langganan awal harus dikonfirmasi. Perpanjangan langganan tidak perlu dikonfirmasi. Untuk informasi selengkapnya terkait kapan langganan perlu dikonfirmasi, lihat topik Menjual langganan.

Rangkuman

Cuplikan kode berikut menunjukkan recap langkah-langkah ini.

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.
}

Untuk memverifikasi bahwa aplikasi Anda telah menerapkan langkah-langkah ini dengan benar, Anda dapat mengikuti panduan pengujian.

Menangani transaksi yang tertunda

Google Play mendukung transaksi yang tertunda, atau transaksi yang memerlukan satu atau beberapa langkah tambahan antara saat pengguna memulai pembelian dan saat metode pembayaran untuk pembelian tersebut diproses. Aplikasi Anda tidak boleh memberikan hak atas jenis pembelian ini sampai Google memberi tahu Anda bahwa metode pembayaran pengguna berhasil ditagih.

Misalnya, pengguna dapat memulai transaksi dengan memilih toko fisik tempat mereka akan membayar nanti dengan uang tunai. Pengguna menerima kode melalui notifikasi dan email. Saat pengguna tiba di toko fisik, mereka dapat menukarkan kode kepada kasir dan membayar dengan uang tunai. Kemudian, Google memberi tahu Anda dan pengguna bahwa pembayaran telah diterima. Kemudian, aplikasi Anda dapat memberikan hak kepada pengguna.

Panggil enablePendingPurchases() sebagai bagian dari inisialisasi BillingClient untuk mengaktifkan transaksi yang tertunda untuk aplikasi Anda. Aplikasi Anda harus mengaktifkan dan mendukung transaksi yang tertunda untuk produk sekali beli. Sebelum menambahkan dukungan, pastikan Anda memahami siklus proses pembelian untuk transaksi yang tertunda.

Jika aplikasi Anda menerima pembelian baru, baik melalui PurchasesUpdatedListener atau sebagai hasil dari panggilan queryPurchasesAsync, gunakan metode getPurchaseState() untuk menentukan apakah status pembelian tersebut adalah PURCHASED atau PENDING. Anda harus memberikan hak hanya jika statusnya adalah PURCHASED.

Jika aplikasi Anda berjalan dan Anda memiliki koneksi Library Layanan Penagihan Play yang aktif saat pengguna menyelesaikan pembelian, PurchasesUpdatedListener akan dipanggil lagi, dan PurchaseState sekarang menjadi PURCHASED. Pada tahap ini, aplikasi Anda dapat memproses pembelian menggunakan metode standar untuk Mendeteksi dan Memproses Pembelian. Aplikasi Anda juga harus memanggil queryPurchasesAsync() di metode onResume() aplikasi untuk menangani pembelian yang telah dialihkan ke status PURCHASED saat aplikasi Anda tidak berjalan.

Saat pembelian bertransisi dari PENDING ke PURCHASED, klien real_time_developer_notifications Anda akan menerima notifikasi ONE_TIME_PRODUCT_PURCHASED atau SUBSCRIPTION_PURCHASED. Jika pembelian dibatalkan, Anda akan menerima notifikasi ONE_TIME_PRODUCT_CANCELED atau SUBSCRIPTION_PENDING_PURCHASE_CANCELED. Hal ini dapat terjadi jika pelanggan tidak menyelesaikan pembayaran dalam jangka waktu yang diperlukan. Perhatikan bahwa Anda selalu dapat menggunakan Google Play Developer API untuk memeriksa status pembelian saat ini.

Menangani pembelian multikuantitas

Dengan tersedianya dukungan untuk Library Layanan Penagihan Google Play versi 4.0 dan yang lebih baru, Google Play memungkinkan pelanggan membeli lebih dari satu produk dalam aplikasi yang sama dalam satu transaksi dengan menentukan kuantitas dari keranjang pembelian. Aplikasi Anda diharapkan dapat menangani pembelian multikuantitas dan memberikan hak berdasarkan jumlah pembelian yang ditentukan.

Untuk memenuhi pembelian multikuantitas, logika penyediaan aplikasi Anda harus memeriksa jumlah item. Anda dapat mengakses kolom quantity dari salah satu API berikut:

Setelah menambahkan logika untuk menangani pembelian multikuantitas, Anda harus mengaktifkan fitur multikuantitas untuk produk yang sesuai di halaman pengelolaan produk dalam aplikasi di Konsol Google Play.

Membuat kueri konfigurasi penagihan pengguna

getBillingConfigAsync() menunjukkan negara yang dipilih pengguna untuk Google Play.

Anda dapat membuat kueri konfigurasi penagihan pengguna setelah membuat BillingClient. Cuplikan kode berikut menjelaskan cara melakukan panggilan ke getBillingConfigAsync(). Tangani respons dengan menerapkan BillingConfigResponseListener. Pemroses ini menerima update untuk semua kueri konfigurasi penagihan yang dimulai dari aplikasi Anda.

Jika BillingResult yang ditampilkan tidak berisi error, Anda dapat memeriksa kolom countryCode di objek BillingConfig untuk mendapatkan negara pilihan pengguna di 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
        }
      }
    });

Pengingat pengabaian keranjang di layar utama Google Play Game (diaktifkan secara default)

Untuk developer Game yang melakukan monetisasi melalui IAP, satu cara agar unit pengelolaan inventaris (SKU) yang aktif di Konsol Google Play dapat dijual di luar aplikasi Anda adalah fitur Pengingat Pengabaian Keranjang, yang mendorong pengguna untuk menyelesaikan pembelian yang sebelumnya ditinggalkan saat menjelajahi Google Play Store. Pembelian ini terjadi di luar aplikasi Anda, dari layar utama Google Play Game di Google Play Store.

Fitur ini diaktifkan secara default untuk membantu pengguna melanjutkan dari tempat terakhir mereka berhenti dan membantu developer memaksimalkan penjualan. Namun, Anda dapat memilih untuk tidak ikut menggunakan fitur ini dengan mengirimkan formulir pilihan tidak ikut fitur Pengingat Pengabaian Keranjang. Untuk praktik terbaik dalam mengelola SKU dalam Konsol Google Play, lihat Membuat produk dalam aplikasi.

Gambar berikut menunjukkan Pengingat Pengabaian Keranjang yang muncul di Google Play Store:

layar Google Play Store menampilkan
    perintah pembelian untuk pembelian yang sebelumnya ditinggalkan
Gambar 2. Layar Google Play Store menampilkan perintah pembelian untuk pembelian yang sebelumnya ditinggalkan.

layar Google Play Store menampilkan
    perintah pembelian untuk pembelian yang sebelumnya ditinggalkan
Gambar 3. Layar Google Play Store menampilkan perintah pembelian untuk pembelian yang sebelumnya ditinggalkan.