构建消耗型数字交易

本指南介绍了如何将数字交易添加到对话式对话中, 使用户可以购买您的消耗型数字商品。

关键术语:消耗型数字商品是指库存量单位 (SKU), 用户可以多次使用和购买,例如一定数量的游戏代币 是 Android 游戏的理想平台此数字商品与非消耗品不同 用户只能购买一次的数字商品

有关消耗型一次性商品的详情,请参阅 Android 关于 一次性商品专用功能

交易流程

本指南概述了数字商品中涉及的每个开发步骤 交易流程当您的 Action 处理数字商品交易时,它 采用以下流程:

  1. 设置数字购买 API 客户端:您的 Action 会使用数字 购买 API 与您的 Google Play 广告资源进行通信并进行交易。 在您的 Action 执行任何其他操作之前,它会创建一个具有 与数字购买 API 通信的服务密钥。
  2. 收集信息:您的 Action 会收集有关 用户和 Google Play 广告资源来为交易做准备
    1. 验证交易要求:您的 Action 使用数字 交易要求帮助程序(在购买流程开始时提供) 确保用户能够进行交易
    2. 收集可用的广告资源:您的 Action 检查您的 Google Play 广告资源,并确定当前可供购买的商品。
  3. 构建订单:您的 Action 会向用户展示可用的数字商品 以便用户选择一个商品进行购买。
  4. 完成购买:您的 Action 会使用 digitalPurchases API 来 通过用户从 Google Play 商店中选择的内容发起购买。
  5. 处理结果:您的 Action 会收到 并通知用户购买成功 其他步骤)。
  6. 确保购买交易可重复:您的 Action 会使用数字购买交易 通过 API 来“使用”使该商品可供购买 再次执行相应操作

限制和查看指南

其他政策适用于涉及交易的操作。这可能需要 查看包含交易的操作数,因此请将这一时间因素考虑在内 规划发布时间表。为了简化审核流程,请确保您符合 替换为 交易政策和准则 然后再提交 Action 以供审核。

销售数字商品的操作只能在以下国家/地区部署:

  • 澳大利亚
  • 巴西
  • 加拿大
  • 印度尼西亚
  • 日本
  • 墨西哥
  • 俄罗斯
  • 新加坡
  • 泰国
  • 土耳其
  • 英国
  • 美国

前提条件

在将数字交易纳入你的 Action 之前,你需要 以下前提条件:

关联 Android 应用

如果您目前没有拥有结算权限的 Android 应用 Google Play 管理中心,请按以下步骤操作:

  1. Android Studio 中或 选择 Android IDE,创建一个新项目。选择以下选项: 项目设置提示创建一个非常基本的应用。
  2. 为项目指定软件包名称,例如 com.mycompany.myapp。 请勿将此名称保留为默认值, 将 com.example 添加到 Play 管理中心。
  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. 依次前往 BuildGenerate Signed Bundle / APK
    2. 点击下一步
    3. Key store path 下,点击 Create new
    4. 填写每个字段,然后点击 OK。记下您的密钥库 密码密钥密码,并妥善保存,因为 稍后会用到它们
    5. 点击下一步
    6. 选择发布
    7. 选择 V1 (JAR Signature)
    8. 点击完成
    9. 几秒钟后,Android Studio 会生成一个 app-release.apk 文件。 找到此文件以供稍后使用。
  6. Google Play 管理中心、 创建新应用。

  7. 前往应用版本页面。

  8. 封闭式轨道下,依次前往管理Alpha 版

  9. 点击创建版本按钮。

  10. 让 Google 管理和保护您的签名密钥下方,输入您的签名 关键信息

  11. 上传 APK 文件。

  12. 点击保存

创建你的数字商品

如果您当前在 Play 管理中心内没有任何数字商品,请按以下方法操作 步骤:

  1. Google Play 管理中心、 依次点击应用内商品受管理的商品。如果您看到警告 按照上述说明创建 Android 应用,或点击链接 创建商家资料。
  2. 点击创建受管理的商品
  3. 填写数字商品对应的字段。记下产品 ID 这就是您在 Action 中引用此商品的方式。
  4. 点击保存
  5. 针对您要销售的每件商品重复第 2-4 步。

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

准备 Actions 项目

在 Google Play 管理中心内设置数字商品后,您必须启用 进行数字交易,并将您的 Actions 项目与您的 Play 应用相关联。

设置

如需在 Actions 项目中启用数字商品交易,请按以下步骤操作: 步骤:

  1. Actions 控制台中,打开你的项目或创建一个新项目。
  2. 转到部署,然后选择目录信息
  3. 其他信息交易下,选中复选框 在您的 Action 会使用 Digital Purchase API 执行交易吗? 数字商品”
  4. 点击保存

创建数字商品 API 密钥

如需向数字商品 API 发送请求,您需要下载 JSON 服务 与 Actions 控制台项目关联的账号密钥。

如需检索您的服务账号密钥,请按以下步骤操作:

  1. Actions 控制台中,点击右上角的三点状图标。 然后选择项目设置
  2. 找到 Action 的 Project ID
  3. 访问此链接,替换“<project_id>”替换为您的项目 ID: https://console.developers.google.com/apis/credentials?project=project_id
  4. 在主导航栏中,前往凭据
  5. 在显示的页面上,点击创建凭据,然后点击服务 账号密钥
  6. 转到服务账号,然后点击新的服务账号
  7. 为服务账号命名,例如 digitaltransactions。
  8. 点击创建
  9. 角色设置为项目 >所有者
  10. 点击继续
  11. 点击创建密钥
  12. 选择 JSON 密钥类型。
  13. 点击创建密钥并下载 JSON 服务账号密钥。

请妥善保存此服务账号密钥。您将在自己的 执行方式为 DigitalPurchases API 创建客户端。

关联到您的 Play 广告资源

为了从 Actions 项目访问您的数字商品,您需要将您的 域名和应用 关联的媒体资源

如需将 Play 管理中心网站网域和应用关联到 Actions 项目,请按以下步骤操作: 具体步骤:

  1. Actions 控制台中,依次点击部署品牌验证
  2. 如果您尚未关联任何媒体资源,请先关联网站:

    1. 点击网络媒体资源 (&lt;/&gt;) 按钮。
    2. 输入您网域的网址,然后点击连接

    Google 会向 已在 Google Search Console。 这封电子邮件的收件人完成上述步骤后,网站应该就会 品牌验证下会显示相应信息。

  3. 您至少关联了一个网站后,请执行以下步骤 关联您的 Android 应用:

    1. Actions 控制台中,依次点击部署品牌验证
    2. 点击关联应用
    3. 在随即显示的页面上,按照说明验证网站 登录该网域选择包含 数字商品,然后输入与 品牌验证页面。

      Google 会再次向以下经过验证的所有者发送验证电子邮件: 网域。他们批准验证后,您的 Play 应用应该 品牌验证下会显示相应信息。

    4. 启用访问 Play 购买交易

显示已关联到 Actions 项目的网站和应用的图片。

构建购买流程

准备好 Actions 项目和数字商品清单后,构建数字商品 商品购买流程。

1. 设置数字购买 API 客户端

在对话 fulfillment 网络钩子中,使用您的服务创建一个 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. 收集信息

您的 Action 会收集有关 用户购买行为的能力以及可通过 Google 地图购买哪些商品 广告资源。

2. a.验证数字购买要求

最好确保用户的账号设置妥当 然后再让他们选择购买您应该 过渡到 DigitalPurchaseCheck 场景,这会检查用户是否已通过验证, 确认是在允许的平台(智能显示屏、 智能音箱或 Android 设备),并且它们所在的语言区域支持数字设备 交易

如需创建数字商品购买检查场景,请按以下步骤操作:

  1. Scenes 标签页中,添加一个名为 DigitalPurchaseCheck 的新场景。
  2. 槽填充下,点击 + 以添加新槽。
  3. 选择类型下,选择 actions.type.DigitalPurchaseCheckResult 作为 广告位类型。
  4. 在槽名称字段中,将槽命名为 DigitalPurchaseCheck
  5. 选中自定义槽值回写复选框(默认处于启用状态)。
  6. 点击保存

数字购买交易检查会产生以下结果之一:

  • 如果满足这些要求,系统就会成功设置会话参数 条件,您可以继续允许用户购买数字商品。
  • 如果不能满足一项或多项要求,则会话参数为 带有失败条件的集合。在这种情况下,您应围绕 或结束对话。

如需处理 Digital Purchase 的检查结果,请按以下步骤操作:

  1. Scenes 标签页中,选择您新创建的 DigitalPurchaseCheck 场景。
  2. 条件下,点击 + 以添加新条件。
  3. 在文本字段中,输入以下条件语法,以检查 成功条件:

    scene.slots.status == "FINAL" && session.params.DigitalPurchaseCheck.resultType == "CAN_PURCHASE"
    
  4. 将光标悬停在您刚刚添加的条件上,然后点击向上箭头 并将其放置在 if scene.slots.status == "FINAL" 之前。

  5. 启用 Send prompts,并提供简单的提示让用户知道 他们已准备好进行交易:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                You are ready to purchase digital goods.
    
  6. 过渡下选择其他场景,以便用户继续操作 对话并继续进行交易。

  7. 选择条件 else if scene.slots.status == "FINAL"

  8. 启用 Send prompts,并提供简单的提示让用户知道 他们无法进行交易:

    candidates:
      - first_simple:
          variants:
            - speech: Sorry you cannot perform a digital purchase.
    
  9. 转换下,选择结束对话以结束对话。

2.收集可用的广告资源

使用数字购买 API 请求您当前可用的 Play 商店 然后针对每个商品将其构建为 JSON 对象数组。 您稍后引用此数组以向用户显示可用的选项 供用户购买

您的每个数字商品都表示为一个 JSON 格式的 SKU。通过 以下 Node.js 代码概述了每个 SKU 的预期格式:

body = {
  skus: [
    skuId: {
      skuType: one of "SKU_TYPE_IN_APP" or "SKU_TYPE_SUBSCRIPTION"
      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': conv.session.id,
        'skuType': 'SKU_TYPE_IN_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 对象的库存数组,并创建 列出响应,其中包含一个用于 :

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

conv.session.typeOverrides = [{
   name: 'type_name',
   mode: 'TYPE_REPLACE',
   synonym: {
       entries: entries
   }
}];

conv.add(new List({
   title: 'List title',
   subtitle: 'List subtitle',
   items: items,
}));

根据用户选择创建购买交易

用户选择商品后,您就可以创建订单了。为此,在 与选定项关联的槽位,您可以向网络钩子发出调用 创建订单在履单中,将订单数据保存到会话 参数。该顺序对象会用于同一会话的各个场景。

conv.session.params.purchase = {
  "@type": "type.googleapis.com/google.actions.transactions.v3.CompletePurchaseValueSpec",
  "skuId": {
    "skuType": "<SKU_TYPE_IN_APP>",
    "id": "<SKU_ID>",
    "packageName": "<PACKAGE_NAME>"
  },
  "developerPayload": ""
};

在 Actions Builder 中,您可以改用 JSON 编辑器来配置槽位 替换为上述订单对象。这两种实现使用相同的格式 CompletePurchaseValueSpec,您可以在 JSON webhook 载荷参考

4. 完成购买

用户选择商品后,您就可以完成购买了。填写完 与所选内容关联的两个广告位时,您应过渡到 执行完整的购买操作。

创建完整的购买场景

  1. Scenes 标签页中,添加一个名为 CompletePurchase 的新场景。
  2. 槽填充下,点击 + 以添加新槽。
  3. 选择类型下,选择 actions.type.CompletePurchaseValue 作为 广告位类型。
  4. 在槽名称字段中,将槽命名为 CompletePurchase
  5. 选中自定义槽值回写复选框(默认处于启用状态)。
  6. 配置槽下,从下拉菜单中选择 Use session parameter
  7. 配置槽下,输入用于配置槽的会话参数的名称 将订单存储到文本字段中(即 $session.params.purchase)。
  8. 点击保存

5. 处理结果

类型为 actions.type.CompletePurchaseValue 的槽可以具有以下特征 结果:

  • 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:交易因未知原因而失败, 导致出现未知状态。处理此错误状态的方法是让 用户知道交易失败,并询问是否要重试。

您应在 CompletePurchase 场景中处理所有这些结果。

  1. Scenes 标签页中,选择您新创建的 CompletePurchase 场景。
  2. 条件下,点击 + 以添加新条件。
  3. 在文本字段中,输入以下条件语法,以检查 成功条件:

    scene.slots.status == "FINAL" && session.params.CompletePurchase.purchaseStatus == "PURCHASE_STATUS_OK"
    
  4. 将光标悬停在您刚刚添加的条件上,然后点击向上箭头 并将其放置在 if scene.slots.status == "FINAL" 之前。

  5. 启用 Send prompts,并提供简单的提示让用户知道 他们已准备好进行交易:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Your purchase was successful.
    
  6. 转换下,选择结束对话以结束对话。

针对您希望支持的每种购买结果重复执行上述步骤。

6. 使购买交易可重复

交易成功后,向数字购买交易发送 POST 请求 API 消耗商品,让用户可再次购买。发送您的 向 https://actions.googleapis.com/v3/conversations/{sessionId}/entitlement:consume 发送请求 端点替换为在 session.id 中找到的会话 ID。

您的 POST 请求还必须包含与 用户的购买信息,该信息可在用户请求 JSON 下的 packageEntitlements.entitlements.inAppDetails.inAppPurchaseData.purchaseToken

以下代码会向数字购买 API 发送 consume 请求,并 报告该请求是否成功:

request.post(`https://actions.googleapis.com/v3/conversations/${conv.session.id}/entitlement:consume`, {
  'auth': {
    'bearer': tokens.access_token,
  },
  'json': true,
  'body': {
  // This purchase token is in both the purchase event and the user's entitlements
  // in their request JSON
    "purchaseToken": entitlement.purchaseToken
  },
  }, (err, httpResponse, body) => {
    if (err) {
     throw new Error(`API request error: ${err}`);
    }
  console.log(`${httpResponse.statusCode}: ${httpResponse.statusMessage}`);
  console.log(JSON.stringify(httpResponse));
  console.log(JSON.stringify(body));
  resolve(body);
});

// Make sure the consume request was successful. In production, don't notify the user; handle failures on the back end
return consumePromise.then(body => {
  const consumed = Object.keys(body).length === 0;
  if (consumed) {
    conv.add(`You successfully consumed ${id}`);
  } else {
    conv.add(`Failed to consume: ${id}`);
  }
});

反映用户的购买情况

当用户查询您的 Action 时,请求 JSON 的 user 对象会包含 列出他们的购买交易请查看此信息,并更改您的 Action 的 根据用户付费的内容来做出响应。

以下示例代码展示了请求的 user 对象,该对象包含 占之前应用内购买交易的 packageEntitlements com.digitalgoods.application 软件包:

{
  "handler": {
    "name": "handler_name"
  },
  "intent": {
    "name": "actions.intent.MAIN",
    "params": {},
    "query": ""
  },
  "scene": {
    "name": "SceneName",
    "slotFillingStatus": "UNSPECIFIED",
    "slots": {}
  },
  "session": {
    "id": "example_session_id",
    "params": {},
    "typeOverrides": []
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED"
      "packageEntitlements": [
        {
          "packageName": "com.digitalgoods.application",
          "entitlements": [
            {
              "sku": "non-consumable.1",
              "skuType": "SKU_TYPE_IN_APP"
            }
            {
              "sku": "consumable.2",
              "skuType": "SKU_TYPE_IN_APP"
            }
          ]
        },
        {
          "packageName": "com.digitalgoods.application",
          "entitlements": [
            {
              "sku": "annual.subscription",
              "skuType": "SKU_TYPE_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=="
              }
            }
          ]
        }
      ]
     }
   },
  "homeStructure": {
    "params": {}
  },
  "device": {
    "capabilities": [
      "SPEECH",
      "RICH_RESPONSE",
      "LONG_FORM_AUDIO"
    ]
  }
}

测试您的项目

测试项目时,你可以在 Actions 控制台中启用沙盒模式 在不向付款方式收取任何费用的情况下测试您的 Action。 如需启用沙盒模式,请按以下步骤操作:

  1. 在 Actions 控制台中,点击导航栏中的 Test
  2. 点击设置
  3. 启用 Development Sandbox 选项。