建構消耗性數位交易 (Dialogflow)

本指南說明如何在對話中新增數位交易 採取行動,讓使用者能夠購買您的消耗性數位商品。

重要詞彙:「消耗性」數位商品是庫存管理單位 (SKU), 使用者可以使用並重複購買,例如指定數量的遊戲代幣 那就是 Android 遊戲這項數位商品與非消耗性產品不同 也就是使用者只能購買一次的數位商品

如要進一步瞭解一次性產品,請參閱 Android 說明文件 一次性產品專屬功能

限制和評論規範

其他政策適用於「含有交易的動作」。這可能需要一些 並考量包含交易的動作 規劃發布時間表為了減輕審查程序,請務必遵守 使用 交易政策與規範 ,再將動作送交審查。

銷售數位商品的動作只能在下列國家/地區部署:

  • 澳洲
  • 巴西
  • 加拿大
  • 印尼
  • 日本
  • 墨西哥
  • 俄羅斯
  • 新加坡
  • 泰國
  • 土耳其
  • 英國
  • 美國
,瞭解如何調查及移除這項存取權。

交易流程

本指南將概述數位商品中發生的所有開發步驟 交易流程當您的動作處理數位商品交易時, 使用下列流程:

  1. 設定數位購買交易 API 用戶端:您的動作使用數位版 購買 API,以便與 Google Play 庫存和交易通訊。 在您執行其他動作之前,系統會先建立 JWT 用戶端, 服務金鑰來與 Digital Purchases API 通訊
  2. 收集資訊:您的動作會收集 和 Google Play 廣告空間,為交易做好萬全準備。
    1. 驗證交易規定:您的動作使用的是數位版 交易需求協助 確保使用者能夠完成交易
    2. 收集可用廣告空間:您的動作會檢查 Google Play 辨識目前可供購買的商品
  3. 建立訂單:您的動作會顯示可用的數位商品: 讓使用者選擇要購買的商品。
  4. 完成購買:您的動作會使用數位購買 API, 在使用者從 Google Play 商店選擇商品時開始購物。
  5. 處理結果:您的動作會收到 交易,並通知使用者該購買成功 (或 其他步驟)。
  6. 進行可重複購買的動作:您的動作使用數位交易。 「使用」的 API客戶購買的商品,接著即可購買該商品 該使用者再次使用服務

必要條件

將數位交易納入動作之前,您需要具備 幾項先決條件

連結 Android 應用程式

如果您還沒有具備帳單權限的 Android 應用程式, Google Play 管理中心,請按照下列步驟操作:

  1. Android Studio 或 即可建立新專案選擇以下其中一種語言: 專案設定提示會建立一個非常基本的應用程式
  2. 為專案指定套件名稱,例如 com.mycompany.myapp。 請勿讓此名稱保持預設值,因為您無法上傳 請在 Play 管理中心加入 com.example
  3. 開啟應用程式的 AndroidManifest.xml 檔案。
  4. manifest 元素中加入這行程式碼:

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

    您的 AndroidManifest.xml 檔案應如下所示:

    <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. 將應用程式建構為已簽署的 APK。在 Android Studio 中,按照下列步驟操作:

    1. 依序前往「Build」和「Generate Signed Bundle / APK」
    2. 點選「下一步」。
    3. 在「Key store path」下方,點選「Create new」
    4. 填寫每個欄位,然後按一下「確定」。請記下「KeyStore」 金鑰密碼,並將這些密碼儲存在安全的地方,因為 您稍後會用到這些內容
    5. 點選「下一步」。
    6. 選取「release」
    7. 選取「V1 (JAR Signature)」
    8. 按一下 [完成]。
    9. 幾秒後,Android Studio 會產生 app-release.apk 檔案。 找出這個檔案供日後使用。
  6. Google Play 管理中心 建立新的應用程式

  7. 前往「應用程式版本」

  8. 在「封閉式測試群組」下方,依序前往「管理」和「Alpha 版」

  9. 按一下「Create Release」按鈕。

  10. 在「讓 Google 管理及保護簽署金鑰」下方,輸入您的簽署憑證 重要資訊。

  11. 上傳 APK 檔案。

  12. 按一下 [儲存]

建立數位商品

如果您在 Play 管理中心目前沒有數位商品,請按照下列指示操作 步驟:

  1. Google Play 管理中心 依序前往「應用程式內商品」和「受管理的產品」。如果看到警告訊息 請按照前述操作說明建立 Android 應用程式,或按一下連結 即可建立商家檔案。
  2. 按一下「建立納入管理的產品」
  3. 填寫數位產品的欄位。記下產品 ID 這就是你在動作中參照這項產品的方式
  4. 按一下 [儲存]
  5. 針對您要銷售的每項產品,重複執行步驟 2 到 4。

Google Play 管理中心的消耗性商品示例。

準備 Actions 專案

在 Google Play 管理中心設定數位商品後,您必須啟用 將您的 Actions 專案與 Play 應用程式建立關聯。

如要在 Actions 專案中啟用數位商品交易功能,請按照下列步驟操作 步驟:

  1. Actions 主控台中開啟專案或建立新專案。
  2. 依序前往「部署」和「目錄資訊」
  3. 在「其他資訊」和「交易」下方,勾選「是」方塊 「您的動作是否使用 Digital Purchase API 執行交易」 數位商品
  4. 按一下 [儲存]

建立數位商品 API 金鑰

如要將要求傳送至 Digital Good API,您必須下載 JSON 服務 帳戶金鑰。

如要擷取服務帳戶金鑰,請按照下列步驟操作:

  1. 在「動作控制台」中,按一下右上角的三點圖示。 和「專案設定」
  2. 找出動作的專案 ID
  3. 請前往這個連結,取代「<project_id>」替換為您的專案 ID: https://console.developers.google.com/apis/credentials?project=project_id
  4. 在主要導覽選單中,前往「憑證」
  5. 在顯示的頁面中,依序點選「建立憑證」和「服務」。 帳戶金鑰。
  6. 前往「Service Account」,然後按一下「New Service Account」
  7. 為服務帳戶命名,例如數位交易。
  8. 按一下「建立」
  9. 角色設定為 專案 >擁有者
  10. 按一下「繼續」
  11. 按一下 [Create Key] (建立金鑰)
  12. 選取「JSON」JSON金鑰類型。
  13. 按一下「建立金鑰」,然後下載 JSON 服務帳戶金鑰。

請將這個服務帳戶金鑰儲存在安全的地方,您將在 的執行要求,建立 Digital Purchase API 的用戶端。

連結至 Play 廣告空間

如要透過 Actions 專案存取您的數位商品,請將 連結為專案的網域和應用程式 連結資源

注意:我們正在驗證連線步驟,這項作業最多可能需要一週才能完成 。如果您在期限過後仍未連結網站或應用程式, 與支援團隊聯絡

如要將 Play 管理中心的網頁網域和應用程式連結至 Actions 專案,請按照下列步驟操作: 步驟如下:

  1. 動作控制台中,依序前往「部署」和「品牌驗證」
  2. 如果尚未連結任何資源,請先連結網站:

    1. 按一下網站資源 (&lt;/&gt;) 按鈕。
    2. 輸入你的網域網址,然後按一下「連結」

    Google 會傳送電子郵件給 進行驗證 Google Search Console。 收到這封電子郵件的使用者完成這些步驟後,網站應該 「品牌驗證」底下。

  3. 擁有至少一個連結網站後,請執行下列步驟, 連結您的 Android 應用程式:

    1. 動作控制台中,依序前往「部署」和「品牌驗證」
    2. 按一下 [連結應用程式]
    3. 在隨即顯示的頁面中,按照操作說明驗證您的網路 網域。選取哪個 Play 應用程式? 然後輸入「數位商品」中顯示的網域網址 「品牌驗證」頁面。

      Google 再次寄送驗證電子郵件給已驗證的擁有者 網域。管理員核准驗證後,您的 Play 應用程式應該就會 「品牌驗證」底下。

    4. 啟用「存取 Play 購買項目」

圖片:顯示與 Actions 專案連結的網站和應用程式。

建立購買流程

備妥 Actions 專案和數位商品清單後,請建立數位 商品購買流程。

1. 設定 Digital Purchases API 用戶端

在對話執行要求 Webhook 中,透過服務建立 JWT 用戶端 帳戶 JSON 金鑰和 https://www.googleapis.com/auth/actions.purchases.digital 範圍。

下列 Node.js 程式碼會建立數位購買 API 的 JWT 用戶端:

  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. 收集資訊

動作會在使用者購物前,收集 使用者能否購物,以及他們提供哪些商品 廣告空間。

2. a.驗證交易需求條件

建議您確認使用者帳戶是否已完成設定 交易,再提供購買選項。這個步驟 包括檢查使用者是否已設定付款方式, 支援數位交易的語言代碼。交易開始時 流程,使用 DIGITAL_PURCHASE_CHECK 輔助程式驗證使用者的交易 您需要先完成相關設定

下列 Node.js 程式碼在DIGITAL_PURCHASE_CHECK 對話:

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

在對話引數中找出這個檢查的結果,如下所示: DIGITAL_PURCHASE_CHECK_RESULT。根據這個結果, 或在交易流程中提示對方查看 Google Pay 此外還會從 0 自動調整資源配置 您完全不必調整資源調度設定

下列 Node.js 程式碼會處理需求檢查結果:

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.收集可用的廣告空間

使用 Digital Purchase API 要求你目前使用的 Play 商店 庫存量,然後將該參數建立成 JSON 物件陣列為每個產品建立 您稍後可以參照這個陣列,向使用者顯示可用的選項 購買。

您的每項數位商品都會以 JSON 格式以 SKU 表示。 以下 Node.js 程式碼概述每個 SKU 的預期格式:

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

傳送 POST 要求至 https://actions.googleapis.com/v3/packages/{packageName}/skus:batchGet 端點,其中 {packageName} 是應用程式在 Google Play 中的套件名稱 控制台 (例如 com.myapp.digitalgoods),並將結果格式化為 SKU 物件陣列。

如果只想在結果陣列中擷取特定數位商品,請列出產品 數位商品的 ID (顯示在 Google Play 中各項應用程式內產品下方 控制台),藉此在 body.ids 中開放購買。

下列 Node.js 程式碼會要求數位商品列出可用的商品清單 購買 API 並將結果格式化為 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': ['consumable.1']
      },
    }, (err, httpResponse, body) => {
      if (err) {
        throw new Error(`API request error: ${err}`);
      }
      console.log(`${httpResponse.statusCode}: ${httpResponse.statusMessage}`);
      console.log(JSON.stringify(body));
    });
  });
});

3. 建立訂單

如要開始使用者的數位商品,請列出你的數位商品 方便購買您可以使用各式各樣的 多元的回應類型來代表 並提示使用者做出選擇

以下 Node.js 程式碼會讀取 SKU 物件的庫存陣列,並建立 包含以下項目的清單項目:清單回應 每個:

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

4. 完成購買程序

如要完成購買程序,請搭配以下參數使用 COMPLETE_PURCHASE 輔助意圖: 使用者選取的項目

以下 Node.js 程式碼會處理使用者在清單回應中選取的 SKU 然後要求含有該資訊的 COMPLETE_PURCHASE 意圖:

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. 處理結果

購買完成後會觸發 actions_intent_COMPLETE_PURCHASE Dialogflow 事件 (或 actions.intent.COMPLETE_PURCHASE Actions SDK 意圖),其中包含 說明結果的 COMPLETE_PURCHASE_VALUE 引數。建立意圖 以便將結果傳送給使用者。

處理下列可能的購買結果:

  • PURCHASE_STATUS_OK:購買成功。交易 就完成了,因此請在交易流程中返回 或對話。
  • PURCHASE_STATUS_ALREADY_OWNED:交易失敗,因為使用者 已有該項目請查看使用者的上一個 也無法自行調整顯示的商品 回購他們現有的商品
  • PURCHASE_STATUS_ITEM_UNAVAILABLE:交易失敗,因為 無法提供要求的項目。檢查可用空間來避免這個錯誤 更接近購買時間的 SKU。
  • PURCHASE_STATUS_ITEM_CHANGE_REQUESTED:交易失敗,因為 使用者決定購買其他商品時再次提出訂單建立程序 讓使用者可以立即做出決定。
  • PURCHASE_STATUS_USER_CANCELLED:交易失敗,因為使用者 已取消購買流程。由於使用者過早退出流程,因此可以提問 使用者想重試交易或結束交易時 以致於可能必須趕在最後一刻 大幅更動專案,甚至將專案全部取消
  • PURCHASE_STATUS_ERROR:交易失敗,原因不明。請 使用者知道交易失敗,並詢問是否要再試一次。
  • PURCHASE_STATUS_UNSPECIFIED:交易失敗,原因不明, 導致狀態不明允許使用者處理這個錯誤狀態 確認交易失敗,並詢問對方是否要再試一次。

以下 Node.js 程式碼會讀取 COMPLETE_PURCHASE_VALUE 引數,並 會處理每項結果:

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

6. 提供可重複購買的交易

使用 Digital Purchase API 要求你目前使用的 Play 商店 庫存量,然後將該參數建立成 JSON 物件陣列為每個產品建立 您稍後可以參照這個陣列,向使用者顯示可用的選項 購買。

您的每項數位商品都會以 JSON 格式以 SKU 表示。 以下 Node.js 程式碼概述每個 SKU 的預期格式:

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

傳送 POST 要求至 https://actions.googleapis.com/v3/packages/{packageName}/skus:batchGet 端點,其中 {packageName} 是應用程式在 Google Play 中的套件名稱 控制台 (例如 com.myapp.digitalgoods),並將結果格式化為 SKU 物件陣列。

如果只想在結果陣列中擷取特定數位商品,請列出產品 數位商品的 ID (顯示在 Google Play 中各項應用程式內產品下方 控制台),藉此在 body.ids 中開放購買。

下列 Node.js 程式碼會要求數位商品列出可用的商品清單 購買 API 並將結果格式化為 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': ['consumable.1']
      },
    }, (err, httpResponse, body) => {
      if (err) {
        throw new Error(`API request error: ${err}`);
      }
      console.log(`${httpResponse.statusCode}: ${httpResponse.statusMessage}`);
      console.log(JSON.stringify(body));
    });
  });
});

反映使用者的購買交易

當使用者查詢您的動作時,要求 JSON 的 user 物件會包含一份清單。 金額。請查看這項資訊,並變更動作的回應 能夠根據使用者付費購買的內容 調整至高比例

以下範例程式碼顯示要求的 user 物件,其中包含 他們過去 packageEntitlements 的應用程式內購 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"
        }
      ]
    }
  ],
  ...
}