本指南介绍了如何将数字交易添加到对话式对话中, 使用户可以购买您的消耗型数字商品。
关键术语:消耗型数字商品是指库存量单位 (SKU), 用户可以多次使用和购买,例如一定数量的游戏代币 是 Android 游戏的理想平台此数字商品与非消耗品不同 用户只能购买一次的数字商品
有关消耗型一次性商品的详情,请参阅 Android 关于 一次性商品专用功能。
交易流程
本指南概述了数字商品中涉及的每个开发步骤 交易流程当您的 Action 处理数字商品交易时,它 采用以下流程:
- 设置数字购买 API 客户端:您的 Action 会使用数字 购买 API 与您的 Google Play 广告资源进行通信并进行交易。 在您的 Action 执行任何其他操作之前,它会创建一个具有 与数字购买 API 通信的服务密钥。
- 收集信息:您的 Action 会收集有关 用户和 Google Play 广告资源来为交易做准备
- 构建订单:您的 Action 会向用户展示可用的数字商品 以便用户选择一个商品进行购买。
- 完成购买:您的 Action 会使用 digitalPurchases API 来 通过用户从 Google Play 商店中选择的内容发起购买。
- 处理结果:您的 Action 会收到 并通知用户购买成功 其他步骤)。
- 确保购买交易可重复:您的 Action 会使用数字购买交易 通过 API 来“使用”使该商品可供购买 再次执行相应操作
限制和查看指南
其他政策适用于涉及交易的操作。这可能需要 查看包含交易的操作数,因此请将这一时间因素考虑在内 规划发布时间表。为了简化审核流程,请确保您符合 替换为 交易政策和准则 然后再提交 Action 以供审核。
销售数字商品的操作只能在以下国家/地区部署:
- 澳大利亚
- 巴西
- 加拿大
- 印度尼西亚
- 日本
- 墨西哥
- 俄罗斯
- 新加坡
- 泰国
- 土耳其
- 英国
- 美国
前提条件
在将数字交易纳入你的 Action 之前,你需要 以下前提条件:
答 开发者账号 和 商家账号 供您在 Google Play 上管理数字商品 Google Play 管理中心。
一个域名 已在 Google Search Console 中验证。 此网域无需与公开发布的网站关联, 只需引用您的网域即可
安装了
com.android.vending.BILLING
的 Android 应用 权限 。您的数字商品将是“应用内购商品” 与此应用关联的账号。您还需要在 Play 管理中心内使用此应用创建一个版本,但如果 如果您不希望公开发布版本,则可以创建封闭式 Alpha 版测试 发布版本。
如果您还没有 Android 应用,请按照 有关关联 Android 应用的说明。
在 Google Play 管理中心、 也就是你通过 Action 销售的数字商品。请注意, 您必须先完成设置,然后才能在 Play 管理中心内创建受管理的商品 安装 Android 应用的前提条件。
如果您还没有受管理的商品,请按照 创建数字商品的操作说明。
关联 Android 应用
如果您目前没有拥有结算权限的 Android 应用 Google Play 管理中心,请按以下步骤操作:
- 在 Android Studio 中或 选择 Android IDE,创建一个新项目。选择以下选项: 项目设置提示创建一个非常基本的应用。
- 为项目指定软件包名称,例如
com.mycompany.myapp
。 请勿将此名称保留为默认值, 将com.example
添加到 Play 管理中心。 - 打开应用的
AndroidManifest.xml
文件。 在
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>
将应用构建为已签名的 APK。在 Android Studio 中,请按以下步骤操作:
- 依次前往 Build 和 Generate Signed Bundle / APK。
- 点击下一步。
- 在 Key store path 下,点击 Create new。
- 填写每个字段,然后点击 OK。记下您的密钥库 密码和密钥密码,并妥善保存,因为 稍后会用到它们
- 点击下一步。
- 选择发布。
- 选择 V1 (JAR Signature)。
- 点击完成。
- 几秒钟后,Android Studio 会生成一个
app-release.apk
文件。 找到此文件以供稍后使用。
在 Google Play 管理中心、 创建新应用。
前往应用版本页面。
在封闭式轨道下,依次前往管理和 Alpha 版。
点击创建版本按钮。
在让 Google 管理和保护您的签名密钥下方,输入您的签名 关键信息
上传 APK 文件。
点击保存。
创建你的数字商品
如果您当前在 Play 管理中心内没有任何数字商品,请按以下方法操作 步骤:
- 在 Google Play 管理中心、 依次点击应用内商品和受管理的商品。如果您看到警告 按照上述说明创建 Android 应用,或点击链接 创建商家资料。
- 点击创建受管理的商品。
- 填写数字商品对应的字段。记下产品 ID 这就是您在 Action 中引用此商品的方式。
- 点击保存。
- 针对您要销售的每件商品重复第 2-4 步。
准备 Actions 项目
在 Google Play 管理中心内设置数字商品后,您必须启用 进行数字交易,并将您的 Actions 项目与您的 Play 应用相关联。
设置
如需在 Actions 项目中启用数字商品交易,请按以下步骤操作: 步骤:
- 在 Actions 控制台中,打开你的项目或创建一个新项目。
- 转到部署,然后选择目录信息。
- 在其他信息和交易下,选中是复选框
在您的 Action 会使用 Digital Purchase API 执行交易吗?
数字商品”。
- 点击保存。
创建数字商品 API 密钥
如需向数字商品 API 发送请求,您需要下载 JSON 服务 与 Actions 控制台项目关联的账号密钥。
如需检索您的服务账号密钥,请按以下步骤操作:
- 在 Actions 控制台中,点击右上角的三点状图标。 然后选择项目设置。
- 找到 Action 的 Project ID。
- 访问此链接,替换“
<project_id>
”替换为您的项目 ID:https://console.developers.google.com/apis/credentials?project=project_id
- 在主导航栏中,前往凭据。
- 在显示的页面上,点击创建凭据,然后点击服务 账号密钥。
- 转到服务账号,然后点击新的服务账号。
- 为服务账号命名,例如 digitaltransactions。
- 点击创建。
- 将角色设置为项目 >所有者。
- 点击继续。
- 点击创建密钥。
- 选择 JSON 密钥类型。
- 点击创建密钥并下载 JSON 服务账号密钥。
请妥善保存此服务账号密钥。您将在自己的 执行方式为 DigitalPurchases API 创建客户端。
关联到您的 Play 广告资源
为了从 Actions 项目访问您的数字商品,您需要将您的 域名和应用 关联的媒体资源。
如需将 Play 管理中心网站网域和应用关联到 Actions 项目,请按以下步骤操作: 具体步骤:
- 在 Actions 控制台中,依次点击部署和品牌验证。
如果您尚未关联任何媒体资源,请先关联网站:
- 点击网络媒体资源 (</>) 按钮。
- 输入您网域的网址,然后点击连接。
Google 会向 已在 Google Search Console。 这封电子邮件的收件人完成上述步骤后,网站应该就会 品牌验证下会显示相应信息。
您至少关联了一个网站后,请执行以下步骤 关联您的 Android 应用:
- 在 Actions 控制台中,依次点击部署和品牌验证。
- 点击关联应用。
在随即显示的页面上,按照说明验证网站 登录该网域选择包含 数字商品,然后输入与 品牌验证页面。
Google 会再次向以下经过验证的所有者发送验证电子邮件: 网域。他们批准验证后,您的 Play 应用应该 品牌验证下会显示相应信息。
启用访问 Play 购买交易。
构建购买流程
准备好 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 设备),并且它们所在的语言区域支持数字设备
交易
如需创建数字商品购买检查场景,请按以下步骤操作:
- 在 Scenes 标签页中,添加一个名为
DigitalPurchaseCheck
的新场景。 - 在槽填充下,点击 + 以添加新槽。
- 在选择类型下,选择
actions.type.DigitalPurchaseCheckResult
作为 广告位类型。 - 在槽名称字段中,将槽命名为
DigitalPurchaseCheck
。 - 选中自定义槽值回写复选框(默认处于启用状态)。
- 点击保存。
数字购买交易检查会产生以下结果之一:
- 如果满足这些要求,系统就会成功设置会话参数 条件,您可以继续允许用户购买数字商品。
- 如果不能满足一项或多项要求,则会话参数为 带有失败条件的集合。在这种情况下,您应围绕 或结束对话。
如需处理 Digital Purchase 的检查结果,请按以下步骤操作:
- 从 Scenes 标签页中,选择您新创建的
DigitalPurchaseCheck
场景。 - 在条件下,点击 + 以添加新条件。
在文本字段中,输入以下条件语法,以检查 成功条件:
scene.slots.status == "FINAL" && session.params.DigitalPurchaseCheck.resultType == "CAN_PURCHASE"
将光标悬停在您刚刚添加的条件上,然后点击向上箭头 并将其放置在
if scene.slots.status == "FINAL"
之前。启用 Send prompts,并提供简单的提示让用户知道 他们已准备好进行交易:
candidates: - first_simple: variants: - speech: >- You are ready to purchase digital goods.
在过渡下选择其他场景,以便用户继续操作 对话并继续进行交易。
选择条件
else if scene.slots.status == "FINAL"
。启用 Send prompts,并提供简单的提示让用户知道 他们无法进行交易:
candidates: - first_simple: variants: - speech: Sorry you cannot perform a digital purchase.
在转换下,选择结束对话以结束对话。
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. 完成购买
用户选择商品后,您就可以完成购买了。填写完 与所选内容关联的两个广告位时,您应过渡到 执行完整的购买操作。
创建完整的购买场景
- 在 Scenes 标签页中,添加一个名为
CompletePurchase
的新场景。 - 在槽填充下,点击 + 以添加新槽。
- 在选择类型下,选择
actions.type.CompletePurchaseValue
作为 广告位类型。 - 在槽名称字段中,将槽命名为
CompletePurchase
。 - 选中自定义槽值回写复选框(默认处于启用状态)。
- 在配置槽下,从下拉菜单中选择
Use session parameter
。 - 在配置槽下,输入用于配置槽的会话参数的名称
将订单存储到文本字段中(即
$session.params.purchase
)。 - 点击保存。
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
场景中处理所有这些结果。
- 从 Scenes 标签页中,选择您新创建的
CompletePurchase
场景。 - 在条件下,点击 + 以添加新条件。
在文本字段中,输入以下条件语法,以检查 成功条件:
scene.slots.status == "FINAL" && session.params.CompletePurchase.purchaseStatus == "PURCHASE_STATUS_OK"
将光标悬停在您刚刚添加的条件上,然后点击向上箭头 并将其放置在
if scene.slots.status == "FINAL"
之前。启用 Send prompts,并提供简单的提示让用户知道 他们已准备好进行交易:
candidates: - first_simple: variants: - speech: >- Your purchase was successful.
在转换下,选择结束对话以结束对话。
针对您希望支持的每种购买结果重复执行上述步骤。
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。 如需启用沙盒模式,请按以下步骤操作:
- 在 Actions 控制台中,点击导航栏中的 Test。
- 点击设置。
- 启用 Development Sandbox 选项。