Membuat transaksi langganan digital (Dialogflow)

Panduan ini menjelaskan cara menambahkan transaksi langganan digital ke Action percakapan, sehingga pengguna dapat membeli langganan Anda.

Istilah utama: Produk digital langganan adalah unit penyimpanan stok (SKU) yang memerlukan biaya berulang bagi pengguna, seperti majalah online. Hal ini berbeda dengan produk digital habis pakai yang harus dibeli ulang secara manual oleh pengguna, atau produk digital tidak habis pakai yang secara otomatis hanya dibeli satu kali.

Untuk informasi selengkapnya tentang langganan digital, lihat dokumentasi Android tentang fitur khusus langganan.

Pembatasan dan panduan peninjauan

Kebijakan tambahan berlaku untuk Action dengan transaksi. Kami membutuhkan waktu beberapa minggu untuk meninjau Action yang menyertakan transaksi, jadi pertimbangkan waktu tersebut saat merencanakan jadwal rilis Anda. Untuk memudahkan proses peninjauan, pastikan Anda mematuhi kebijakan dan panduan untuk transaksi sebelum mengirimkan Action untuk ditinjau.

Tindakan yang menjual produk digital hanya dapat di-deploy di negara berikut:

  • Australia
  • Brasil
  • Kanada
  • Indonesia
  • Jepang
  • Meksiko
  • Rusia
  • Singapura
  • Thailand
  • Turkiye
  • Inggris Raya
  • Amerika Serikat

Alur transaksi

Panduan ini menguraikan setiap langkah pengembangan saat terjadi dalam alur transaksi produk digital. Saat menangani transaksi untuk produk digital, Action Anda menggunakan alur berikut:

  1. Menyiapkan klien API pembelian digital: Action Anda menggunakan API pembelian digital untuk berkomunikasi dengan inventaris Google Play dan bertransaksi. Sebelum Action Anda melakukan hal lain, Action tersebut akan membuat klien JWT dengan kunci layanan untuk berkomunikasi dengan API pembelian digital.
  2. Mengumpulkan informasi: Action Anda mengumpulkan informasi dasar tentang pengguna dan inventaris Google Play untuk mempersiapkan transaksi.
    1. Validasi persyaratan transaksi: Action Anda menggunakan helper persyaratan transaksi digital di awal alur pembelian untuk memastikan pengguna dapat bertransaksi.
    2. Mengumpulkan inventaris yang tersedia: Action Anda memeriksa inventaris Google Play dan mengidentifikasi item yang saat ini tersedia untuk dibeli.
  3. Buat pesanan: Action Anda menampilkan produk digital yang tersedia kepada pengguna sehingga mereka dapat memilih salah satu untuk dibeli.
  4. Selesaikan pembelian: Action Anda menggunakan API pembelian digital untuk memulai pembelian dengan pilihan pengguna ke Google Play Store.
  5. Menangani hasilnya: Action Anda menerima kode status untuk transaksi dan memberi tahu pengguna bahwa pembelian berhasil (atau melakukan langkah tambahan).

Prasyarat

Sebelum memasukkan transaksi digital ke dalam Action, Anda memerlukan prasyarat berikut:

  • Akun developer dan akun penjual di Google Play, untuk mengelola produk digital Anda di konsol Google Play.

  • Domain web yang terverifikasi di Google Search Console. Domain ini tidak perlu dikaitkan dengan situs yang diluncurkan secara publik, kami hanya perlu mereferensikan domain web Anda.

  • Aplikasi Android dengan izin com.android.vending.BILLING di konsol Google Play. Produk digital Anda akan menjadi “pembelian dalam aplikasi” yang terkait dengan aplikasi ini di konsol Google Play.

    Anda juga perlu membuat rilis di konsol Play dengan aplikasi ini, tetapi jika tidak ingin rilis bersifat publik, Anda dapat membuat rilis alfa tertutup.

    Jika Anda belum memiliki aplikasi Android, ikuti petunjuk Mengaitkan Aplikasi Android.

  • Satu atau beberapa langganan di konsol Google Play, yang merupakan produk digital yang Anda jual dengan Action. Perlu diperhatikan bahwa Anda tidak dapat membuat langganan di konsol Play sebelum menyiapkan prasyarat aplikasi Android.

    Jika Anda belum memiliki langganan, ikuti petunjuk Membuat Produk Digital Anda.

Mengaitkan Aplikasi Android

Jika saat ini Anda belum memiliki aplikasi Android dengan izin penagihan di konsol Google Play, ikuti langkah-langkah berikut:

  1. Di Android Studio atau Android IDE pilihan Anda, buat project baru. Pilih opsi dalam perintah penyiapan project untuk membuat aplikasi yang sangat dasar.
  2. Beri nama paket untuk project, seperti com.mycompany.myapp. Jangan biarkan nama ini sebagai default, karena Anda tidak dapat mengupload paket yang menyertakan com.example ke konsol Play.
  3. Buka file AndroidManifest.xml aplikasi Anda.
  4. Tambahkan baris kode berikut di dalam elemen manifest:

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

    File AndroidManifest.xml Anda akan terlihat seperti blok kode berikut:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        package="com.mycompany.myapp">
        <uses-permission android:name="com.android.vending.BILLING" />
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme" />
    </manifest>
    
  5. Build aplikasi Anda sebagai APK yang ditandatangani. Di Android Studio, ikuti langkah-langkah berikut:

    1. Buka Build, Generate Signed Bundle / APK.
    2. Klik Next.
    3. Di bagian Key store path, klik Create new.
    4. Isi setiap kolom, lalu klik OK. Catat Sandi penyimpanan kunci dan Sandi kunci, dan simpan di tempat yang aman karena Anda akan menggunakannya nanti.
    5. Klik Next.
    6. Pilih rilis.
    7. Pilih V1 (Tanda Tangan JAR).
    8. Klik Selesai.
    9. Setelah beberapa detik, Android Studio akan membuat file app-release.apk. Temukan file ini untuk digunakan nanti.
  6. Di konsol Google Play, buat aplikasi baru.

  7. Buka Rilis aplikasi.

  8. Di bagian Jalur tertutup, buka Kelola, lalu Alfa.

  9. Klik tombol Buat Rilis.

  10. Di bagian Izinkan Google mengelola dan melindungi kunci penandatanganan Anda, masukkan informasi kunci penandatanganan Anda.

  11. Upload file APK Anda.

  12. Klik Simpan.

Membuat Produk Digital Anda

Jika saat ini Anda tidak memiliki produk digital di konsol Play, ikuti langkah-langkah berikut:

  1. Di konsol Google Play, buka Produk dalam aplikasi, lalu Langganan. Jika Anda melihat peringatan, ikuti petunjuk sebelumnya untuk membuat aplikasi Android atau klik link untuk membuat profil penjual.
  2. Klik Buat Langganan.
  3. Isi kolom untuk produk digital Anda. Catat ID Produk, yaitu cara Anda akan mereferensikan produk ini dari Action Anda.
  4. Klik Simpan.
  5. Ulangi langkah 2-4 untuk setiap produk yang ingin Anda jual.

Contoh langganan di konsol Google Play.

Menyiapkan project Action

Setelah produk digital disiapkan di konsol Google Play, Anda harus mengaktifkan transaksi digital dan mengaitkan project Action Anda dengan aplikasi Play.

Untuk mengaktifkan transaksi produk digital di project Action Anda, ikuti langkah-langkah berikut:

  1. Di Konsol Actions, buka project Anda atau buat project baru.
  2. Buka Deploy, lalu Directory information.
  3. Di bagian Informasi tambahan dan Transaksi, centang kotak Ya di bagian Apakah Action Anda menggunakan Digital Purchase API untuk melakukan transaksi produk digital.
  4. Klik Simpan.

Membuat kunci API produk digital

Untuk mengirim permintaan ke API produk digital, Anda perlu mendownload kunci akun layanan JSON yang terkait dengan project konsol Actions Anda.

Untuk mengambil kunci akun layanan, ikuti langkah-langkah berikut:

  1. Di konsol Actions, klik ikon tiga titik di sudut kanan atas, lalu Project settings.
  2. Temukan Project ID Action Anda.
  3. Klik link ini untuk mengganti "<project_id>" dengan ID project Anda: https://console.developers.google.com/apis/credentials?project=project_id
  4. Di navigasi utama, buka Credentials.
  5. Di halaman yang muncul, klik Create credentials, lalu Service account key.
  6. Buka Service Account, lalu klik New Service Account.
  7. Beri nama akun layanan seperti transaksi digital.
  8. Klik Create.
  9. Tetapkan Role ke Project > Owner.
  10. Klik Continue.
  11. Klik Buat Kunci.
  12. Pilih jenis kunci JSON.
  13. Klik Create key dan download kunci akun layanan JSON.

Simpan kunci akun layanan ini di tempat yang aman. Anda akan menggunakan kunci ini dalam fulfillment Anda guna membuat klien untuk API pembelian digital.

Menghubungkan ke inventaris Play

Untuk mengakses produk digital Anda dari project Action, kaitkan domain web dan aplikasi Anda dengan project Anda sebagai properti yang terhubung.

Catatan: Mungkin perlu waktu hingga satu minggu untuk menyelesaikan langkah-langkah penautan selagi kami memverifikasi properti Anda. Jika situs atau aplikasi Anda tidak ditautkan setelah jangka waktu tersebut, hubungi dukungan.

Untuk menghubungkan domain web dan aplikasi konsol Play ke project Action Anda, ikuti langkah-langkah berikut:

  1. Di Konsol Actions, buka Deploy, lalu Brand verification.
  2. Jika Anda belum menghubungkan properti, hubungkan situs terlebih dahulu:

    1. Klik tombol properti web (</>).
    2. Masukkan URL untuk domain web Anda, lalu klik Connect.

    Google akan mengirimkan email yang berisi petunjuk lebih lanjut kepada individu yang memverifikasi untuk domain web tersebut di Google Search Console. Setelah penerima email ini mengikuti langkah-langkah tersebut, situs akan muncul di bagian Verifikasi brand.

  3. Setelah memiliki setidaknya satu situs yang terhubung, lakukan langkah-langkah berikut untuk menghubungkan aplikasi Android Anda:

    1. Di Konsol Actions, buka Deploy, lalu Brand verification.
    2. Klik Hubungkan Aplikasi.
    3. Di halaman yang muncul, ikuti petunjuk untuk memverifikasi domain web Anda di konsol Play. Pilih aplikasi Play yang berisi produk digital Anda, lalu masukkan URL domain web persis seperti yang ditampilkan di halaman Verifikasi merek.

      Google akan mengirimkan email verifikasi sekali lagi kepada pemilik domain yang terverifikasi. Setelah mereka menyetujui verifikasi, aplikasi Play Anda akan muncul di bagian Verifikasi merek.

    4. Aktifkan Akses pembelian Play.

Gambar yang menampilkan situs dan aplikasi yang terhubung ke project Action.

Membuat alur pembelian

Setelah project Action dan inventaris produk digital Anda siap, bangun alur pembelian barang digital di webhook fulfillment percakapan Anda.

1. Menyiapkan klien API pembelian digital

Di webhook fulfillment percakapan, buat klien JWT dengan kunci JSON akun layanan dan cakupan https://www.googleapis.com/auth/actions.purchases.digital.

Kode Node.js berikut membuat klien JWT untuk API pembelian digital:

  const serviceAccount = {'my-file.json'};
  const request = require('request');
  const {google} = require('googleapis');

  const jwtClient = new google.auth.JWT(
    serviceAccount.client_email, null, serviceAccount.private_key,
    ['https://www.googleapis.com/auth/actions.purchases.digital'],
    null
  );

2. Mengumpulkan informasi

Sebelum pengguna dapat melakukan pembelian, Action Anda mengumpulkan informasi tentang kemampuan pengguna untuk melakukan pembelian dan barang yang tersedia dari inventaris.

2. a. Memvalidasi persyaratan transaksi

Sebaiknya pastikan akun pengguna disiapkan untuk melakukan transaksi, sebelum memberi mereka opsi untuk melakukan pembelian. Langkah ini termasuk memeriksa apakah pengguna telah mengonfigurasi metode pembayaran dan mereka menggunakan wilayah yang mendukung transaksi digital. Di awal alur transaksi, gunakan helper DIGITAL_PURCHASE_CHECK untuk memvalidasi konfigurasi transaksi pengguna dengan Asisten.

Kode Node.js berikut menggunakan DIGITAL_PURCHASE_CHECK di awal percakapan:

app.intent('Default Welcome Intent', async (conv, { SKU }) => {
  // Immediately invoke digital purchase check intent to confirm
  // purchase eligibility.
  conv.ask(new DigitalPurchaseCheck());
});

Temukan hasil pemeriksaan ini dalam argumen percakapan sebagai DIGITAL_PURCHASE_CHECK_RESULT. Berdasarkan hasil ini, lanjutkan alur transaksi atau beralih dan minta mereka untuk memeriksa konfigurasi Google Pay.

Kode Node.js berikut menangani hasil pemeriksaan persyaratan :

app.intent('Digital Purchase Check', async (conv) => {
  const arg = conv.arguments.get('DIGITAL_PURCHASE_CHECK_RESULT');
  if (!arg || !arg.resultType) {
    conv.close('Digital Purchase check failed. Please check logs.');
    return;
  }
  // User does not meet necessary conditions for completing a digital purchase
  if (arg.resultType === 'CANNOT_PURCHASE' || arg.resultType === 'RESULT_TYPE_UNSPECIFIED') {
    conv.close(`It looks like you aren't able to make digital purchases. Please check your Google Pay configuration and try again.`);
    return;
  }
  conv.ask('Welcome to the Digital Goods Sample. Would you like to see what I have for sale?');
});

2. b. Mengumpulkan inventaris yang tersedia

Gunakan API pembelian digital untuk meminta inventaris Play Store yang saat ini tersedia, lalu gabungkan ke dalam array objek JSON untuk setiap produk. Anda mereferensikan array ini nanti untuk menunjukkan kepada pengguna opsi yang tersedia untuk dibeli.

Setiap produk digital Anda direpresentasikan sebagai SKU dalam format JSON. Kode Node.js berikut menguraikan format yang diharapkan untuk setiap SKU:

body = {
  skus: [
    skuId: {
      skuType: one of "APP" or "UNSPECIFIED"
      id: string,
      packageName: string
    }
    formattedPrice: string,
    title: string,
    description: string
  ]
}

Kirim permintaan POST ke endpoint https://actions.googleapis.com/v3/packages/{packageName}/skus:batchGet, dengan {packageName} sebagai nama paket aplikasi Anda di Konsol Google Play (misalnya, com.myapp.digitalgoods), dan format hasilnya ke dalam array objek SKU.

Untuk hanya mengambil produk digital tertentu dalam array yang dihasilkan, cantumkan ID produk untuk produk digital (seperti yang ditunjukkan di bawah setiap produk dalam aplikasi di Konsol Google Play) yang ingin Anda sediakan untuk dibeli di body.ids.

Kode Node.js berikut meminta daftar barang yang tersedia dari API pembelian digital dan memformat hasilnya sebagai array SKU:

return jwtClient.authorize((err, tokens) => {
    if (err) {
      throw new Error(`Auth error: ${err}`);
    }

    const packageName = 'com.example.projectname';

    request.post(`https://actions.googleapis.com/v3/packages/${packageName}/skus:batchGet`, {
      'auth': {
        'bearer': tokens.access_token,
      },
      'json': true,
      'body': {
        'conversationId': conversationId,
        'skuType': 'APP',
        // This request is filtered to only retrieve SKUs for the following product IDs
        'ids': ['annual.subscription']
      },
    }, (err, httpResponse, body) => {
      if (err) {
        throw new Error(`API request error: ${err}`);
      }
      console.log(`${httpResponse.statusCode}: ${httpResponse.statusMessage}`);
      console.log(JSON.stringify(body));
    });
  });
});

3. Membuat pesanan

Untuk memulai pembelian digital pengguna, tunjukkan daftar produk digital Anda yang tersedia untuk dibeli. Anda dapat menggunakan berbagai jenis respons kaya untuk merepresentasikan stok Anda dan meminta pengguna untuk membuat pilihan.

Kode Node.js berikut membaca array inventaris objek SKU dan membuat respons daftar dengan satu item daftar untuk masing-masing:

skus.forEach((sku) => {
  const key = `${sku.skuId.skuType},${sku.skuId.id}`
  list.items[key] = {
    title: sku.title,
    description: `${sku.description} | ${sku.formattedPrice}`,
  };
});

4. Selesaikan pembelian

Untuk menyelesaikan pembelian, gunakan intent helper COMPLETE_PURCHASE dengan item yang dipilih pengguna.

Kode Node.js berikut menangani pilihan SKU pengguna dari respons daftar dan meminta intent COMPLETE_PURCHASE dengan informasi tersebut:

app.intent('Send Purchase', (conv, params, option) => {
  let [skuType, id] = option.split(',');

  conv.ask(new CompletePurchase({
    skuId: {
      skuType: skuType,
      id: id,
      packageName: <PACKAGE_NAME>,
    },
  }));
});

5. Menangani hasil

Setelah pembelian selesai, pembelian akan memicu peristiwa Dialogflow actions_intent_COMPLETE_PURCHASE (atau intent Action SDK actions.intent.COMPLETE_PURCHASE) dengan argumen COMPLETE_PURCHASE_VALUE yang menjelaskan hasilnya. Membuat intent, yang dipicu oleh peristiwa ini, yang memberitahukan hasilnya kepada pengguna.

Tangani kemungkinan hasil pembelian berikut:

  • PURCHASE_STATUS_OK: Pembelian berhasil. Transaksi selesai pada tahap ini, jadi keluar dari alur transaksi dan beralih kembali ke percakapan Anda.
  • PURCHASE_STATUS_ALREADY_OWNED: Transaksi gagal karena pengguna sudah memiliki item tersebut. Hindari error ini dengan memeriksa pembelian sebelumnya pengguna dan menyesuaikan item yang ditampilkan agar tidak memiliki opsi untuk membeli kembali item yang sudah dimiliki.
  • PURCHASE_STATUS_ITEM_UNAVAILABLE: Transaksi gagal karena item yang diminta tidak tersedia. Hindari error ini dengan memeriksa SKU yang tersedia saat mendekati waktu pembelian.
  • PURCHASE_STATUS_ITEM_CHANGE_REQUESTED: Transaksi gagal karena pengguna memutuskan untuk membeli hal lain. Mintalah ulang dengan membuat pesanan agar pengguna dapat segera membuat keputusan lain.
  • PURCHASE_STATUS_USER_CANCELLED: Transaksi gagal karena pengguna membatalkan alur pembelian. Karena pengguna keluar dari alur sebelum waktunya, tanyakan kepada pengguna apakah mereka ingin mencoba kembali transaksi atau keluar dari transaksi.
  • PURCHASE_STATUS_ERROR: Transaksi gagal karena alasan yang tidak diketahui. Beri tahu pengguna bahwa transaksi gagal, dan tanyakan apakah mereka ingin mencoba lagi.
  • PURCHASE_STATUS_UNSPECIFIED: Transaksi gagal karena alasan yang tidak diketahui, sehingga menghasilkan status yang tidak diketahui. Tangani status error ini dengan memberi tahu pengguna bahwa transaksi gagal, dan tanyakan apakah mereka ingin mencoba lagi.

Kode Node.js berikut membaca argumen COMPLETE_PURCHASE_VALUE dan menangani setiap hasil:

app.intent('Purchase Result', (conv) => {
  const arg = conv.arguments.get('COMPLETE_PURCHASE_VALUE');
  console.log('User Decision: ' + JSON.stringify(arg));
  if (!arg || !arg.purchaseStatus) {
    conv.close('Purchase failed. Please check logs.');
    return;
  }
  if (arg.purchaseStatus === 'PURCHASE_STATUS_OK') {
    conv.close(`Purchase completed! You're all set!`);
  } else if (arg.purchaseStatus === 'PURCHASE_STATUS_ALREADY_OWNED') {
    conv.close('Purchase failed. You already own this item.');
  } else if (arg.purchaseStatus === 'PURCHASE_STATUS_ITEM_UNAVAILABLE') {
    conv.close('Purchase failed. Item is not available.');
  } else if (arg.purchaseStatus === 'PURCHASE_STATUS_ITEM_CHANGE_REQUESTED') {
    // Reprompt with your item selection dialog
  }  else {
    conv.close('Purchase Failed:' + arg.purchaseStatus);
  }
});

Mencerminkan pembelian pengguna

Saat pengguna membuat kueri Action Anda, objek user JSON permintaan akan menyertakan daftar pembelian mereka. Periksa informasi ini dan ubah respons Action Anda berdasarkan konten yang telah dibayar pengguna.

Kode contoh berikut menunjukkan objek user permintaan yang menyertakan packageEntitlements pembelian dalam aplikasi sebelumnya yang mereka lakukan untuk paket com.digitalgoods.application:

  "user": {
    "userId": "xxxx",
    "locale": "en-US",
    "lastSeen": "2018-02-09T01:49:23Z",
    "packageEntitlements": [
      {
        "packageName": "com.digitalgoods.application",
        "entitlements": [
          {
            "sku": "non-consumable.1",
            "skuType": "APP"
          }
          {
            "sku": "consumable.2",
            "skuType": "APP"
          }
        ]
      },
      {
        "packageName": "com.digitalgoods.application",
        "entitlements": [
          {
            "sku": "annual.subscription",
            "skuType": "SUBSCRIPTION",
            "inAppDetails": {
              "inAppPurchaseData": {
                "autoRenewing": true,
                "purchaseState": 0,
                "productId": "annual.subscription",
                "purchaseToken": "12345",
                "developerPayload": "HSUSER_IW82",
                "packageName": "com.digitalgoods.application",
                "orderId": "GPA.233.2.32.3300783",
                "purchaseTime": 1517385876421
              },
              "inAppDataSignature": "V+Q=="
            }
          }
        ]
      }
    ]
  },
  "conversation": {
    "conversationId": "1518141160297",
    "type": "NEW"
  },
  "inputs": [
    {
      "intent": "actions.intent.MAIN",
      "rawInputs": [
        {
          "inputType": "VOICE",
          "query": "Talk to My Test App"
        }
      ]
    }
  ],
  ...
}