Mengimplementasikan Penagihan dalam Aplikasi

Penagihan dalam Aplikasi di Google Play menyediakan antarmuka yang sederhana dan mudah dipahami untuk mengirimkan permintaan Penagihan dalam Aplikasi dan mengelola transaksi Penagihan dalam Aplikasi menggunakan Google Play. Informasi berikut mencakup dasar-dasar cara membuat panggilan dari aplikasi Anda ke layanan Penagihan dalam Aplikasi menggunakan Version 3 API.

Catatan: Untuk melihat implementasi lengkap dan mempelajari cara menguji aplikasi Anda, lihat kelas pelatihan Menjual Produk dalam Aplikasi . Kelas pelatihan menyediakan contoh aplikasi Penagihan dalam Aplikasi yang lengkap, termasuk kelas kapan pun bisa diikuti untuk menangani tugas kunci yang terkait dengan menyiapkan koneksi, mengirimkan permintaan penagihan, dan memproses respons dari Google Play, dan mengelola utas latar belakang sehingga Anda bisa membuat panggilan Penagihan dalam Aplikasi dari aktivitas utama Anda.

Sebelum mulai, pastikan Anda telah membaca Ringkasan Penagihan dalam Aplikasi untuk memahami konsep-konsep yang akan memudahkan Anda mengimplementasikan Penagihan dalam Aplikasi.

Untuk mengimplementasikan Penagihan dalam Aplikasi di aplikasi, Anda perlu melakukan yang berikut:

  1. Tambahkan pustaka Penagihan dalam Aplikasi ke proyek Anda.
  2. Perbarui file AndroidManifest.xml Anda.
  3. Buat ServiceConnection dan ikatkan ke IInAppBillingService.
  4. Kirim permintaan Penagihan dalam Aplikasi dari aplikasi ke IInAppBillingService.
  5. Tangani respons Penagihan dalam Aplikasi dari Google Play.

Menambahkan file AIDL ke proyek Anda

IInAppBillingService.aidl adalah Bahasa Definisi Antarmuka Android (Android Interface Definition Language - AIDL) yang mendefinisikan antarmuka ke layanan Penagihan dalam Aplikasi Versi 3. Anda akan menggunakan antarmuka ini untuk membuat permintaan penagihan dengan menerapkan panggilan metode IPC.

Untuk mendapatkan file AIDL:

  1. Buka Android SDK Manager.
  2. Di SDK Manager, luaskan bagian Extras.
  3. Pilih Google Play Billing Library.
  4. Klik Install packages untuk menyelesaikan unduhan.

File IInAppBillingService.aidl akan dipasang ke <sdk>/extras/google/play_billing/.

Untuk menambahkan AIDL ke proyek Anda:

  1. Pertama, unduh Google Play Billing Library ke proyek Android Anda:
    1. Pilih Tools > Android > SDK Manager.
    2. Di bawah Appearance & Behavior > System Settings > Android SDK, pilih tab SDK Tools untuk memilih dan mengunduh Google Play Billing Library.
  2. Selanjutnya, salin file IInAppBillingService.aidl ke proyek Anda.
    • Jika Anda menggunakan Android Studio:
      1. Masuk ke src/main di jendela Project tool.
      2. Pilih File > New > Directory dan masukkan aidl di jendela New Directory, lalu pilih OK.
      3. Pilih File > New > Package dan masukkan com.android.vending.billing di jendela New Package, lalu pilih OK.
      4. Menggunakan penjelajah file sistem operasi Anda, masuk ke <sdk>/extras/google/play_billing/, salin file IInAppBillingService.aidl, dan tempelkan ke paket com.android.vending.billing di proyek Anda.
    • Jika Anda mengerjakan pengembangan di lingkungan selain Android Studio: Buat direktori /src/com/android/vending/billing berikut dan salin file IInAppBillingService.aidl ke direktori ini. Tempatkan file AIDL ke proyek Anda dan gunakan alat Gradle untuk membangun proyek Anda sehingga file IInAppBillingService.java dihasilkan.
  3. Bangun aplikasi Anda. Anda seharusnya melihat file yang dihasilkan yang bernama IInAppBillingService.java di direktori /gen proyek Anda.

Memperbarui Manifes Aplikasi Anda

Penagihan dalam aplikasi bergantung pada aplikasi Google Play yang menangani semua komunikasi antara aplikasi Anda dengan server Google Play. Untuk menggunakan aplikasi Google Play, aplikasi Anda harus meminta izin yang benar. Anda bisa melakukannya dengan menambahkan izin com.android.vending.BILLING ke file AndroidManifest.xml Anda. Jika aplikasi Anda tidak mendeklarasikan izin Penagihan dalam Aplikasi, tetapi mencoba mengirim permintaan penagihan, Google Play akan menolak permintaan tersebut dan meresponsnya dengan kesalahan.

Untuk memberikan izin yang diperlukan pada aplikasi Anda, tambahkan baris ini ke file AndroidManifest.xml:

<uses-permission android:name="com.android.vending.BILLING" />

Membuat ServiceConnection

Aplikasi Anda harus memiliki ServiceConnection untuk memfasilitasi perpesanan antara aplikasi Anda dengan Google Play. Paling tidak, aplikasi Anda harus melakukan yang berikut:

  • Terikat ke IInAppBillingService.
  • Mengirim permintaan penagihan (sebagai panggilan metode IPC) ke aplikasi Google Play.
  • Menangani pesan respons sinkron yang dikembalikan dengan setiap permintaan penagihan.

Mengikatkan ke InAppBillingService

Untuk membuat sambungan ke layanan Penagihan dalam Aplikasi di Google Play, implementasikan ServiceConnection untuk mengikatkan aktivitas Anda ke IInAppBillingService. Ganti metode onServiceDisconnected dan onServiceConnected untuk mendapatkan referensi ke instance IInAppBillingService setelah sambungan terbuat.

IInAppBillingService mService;

ServiceConnection mServiceConn = new ServiceConnection() {
   @Override
   public void onServiceDisconnected(ComponentName name) {
       mService = null;
   }

   @Override
   public void onServiceConnected(ComponentName name,
      IBinder service) {
       mService = IInAppBillingService.Stub.asInterface(service);
   }
};

Dalam metode onCreate aktivitas Anda, lakukan pengikatan dengan memanggil metode bindService. Teruskan Intent ke metode yang mereferensi layanan Penagihan dalam Aplikasi dan instance ServiceConnection yang Anda buat dan secara eksplisit tetapkan nama paket target Maksud ke com.android.vending — nama paket aplikasi Google Play.

Perhatian: Untuk melindungi keamanan transaksi penagihan, selalu pastikan untuk menetapkan nama paket target maksud secara eksplisit ke com.android.vending, menggunakan setPackage() seperti yang ditampilkan dalam contoh berikut. Menetapkan nama paket secara eksplisit memastikan bahwa hanya aplikasi Google Play yang bisa menangani permintaan penagihan dari aplikasi Anda, sehingga mencegah aplikasi lain menangkap permintaan tersebut.

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  Intent serviceIntent =
      new Intent("com.android.vending.billing.InAppBillingService.BIND");
  serviceIntent.setPackage("com.android.vending");
  bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
}

Kini Anda bisa menggunakan referensi mService untuk berkomunikasi dengan layanan Google Play.

Penting: Ingatlah untuk melepas ikatan dari layanan Penagihan dalam Aplikasi bila Anda sudah selesai dengan Activity. Jika Anda tidak melepas ikatan, sambungan layanan yang terbuka bisa mengakibatkan kinerja perangkat Anda menurun. Contoh ini menampilkan cara melakukan operasi pelepasan ikatan pada sambungan layanan ke Penagihan dalam Aplikasi yang disebut sebagai mServiceConn dengan mengganti metode onDestroy aktivitas.

@Override
public void onDestroy() {
    super.onDestroy();
    if (mService != null) {
        unbindService(mServiceConn);
    }
}

Untuk implementasi lengkap sambungan layanan yang mengikat ke IInAppBillingService, lihat kelas pelatihan Menjual Produk dalam Aplikasi dan contoh terkait.

Membuat Permintaan Penagihan dalam Aplikasi

Setelah aplikasi Anda tersambung ke Google Play, Anda bisa memulai permintaan pembelian untuk produk dalam aplikasi Anda. Google Play menyediakan antarmuka checkout bagi pengguna untuk memasukkan metode pembayarannya, sehingga aplikasi Anda tidak perlu menangani transaksi pembayaran secara langsung. Saat item dibeli, Google Play mengenali pengguna sebagai telah memegang kepemilikan atas item tersebut dan mencegah pengguna membeli item lain dengan ID produk yang sama sampai item dikonsumsi. Anda bisa mengontrol bagaimana item dikonsumsi di aplikasi Anda dan memberi tahu Google Play untuk membuat item kembali tersedia untuk dibeli. Anda juga bisa melakukan kueri pada Google Play untuk secara cepat mengambil daftar pembelian yang dilakukan oleh pengguna. Ini berguna, misalnya, bila Anda ingin memulihkan pembelian pengguna saat pengguna meluncurkan aplikasi.

Membuat Kueri Item yang Tersedia untuk Dibeli

Dalam aplikasi Anda, Anda bisa melakukan kueri detail item dari Google Play menggunakan In-app Billing Version 3 API. Untuk meneruskan permintaan ke layanan Penagihan dalam Aplikasi, buat Bundle terlebih dulu yang berisi String ArrayList ID produk dengan kunci "ITEM_ID_LIST", yang setiap stringnya adalah sebuah ID produk untuk item yang bisa dibeli.

ArrayList<String> skuList = new ArrayList<String> ();
skuList.add("premiumUpgrade");
skuList.add("gas");
Bundle querySkus = new Bundle();
querySkus.putStringArrayList(“ITEM_ID_LIST”, skuList);

Untuk mengambil informasi ini dari Google Play, panggil metode getSkuDetails di In-app Billing Version 3 API, dan teruskan metode In-app Billing API Version (“3”), nama paket aplikasi yang memanggil, jenis pembelian ("inapp") dan Bundle yang Anda buat ke metode.

Bundle skuDetails = mService.getSkuDetails(3,
   getPackageName(), "inapp", querySkus);

Jika permintaan berhasil, Bundleyang dikembalikan memiliki kode respons BILLING_RESPONSE_RESULT_OK (0).

Peringatan: Jangan panggil metode getSkuDetails di thread utama. Memanggil metode ini akan memicu permintaan jaringan yang bisa memblokir thread utama Anda. Sebagai gantinya, buat thread terpisah dan panggil metode getSkuDetails dari dalam thread tersebut.

Untuk melihat semua kode respons yang bisa dipakai dari Google Play, lihat Referensi Penagihan dalam Aplikasi.

Hasil kueri disimpan di String ArrayList dengan kunci DETAILS_LIST. Informasi pembelian disimpan di String dalam format JSON. Untuk melihat jenis informasi detail produk yang dikembalikan, lihat Referensi Penagihan dalam Aplikasi.

Dalam contoh ini, Anda mengambil harga untuk item dalam aplikasi Anda dari skuDetails Bundle yang dikembalikan dari cuplikan kode sebelumnya.

int response = skuDetails.getInt("RESPONSE_CODE");
if (response == 0) {
   ArrayList<String> responseList
      = skuDetails.getStringArrayList("DETAILS_LIST");

   for (String thisResponse : responseList) {
      JSONObject object = new JSONObject(thisResponse);
      String sku = object.getString("productId");
      String price = object.getString("price");
      if (sku.equals("premiumUpgrade")) mPremiumUpgradePrice = price;
      else if (sku.equals("gas")) mGasPrice = price;
   }
}

Membeli Item

Untuk memulai permintaan pembelian dari aplikasi Anda, panggil metode getBuyIntent di layanan Penagihan dalam Aplikasi. Teruskan In-app Billing API versi ("3), nama paket aplikasi yang memanggil, ID produk untuk item yang akan dibeli, jenis pembelian ("inapp" atau "subs"), dan String developerPayload. String developerPayload digunakan untuk menentukan argumen tambahan yang Anda inginkan agar dikirimkan kembali oleh Google Play bersama dengan informasi pembelian.

Bundle buyIntentBundle = mService.getBuyIntent(3, getPackageName(),
   sku, "inapp", "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ");

Jika permintaan berhasil, Bundle yang dikembalikan memiliki kode respons BILLING_RESPONSE_RESULT_OK (0) dan sebuah PendingIntent yang bisa Anda gunakan untuk memulai alur pembelian. Untuk melihat semua kode respons yang bisa dipakai dari Google Play, lihat Referensi Penagihan dalam Aplikasi. Selanjutnya, ekstraksi PendingIntent dari Bundle respons dengan kunci BUY_INTENT.

PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");

Untuk menyelesaikan transaksi pembelian, panggil metode startIntentSenderForResult dan gunakan PendingIntent yang Anda buat. Dalam contoh ini, Anda menggunakan nilai arbitrer 1001 untuk kode permintaan.

startIntentSenderForResult(pendingIntent.getIntentSender(),
   1001, new Intent(), Integer.valueOf(0), Integer.valueOf(0),
   Integer.valueOf(0));

Google Play mengirimkan respons atas PendingIntent Anda ke metode onActivityResult aplikasi Anda. Metode onActivityResult akan menghasilkan kode Activity.RESULT_OK (1) atau Activity.RESULT_CANCELED (0). Untuk melihat jenis informasi pesanan yang dikembalikan di Intent respons, lihat Referensi Penagihan dalam Aplikasi.

Data pembelian untuk pesanan adalah String dalam format JSON yang dipetakan ke kunci INAPP_PURCHASE_DATA di Intent respons, misalnya:

'{
   "orderId":"GPA.1234-5678-9012-34567",
   "packageName":"com.example.app",
   "productId":"exampleSku",
   "purchaseTime":1345678900000,
   "purchaseState":0,
   "developerPayload":"bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ",
   "purchaseToken":"opaque-token-up-to-1000-characters"
 }'

Catatan: Google Play membuat token untuk pembelian. Token ini adalah urutan karakter yang sulit dimengerti yang panjangnya sampai 1000 karakter. Teruskan keseluruhan token ini ke metode lain, misalnya saat Anda mengonsumsi pembelian, seperti yang dijelaskan di Mengonsumsi Pembelian. Jangan menyingkat atau memotong token ini; Anda harus menyimpan dan mengembalikan keseluruhan token.

Berlanjut dari contoh sebelumnya, Anda mendapatkan kode respons, data pembelian, dan tanda tangan dari Intent respons.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
   if (requestCode == 1001) {
      int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
      String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
      String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");

      if (resultCode == RESULT_OK) {
         try {
            JSONObject jo = new JSONObject(purchaseData);
            String sku = jo.getString("productId");
            alert("You have bought the " + sku + ". Excellent choice,
               adventurer!");
          }
          catch (JSONException e) {
             alert("Failed to parse purchase data.");
             e.printStackTrace();
          }
      }
   }
}

Saran Keamanan: Saat Anda mengirimkan permintaan pembelian, buat token String yang secara unik mengidentifikasi permintaan pembelian ini dan sertakan token ini ke developerPayload. Anda bisa menggunakan string yang dibuat acak sebagai token. Saat Anda menerima respons pembelian dari Google Play, pastikan periksa tanda tangan data yang dikembalikan, orderId, dan String developerPayload. Untuk keamanan tambahan, Anda sebaiknya melakukan pemeriksaan pada server aman Anda sendiri. Pastikan untuk memverifikasi bahwa orderId adalah nilai unik yang belum pernah Anda proses dan String developerPayload cocok dengan token yang Anda kirim sebelumnya dengan permintaan pembelian.

Membuat Kueri Item yang Dibeli

Untuk mengambil informasi tentang pembelian yang dibuat oleh pengguna dari aplikasi Anda, panggil metode getPurchases di layanan Penagihan dalam Aplikasi Versi 3. Teruskan In-app Billing API versi ("3), nama paket aplikasi yang memanggil, dan jenis pembelian ("inapp" atau "subs") ke metode.

Bundle ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);

Layanan Google Play hanya mengembalikan pembelian yang dibuat oleh akun pengguna yang sedang dalam proses masuk ke perangkat. Jika permintaan berhasil, Bundle yang dikembalikan memiliki kode respons 0. Bundle respons juga berisi daftar ID produk, daftar detail pesanan untuk setiap pembelian, dan tanda tangan untuk setiap pembelian.

Untuk meningkatkan kinerja, layanan Penagihan dalam Aplikasi hanya mengembalikan maksimal 700 produk yang dimiliki oleh pengguna saat getPurchase pertama kali dipanggil. Jika pengguna memiliki banyak sekali produk, Google Play akan menyertakan token String yang dipetakan ke INAPP_CONTINUATION_TOKEN kunci dalam Bundle respons untuk menunjukkan bahwa lebih banyak produk bisa diambil. Aplikasi Anda kemudian bisa membuat panggilan getPurchases lanjutan dan meneruskan token ini sebagai argumen. Google Play terus mengembalikan token lanjutan di Bundle respons sampai semua produk yang dimiliki oleh pengguna telah dikirimkan ke aplikasi Anda.

Untuk informasi selengkapnya tentang data yang dikembalikan oleh getPurchases, lihat Referensi Penagihan dalam Aplikasi. Contoh berikut menampilkan cara Anda bisa mengambil data ini dari respons.

int response = ownedItems.getInt("RESPONSE_CODE");
if (response == 0) {
   ArrayList<String> ownedSkus =
      ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
   ArrayList<String>  purchaseDataList =
      ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
   ArrayList<String>  signatureList =
      ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
   String continuationToken =
      ownedItems.getString("INAPP_CONTINUATION_TOKEN");

   for (int i = 0; i < purchaseDataList.size(); ++i) {
      String purchaseData = purchaseDataList.get(i);
      String signature = signatureList.get(i);
      String sku = ownedSkus.get(i);

      // do something with this purchase information
      // e.g. display the updated list of products owned by user
   }

   // if continuationToken != null, call getPurchases again
   // and pass in the token to retrieve more items
}

Mengonsumsi Pembelian

Anda bisa menggunakan In-app Billing Version 3 API untuk melacak kepemilikan produk dalam aplikasi di Google Play. Setelah produk dalam aplikasi dibeli, produk dianggap sebagai "dimiliki" dan tidak bisa dibeli dari Google Play. Anda harus mengirimkan permintaan konsumsi untuk produk dalam aplikasi sebelum Google Play membuatnya tersedia untuk dibeli lagi.

Penting: Produk dalam aplikasi terkelola bisa dikonsumsi, tetapi langganan tidak bisa.

Bagaimana Anda akan menggunakan mekanisme konsumsi di aplikasi adalah keputusan Anda sendiri. Umumnya, Anda akan mengimplementasikan konsumsi untuk produk dalam aplikasi dengan manfaat sementara yang mungkin ingin dibeli pengguna beberapa kali (misalnya, mata uang atau perlengkapan dalam game). Anda umumnya tidak ingin mengimplementasikan konsumsi untuk produk dalam aplikasi yang sekali beli dan menyediakan efek permanen (misalnya, peningkatan versi premium).

Untuk mencatat konsumsi pembelian, kirimkan metode consumePurchase ke layanan Penagihan dalam Aplikasi dan teruskan nilai String purchaseToken yang mengidentifikasi pembelian yang akan dibuang. purchaseToken adalah bagian data yang dikembalikan di String INAPP_PURCHASE_DATA oleh layanan Google Play setelah terjadi permintaan pembelian yang berhasil. Dalam contoh ini, Anda mencatat konsumsi produk yang diidentifikasi dengan purchaseToken di variabel token.

int response = mService.consumePurchase(3, getPackageName(), token);

Peringatan: Jangan panggil metode consumePurchase di thread utama. Memanggil metode ini akan memicu permintaan jaringan yang bisa memblokir thread utama Anda. Sebagai gantinya, buat thread terpisah dan panggil metode consumePurchase dari dalam thread tersebut.

Anda bertanggung jawab mengontrol dan melacak bagaimana produk dalam aplikasi disediakan kepada pengguna. Misalnya, jika pengguna membeli mata uang dalam game, Anda harus memperbarui inventaris pemain dengan jumlah mata uang yang dibeli.

Saran Keamanan: Anda harus mengirimkan permintaan konsumsi sebelum menyediakan manfaat pembelian dalam aplikasi yang bisa dikonsumsi kepada pengguna. Pastikan Anda telah menerima respons konsumsi yang berhasil dari Google Play sebelum Anda menyediakan item.

Mengimplementasikan Langganan

Meluncurkan alur pembelian untuk langganan mirip dengan meluncurkan alur pembelian untuk produk, dengan pengecualian jenis produk harus disetel ke "subs". Hasil pembelian dikirimkan ke metode onActivityResult Aktivitas Anda, tepat seperti di produk dalam aplikasi.

Bundle bundle = mService.getBuyIntent(3, "com.example.myapp",
   MY_SKU, "subs", developerPayload);

PendingIntent pendingIntent = bundle.getParcelable(RESPONSE_BUY_INTENT);
if (bundle.getInt(RESPONSE_CODE) == BILLING_RESPONSE_RESULT_OK) {
   // Start purchase flow (this brings up the Google Play UI).
   // Result will be delivered through onActivityResult().
   startIntentSenderForResult(pendingIntent, RC_BUY, new Intent(),
       Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));
}

Untuk melakukan kueri langganan aktif, gunakan metode getPurchases, lagi dengan parameter jenis produk ditetapkan ke "subs".

Bundle activeSubs = mService.getPurchases(3, "com.example.myapp",
                   "subs", continueToken);

Panggilan mengembalikan Bundle dengan semua langganan aktif yang dimiliki pengguna. Setelah langganan berakhir tanpa perpanjangan, langganan tidak lagi tampak di Bundle yang dikembalikan.

Mengamankan Aplikasi Anda

Untuk membantu memastikan integritas informasi transaksi yang dikirimkan ke aplikasi, Google Play menandatangani string JSON yang berisi data respons untuk pesanan pembelian (PO). Google Play menggunakan kunci pribadi yang dikaitkan dengan aplikasi Anda di Developer Console untuk membuat tanda tangan ini. Developer Console membuat pasangan kunci RSA untuk setiap aplikasi.

Catatan:Untuk menemukan bagian kunci publik dari pasangan kunci ini, buka detail aplikasi Anda di Developer Console, kemudian klik Services & APIs, dan lihat bidang berjudul Your License Key for This Application.

Kunci publik RSA berenkode Base64 yang dihasilkan oleh Google Play adalah berenkode biner, berformat X.509 subjectPublicKeyInfo DER SEQUENCE. Ini adalah kunci publik yang sama yang digunakan dengan lisensi Google Play.

Bila aplikasi Anda menerima respons bertanda tangan, Anda bisa menggunakan bagian kunci publik dari pasangan kunci RSA Anda untuk memverifikasi tanda tangan. Dengan melakukan verifikasi tanda tangan, Anda bisa mendeteksi respons yang telah diubah atau yang telah dipalsukan. Anda bisa menjalankan langkah verifikasi tanda tangan ini dalam aplikasi Anda; tetapi jika aplikasi Anda tersambung ke server jauh yang aman, kami sarankan agar Anda melakukan verifikasi tanda tangan di server tersebut.

Untuk informasi selengkapnya tentang praktik terbaik untuk keamanan dan desain, lihat Keamanan dan Desain.