本指南介绍了如何将数字交易添加到对话 促使用户购买您的非消耗型数字商品的操作。
关键术语:非消耗型数字商品是指库存量单位 (SKU), 只能购买一次,例如在 Action 中付费访问更多内容 或 Android 应用此类商品不同于消耗型数字商品 可供购买、使用和再次购买的产品。
如需详细了解非消耗型一次性商品,请参阅 Android 关于 一次性商品专用功能。
限制和查看指南
其他政策适用于涉及交易的操作。这可能需要 查看包含交易的操作数,因此请将这一时间因素考虑在内 规划发布时间表。为了简化审核流程,请确保您符合 替换为 交易政策和准则 然后再提交 Action 以供审核。
销售数字商品的操作只能在以下国家/地区部署:
- 澳大利亚
- 巴西
- 加拿大
- 印度尼西亚
- 日本
- 墨西哥
- 俄罗斯
- 新加坡
- 泰国
- 土耳其
- 英国
- 美国
交易流程
本指南概述了数字商品中涉及的每个开发步骤 交易流程当您的 Action 处理数字商品交易时,它 采用以下流程:
- 设置数字购买 API 客户端:您的 Action 会使用数字 购买 API 与您的 Google Play 广告资源进行通信并进行交易。 在您的 Action 执行任何其他操作之前,它会创建一个具有 与数字购买 API 通信的服务密钥。
- 收集信息:您的 Action 会收集有关 用户和 Google Play 广告资源来为交易做准备
- 构建订单:您的 Action 会向用户展示可用的数字商品 以便用户选择一个商品进行购买。
- 完成购买:您的 Action 会使用 digitalPurchases API 来 通过用户选择前往 Google Play 商店进行购买。
- 处理结果:您的 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.验证交易要求
最好确保用户的账号设置妥当
,然后再为用户提供购买选项。此步骤
包括检查用户是否配置了付款方式,以及是否处于
支持数字交易的语言区域。交易开始时
流程,请使用 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
配置。
以下 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.收集可用的广告资源
使用数字购买 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': ['nonconsumable.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
帮助程序 intent 与
与用户选择的内容相关联。
以下 Node.js 代码会处理用户在列表响应中选择的 SKU
并请求包含相应信息的 COMPLETE_PURCHASE
intent:
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 intent)
描述结果的 COMPLETE_PURCHASE_VALUE
参数。构建一个 intent
将结果传达给用户。
处理以下可能的购买结果:
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);
}
});
反映用户的购买情况
当用户查询您的 Action 时,请求 JSON 的 user
对象会包含一个列表
用户购买的产品/服务请查看此信息并更改你的 Action 的回应
根据用户付费的内容付费
以下示例代码展示了请求的 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"
}
]
}
],
...
}