本指南将逐步介绍如何开发 Actions 项目 包含实体商品交易并使用 Google Pay 进行付款。
交易流程
当您的 Actions 项目使用商家管理的付款功能处理实际交易时, 采用以下流程:
- 收集信息(可选)- 根据您网站的性质,
您可能需要在一开始就向用户收集以下信息
对话内容:
<ph type="x-smartling-placeholder">- </ph>
- 验证交易要求 - 在对话开始时, 验证用户是否满足进行交易的要求,例如 之前已正确配置和提供付款信息 构建购物车
- 请求配送地址 - 如果交易要求配送 向用户收集一个地址
 
- 建立订单 - 引导用户完成 "购物车组装"在这里,用户选择想要购买的商品
- 提议订单 - 购物车完成后,向 用户,以便他们确认其正确无误。订单得到确认后,您可以 收到包含订单详情和付款令牌的响应。
- 敲定订单并发送收据 - 订单已确认后,更新 库存跟踪或其他履单服务,然后发送收据 。
- 发送订单更新 - 在履单的整个有效期内, 通过向订单发送 PATCH 请求,向用户提供订单更新 API。
限制和查看指南
请注意,其他政策适用于涉及交易的操作。它 我们最多可能需要 6 周时间来审核涉及交易的操作数,因此 然后再安排发布时间表为了简化审核流程 请务必遵守 交易政策和准则 然后再提交 Action 以供审核。
您只能在以下国家/地区部署销售实体商品的 Action:
| 澳大利亚 巴西 加拿大 印度尼西亚 | 日本 墨西哥 俄罗斯 | 新加坡 泰国 土耳其 英国 美国 | 
构建您的项目
如需查看事务性对话的详尽示例,请参阅 Node.js 事务 示例。
设置
创建 Action 时,你必须指定要执行交易 在 Actions 控制台中操作。
如需设置项目和执行方式,请执行以下操作:
- 创建新项目或导入现有项目。
- 导航到部署 >目录信息。
- 在其他信息 >交易 >选中 使用 Transaction API 执行实体商品的交易?”。  
1. 收集信息(可选)
1a. 验证交易要求(可选)
用户一表明想购买就行了 您应检查以确保他们能够执行交易。 例如,调用该 Action 后,你的 Action 可能会询问“你想要订购鞋子吗? 或查看您的账号余额?”如果用户说“订购鞋子”,您应确保他们 可以继续操作,并让他们有机会修正导致其无法运行的设置 继续交易为此,您应该改用 用于执行事务要求检查的场景。
创建交易要求检查场景
- 在“Scenes”(场景)标签页中,添加一个名为 TransactionRequirementsCheck的新场景。
- 在槽填充下,点击 + 以添加新槽。
- 在选择类型下,选择 actions.type.TransactionRequirementsCheckResult作为广告位类型
- 在槽名称字段中,将槽命名为 TransactionRequirementsCheck。
- 选中自定义槽值回写复选框(默认处于启用状态)。
 
- 点击保存。
事务要求检查会产生以下结果之一:
- 如果满足这些要求,系统就会成功设置会话参数 您可以继续构建用户订单。
- 如果无法满足一项或多项要求,系统就会设置会话参数
并带有失败条件在这种情况下,
或结束对话。
- 如果用户可以更正导致失败状态的任何错误, 系统会提示他们在设备上解决这些问题。如果 对话是在纯语音平台上进行, 。
 
处理交易要求检查结果
- 在 Scenes 标签页中,选择您新创建的场景
TransactionRequirementsCheck个场景。
- 在条件下,点击 + 以添加新条件。
- 在文本字段中,输入以下条件语法,以检查 成功条件: - scene.slots.status == "FINAL" && session.params.TransactionRequirementsCheck.resultType == "CAN_TRANSACT"
- 将光标悬停在您刚刚添加的条件上,然后点击向上箭头 并将其放置在 - if scene.slots.status == "FINAL"之前。
- 启用 Send prompts,并提供简单的提示让用户知道 他们已准备好进行交易: - candidates: - first_simple: variants: - speech: >- You are ready to purchase physical goods.
- 在过渡下选择其他场景,以便用户继续 并继续进行交易。  
- 选择条件 - else if scene.slots.status == "FINAL"。
- 启用 Send prompts,并提供简单的提示让用户知道 他们无法进行交易: - candidates: - first_simple: variants: - speech: Transaction requirements check failed.
- 在 Transition(转换)下,选择结束对话以结束对话 用户无法进行交易。  
申请配送地址
如果您的交易需要用户的送货地址,您应发出请求 。这项信息可能有助于确定总价 送货/自提位置,或用于确保用户在您的服务区域内。 为此,您应该过渡到一个提示用户做出回答的场景 送货地址。
创建配送地址场景
- 在 Scenes 标签页中,添加一个名为 DeliveryAddress的新场景。
- 在槽填充下,点击 + 以添加新槽。
- 在选择类型下,选择 actions.type.DeliveryAddressValue作为槽类型。
- 在槽名称字段中,将槽命名为 TransactionDeliveryAddress。
- 选中自定义槽值回写复选框(默认处于启用状态)。
- 点击保存。 
在配置槽时,您可以提供一个 reason,以便执行以下操作:
用于获取带有字符串的地址。默认
原因字符串是“知道将订单发送到哪里”。因此,Google 助理
系统可能会询问用户:“我需要先知道你的送货地址,才能知道把订单发送到哪里”。
- 在带有屏幕的界面上,用户需要选择要使用的地址 。如果他们之前没有提供地址 以便输入新地址
- 在纯语音界面上,Google 助理会请求用户授予以下权限: 分享交易的默认地址。如果他们之前未 您给出一个地址后,系统就会将相应对话转交给手机以供他人进入。
如需处理配送地址结果,请按以下步骤操作:
- 从 Scenes 标签页中,选择您新创建的 DeliveryAddress场景。
- 在条件下,点击 + 以添加新条件。
- 在文本字段中,输入以下条件语法,以检查 成功条件: - scene.slots.status == "FINAL" && session.params.TransactionDeliveryAddress.userDecision == "ACCEPTED"
- 将光标悬停在您刚刚添加的条件上,然后点击向上箭头 并将其放置在 - if scene.slots.status == "FINAL"之前。
- 启用 Send prompts,并提供一条简单提示让用户 知道您收到了他们的地址: - candidates: - first_simple: variants: - speech: >- Great! Your order will be delivered to $session.params.TransactionDeliveryAddress.location.postalAddress.locality $session.params.TransactionDeliveryAddress.location.postalAddress.administrativeArea $session.params.TransactionDeliveryAddress.location.postalAddress.regionCode $session.params.TransactionDeliveryAddress.location.postalAddress.postalCode
- 在过渡下,选择其他场景,以便用户继续操作 对话。  
- 选择条件 - else if scene.slots.status == "FINAL"。
- 启用 Send prompts,并提供简单的提示让用户知道 他们无法进行交易: - candidates: - first_simple: variants: - speech: I failed to get your delivery address.
- 在转换下,选择结束对话以结束对话 如果用户无法进行交易。  
创建订单
获得所需的用户信息后,您就可以构建“购物车” 组装"引导用户创建订单每一项行动 根据他们的客户 产品或服务。
最基本的购物车组装体验是用户从列表中选择要添加的商品 但您可以设计对话以简化对话 用户体验。您可以打造一种购物车组装体验, 通过简单的“是”或“否”问题重新订购最近一次购买的商品。 您还可以向用户展示顶部“精选”的轮播界面或列表卡片或 “推荐”项。
我们建议使用富媒体 响应来呈现用户的选项 不仅如此,还要设计对话方式 只使用他们的语音指令。一些最佳实践和 优质的购物车组装体验,请参阅 设计准则。
创建一个订单
在整个对话过程中,您需要收集用户想要的商品
然后构建 Order 对象。
您的 Order 必须至少包含以下内容:
- buyerInfo- 购买用户的相关信息。
- transactionMerchant- 为交易提供便利的商家的相关信息 订单。
- contents- 列为- lineItems的订单的实际内容。
- priceAttributes- 订单的价格详情,包括总金额 订单费用,以及折扣和税费。
请参阅 Order
构建您的购物车所需的响应文档。请注意,您可能需要将
不同的字段。
以下示例代码展示了一个完整的订单,其中包括可选字段:
const order = {
  createTime: '2019-09-24T18:00:00.877Z',
  lastUpdateTime: '2019-09-24T18:00:00.877Z',
  merchantOrderId: orderId, // A unique ID String for the order
  userVisibleOrderId: orderId,
  transactionMerchant: {
    id: 'http://www.example.com',
    name: 'Example Merchant',
  },
  contents: {
    lineItems: [
      {
        id: 'LINE_ITEM_ID',
        name: 'Pizza',
        description: 'A four cheese pizza.',
        priceAttributes: [
          {
            type: 'REGULAR',
            name: 'Item Price',
            state: 'ACTUAL',
            amount: {
              currencyCode: 'USD',
              amountInMicros: 8990000,
            },
            taxIncluded: true,
          },
          {
            type: 'TOTAL',
            name: 'Total Price',
            state: 'ACTUAL',
            amount: {
              currencyCode: 'USD',
              amountInMicros: 9990000,
            },
            taxIncluded: true,
          },
        ],
        notes: [
          'Extra cheese.',
        ],
        purchase: {
          quantity: 1,
          unitMeasure: {
            measure: 1,
            unit: 'POUND',
          },
          itemOptions: [
            {
              id: 'ITEM_OPTION_ID',
              name: 'Pepperoni',
              prices: [
                {
                  type: 'REGULAR',
                  state: 'ACTUAL',
                  name: 'Item Price',
                  amount: {
                    currencyCode: 'USD',
                    amountInMicros: 1000000,
                  },
                  taxIncluded: true,
                },
                {
                  type: 'TOTAL',
                  name: 'Total Price',
                  state: 'ACTUAL',
                  amount: {
                    currencyCode: 'USD',
                    amountInMicros: 1000000,
                  },
                  taxIncluded: true,
                },
              ],
              note: 'Extra pepperoni',
              quantity: 1,
              subOptions: [],
            },
          ],
        },
      },
    ],
  },
  buyerInfo: {
    email: 'janedoe@gmail.com',
    firstName: 'Jane',
    lastName: 'Doe',
    displayName: 'Jane Doe',
  },
  priceAttributes: [
    {
      type: 'SUBTOTAL',
      name: 'Subtotal',
      state: 'ESTIMATE',
      amount: {
        currencyCode: 'USD',
        amountInMicros: 9990000,
      },
      taxIncluded: true,
    },
    {
      type: 'DELIVERY',
      name: 'Delivery',
      state: 'ACTUAL',
      amount: {
        currencyCode: 'USD',
        amountInMicros: 2000000,
      },
      taxIncluded: true,
    },
    {
      type: 'TAX',
      name: 'Tax',
      state: 'ESTIMATE',
      amount: {
        currencyCode: 'USD',
        amountInMicros: 3780000,
      },
      taxIncluded: true,
    },
    {
      type: 'TOTAL',
      name: 'Total Price',
      state: 'ESTIMATE',
      amount: {
        currencyCode: 'USD',
        amountInMicros: 15770000,
      },
      taxIncluded: true,
    },
  ],
  followUpActions: [
    {
      type: 'VIEW_DETAILS',
      title: 'View details',
      openUrlAction: {
        url: 'http://example.com',
      },
    },
    {
      type: 'CALL',
      title: 'Call us',
      openUrlAction: {
        url: 'tel:+16501112222',
      },
    },
    {
      type: 'EMAIL',
      title: 'Email us',
      openUrlAction: {
        url: 'mailto:person@example.com',
      },
    },
  ],
  termsOfServiceUrl: 'http://www.example.com',
  note: 'Sale event',
  promotions: [
    {
      coupon: 'COUPON_CODE',
    },
  ],
  purchase: {
    status: 'CREATED',
    userVisibleStatusLabel: 'CREATED',
    type: 'FOOD',
    returnsInfo: {
      isReturnable: false,
      daysToReturn: 1,
      policyUrl: 'http://www.example.com',
    },
    fulfillmentInfo: {
      id: 'FULFILLMENT_SERVICE_ID',
      fulfillmentType: 'DELIVERY',
      expectedFulfillmentTime: {
        timeIso8601: '2019-09-25T18:00:00.877Z',
      },
      location: location,
      price: {
        type: 'REGULAR',
        name: 'Delivery Price',
        state: 'ACTUAL',
        amount: {
          currencyCode: 'USD',
          amountInMicros: 2000000,
        },
        taxIncluded: true,
      },
      fulfillmentContact: {
        email: 'johnjohnson@gmail.com',
        firstName: 'John',
        lastName: 'Johnson',
        displayName: 'John Johnson',
      },
    },
    purchaseLocationType: 'ONLINE_PURCHASE',
  },
};
创建顺序和展示选项
在用户确认订单之前, 订单卡片。您可以自定义向用户呈现此卡片的方式 设置各种顺序和呈现选项
以下是使用 配送地址,包括订单确认卡片中的用户的电子邮件地址:
const orderOptions = {
      'requestDeliveryAddress': true,
      'userInfoOptions': {
        'userInfoProperties': ['EMAIL']
      }
    };
const presentationOptions = {
      'actionDisplayName': 'PLACE_ORDER'
    };
创建付款参数
您的 paymentParameters 对象将包含标记化参数,这些参数将
根据您计划使用的 Google Pay 处理方而发生变化
(例如 Stripe、Braintree 和 ACI 等)。
const paymentParamenters = {
      'googlePaymentOption': {
        // facilitationSpec is expected to be a serialized JSON string
        'facilitationSpec': JSON.stringify({
          'apiVersion': 2,
          'apiVersionMinor': 0,
          'merchantInfo': {
            'merchantName': 'Example Merchant',
          },
          'allowedPaymentMethods': [
            {
              'type': 'CARD',
              'parameters': {
                'allowedAuthMethods': ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
                'allowedCardNetworks': [
                  'AMEX', 'DISCOVER', 'JCB', 'MASTERCARD', 'VISA'],
              },
              'tokenizationSpecification': {
                'type': 'PAYMENT_GATEWAY',
                'parameters': {
                  'gateway': 'example',
                  'gatewayMerchantId': 'exampleGatewayMerchantId',
                },
              },
            },
          ],
          'transactionInfo': {
            'totalPriceStatus': 'FINAL',
            'totalPrice': '15.77',
            'currencyCode': 'USD',
          },
        }),
      },
    };
tokenizationSpecification 对象的内容各不相同
支付网关。下表显示了每个网关使用的参数:
"parameters": {
  "gateway": "example",
  "gatewayMerchantId": "exampleGatewayMerchantId"
}"parameters": {
  "gateway": "aciworldwide",
  "gatewayMerchantId": "YOUR_ENTITY_ID"
}"parameters": {
  "gateway": "adyen",
  "gatewayMerchantId": "YOUR_MERCHANT_ACCOUNT_NAME"
}"parameters": {
  "gateway": "alfabank",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "bluemedia",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "bluesnap",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "braintree",
  "braintree:apiVersion": "v1",
  "braintree:sdkVersion": braintree.client.VERSION,
  "braintree:merchantId": "YOUR_BRAINTREE_MERCHANT_ID",
  "braintree:clientKey": "YOUR_BRAINTREE_TOKENIZATION_KEY"
}"parameters": {
  "gateway": "chase",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ACCOUNT_NUMBER"
}"parameters": {
  "gateway": "checkoutltd",
  "gatewayMerchantId": "YOUR_PUBLIC_KEY"
}"parameters": {
  "gateway": "cloudpayments",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "cybersource",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}"parameters": {
  "gateway": "datatrans",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}"parameters": {
  "gateway": "ebanx",
  "gatewayMerchantId": "YOUR_PUBLIC_INTEGRATION_KEY"
}"parameters": {
  "gateway": "firstdata",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}"parameters": {
  "gateway": "globalpayments",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}"parameters": {
  "gateway": "gopay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "hitrustpay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "imsolutions",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}"parameters": {
  "gateway": "lyra",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "mpgs",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "moneymailru",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "newebpay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "nexi",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "creditcall",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "paysafe",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "payture",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "payu",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "przelewy24",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}"parameters": {
  "gateway": "rbkmoney",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}"parameters": {
  "gateway": "sberbank",
  "gatewayMerchantId": "YOUR_ORGANIZATION_NAME"
}"parameters": {
  "gateway": "square",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "stripe",
  "stripe:version": "2018-10-31",
  "stripe:publishableKey": "YOUR_PUBLIC_STRIPE_KEY"
}"parameters": {
  "gateway": "tappay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "tinkoff",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "uniteller",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}"parameters": {
  "gateway": "vantiv",
  "vantiv:merchantPayPageId": "YOUR_PAY_PAGE_ID",
  "vantiv:merchantOrderId": "YOUR_ORDER_ID",
  "vantiv:merchantTransactionId": "YOUR_TRANSACTION_ID",
  "vantiv:merchantReportGroup": "*web"
}"parameters": {
  "gateway": "worldpay",
  "gatewayMerchantId": "YOUR_WORLDPAY_MERCHANT_ID"
}"parameters": {
  "gateway": "yandexcheckout",
  "gatewayMerchantId": "YOUR_SHOP_ID"
}在会话参数中保存订单数据
在 fulfillment 中,将订单数据保存到会话参数中。顺序 对象将用于同一会话的各个场景。
conv.session.params.order = {
    '@type': 'type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec',
    order: order,
    orderOptions: orderOptions,
    presentationOptions: presentationOptions,
    paymentParameters: paymentParameters
};
提议订单
创建订单后,您必须将其呈现给用户以确认或拒绝。 为此,您应该过渡到执行交易决策的场景。
创建交易决策场景
- 在 Scenes 标签页中,添加一个名为 TransactionDecision的新场景。
- 在槽填充下,点击 + 以添加新槽。
- 在选择类型下,选择 actions.type.TransactionDecisionValue作为 广告位类型。
- 在槽名称字段中,将槽命名为 TransactionDecision。
- 选中自定义槽值回写复选框(默认处于启用状态)。
- 在配置槽下,从下拉菜单中选择使用会话参数。
- 在配置槽下,输入所用会话参数的名称
将订单存储到文本字段中(即 $session.params.order)。
- 点击保存。 
为了尝试填充 TransactionDecisionValue 槽,Google 助理启动
一种内置体验,您传递的 Order 会直接渲染到
“购物车预览卡片”用户可以说“下单”、拒绝交易
更改付款选项(如信用卡或地址),或申请
订单的内容
此时,用户也可以请求更改订单。在这种情况下, 应确保您的履单可以处理 完成购物车组装体验
处理交易决策结果
当 TransactionDecisionValue 槽被填充时,系统会针对
交易决策将存储在一个会话参数中。该值包含
以下:
- ORDER_ACCEPTED、
- ORDER_REJECTED、
- DELIVERY_ADDRESS_UPDATED、
- CART_CHANGE_REQUESTED
- USER_CANNOT_TRANSACT。
如需处理事务决策结果,请执行以下操作:
- 从 Scenes 标签页中,选择您新创建的 TransactionDecision场景。
- 在条件下,点击 + 以添加新条件。
- 在文本字段中,输入以下条件语法以检查成功条件: - scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
- 将光标悬停在您刚刚添加的条件上,然后点击向上箭头 并将其放置在 - if scene.slots.status == "FINAL"之前。
- 启用 Send prompts,并提供简单的提示让用户知道 订单已完成: - candidates: - first_simple: variants: - speech: >- Transaction completed! Your order $session.params.TransactionDecision.order.merchantOrderId is all set!
- 在转换下,选择结束对话以结束对话。  
- 在条件下,点击 + 以添加新条件。 
- 在文本字段中,输入以下条件语法,以检查 失败的情况: - scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_REJECTED"
- 将光标悬停在您刚刚添加的条件上,然后点击向上箭头 并将其放置在 - if scene.slots.status == "FINAL"之前。
- 启用 Send prompts,并提供简单的提示让用户知道 订单遭拒: - candidates: - first_simple: variants: - speech: Look like you don't want to order anything. Goodbye.
- 在转换下,选择结束对话以结束对话。  
- 选择条件 - else if scene.slots.status == "FINAL"。
- 启用 Send prompts,并提供一条简单提示让用户 知道自己无法进行交易: - candidates: - first_simple: variants: - speech: >- Transaction failed with status $session.params.TransactionDecision.transactionDecision
- 在转换下,选择结束对话以结束对话 如果用户无法进行交易。  
完成订单并发送收据
当 TransactionDecisionValue 槽返回 ORDER_ACCEPTED 的结果时,
您必须立即执行任何所需的处理来“确认”该
顺序(例如将其保留在您自己的数据库中并向用户收费)。
您可以使用此回复结束对话,但必须包含一个简单的
让对话继续下去。提供这个初始
orderUpdate,用户将看到“收起收据卡片”以及其余的
。此卡片将反映用户在其
订单历史记录。
在订单确认期间,您的订单对象可包含 userVisibleOrderId、
即用户看到的订单的 ID您可以重复使用
此字段的 merchantOrderId。
OrderUpdate 对象的一部分将需要包含一个后续操作对象,
订单详情底部的网址按钮
可在其 Google 助理订单记录中找到
- 您必须至少提供
VIEW_DETAILS针对每笔订单采取后续行动。其中应包含指向 表示您的移动应用或网站上的订单。
- 此外,您还必须通过电子邮件发送符合所有法律法规的正式收据, 除收据卡外,对进行交易所需满足的要求 。
要发送初始订单更新,请执行以下操作:
- 从 Scenes 标签页中,选择您的 TransactionDecision场景。
- 在条件下,选择用于检查成功结果的条件。 - ORDER_ACCEPTED:- scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
- 对于此条件,请启用 Call your webhook, 并提供 intent 处理程序名称,例如 - update_order。 
- 在网络钩子代码中,添加一个用于发送初始订单的 intent 处理程序 更新: - app.handle('update_order', conv => { const currentTime = new Date().toISOString(); let order = conv.session.params.TransactionDecision.order; conv.add(new OrderUpdate({ 'updateMask': { 'paths': [ 'purchase.status', 'purchase.user_visible_status_label' ] }, 'order': { 'merchantOrderId': order.merchantOrderId, 'lastUpdateTime': currentTime, 'purchase': { 'status': 'CONFIRMED', 'userVisibleStatusLabel': 'Order confirmed' }, }, 'reason': 'Reason string })); });
发送订单更新
您需要让用户了解订单的状态, 整个有效期。通过发送 HTTP 来发送用户订单更新 向 Orders API 发出的 PATCH 请求,其中包含订单状态和详情。
设置向 Orders API 发出的异步请求
对 Orders API 的订单更新请求已获得访问权限授权
令牌。如需 PATCH 对 Orders API 的订单更新,请下载 JSON
与您的 Actions 控制台项目关联的服务账号密钥,然后交换
不记名令牌的服务账号密钥,该令牌可以传递到
Authorization 标头。
如需检索您的服务账号密钥,请执行以下步骤:
- 在 Google Cloud 控制台中,执行以下操作: 转到菜单 ☰ >API 和服务 >凭据 >创建凭据 >服务账号密钥。
- 在服务账号下,选择新的服务账号。
- 将服务账号设置为 service-account。
- 将角色设置为项目 >所有者。
- 将密钥类型设置为 JSON。
- 选择创建。
- 系统会将一个专用 JSON 服务账号密钥下载到您的本地机器。
在订单更新代码中,您可以将服务密钥换成不记名令牌 使用 Google API 客户端库 "https://www.googleapis.com/auth/actions.order.developer" 作用域。您可以 有关 API 客户端库的安装步骤和示例 GitHub 页面。
您还可以在我们的order-update.js
Node.js 示例
获取密钥交换示例。
发送订单更新
在用您的服务账号密钥交换 OAuth 不记名令牌之后, 可以将订单更新作为已获授权的 PATCH 请求发送到 Orders API。
Orders API 网址:
PATCH https://actions.googleapis.com/v3/orders/${orderId}
在请求中提供以下标头:
- 将 "Authorization: Bearer token"替换为 OAuth 不记名令牌 您的服务账号密钥。
- "Content-Type: application/json"。
PATCH 请求应采用以下格式的 JSON 正文:
{ "orderUpdate": OrderUpdate }OrderUpdate
对象包含以下顶级字段:
- updateMask- 要更新的订单的字段。要更新 订单状态 将值设置为- purchase.status, purchase.userVisibleStatusLabel。
- order- 更新的内容。如果您要更新 订单内容,请将值设置为更新后的- Order对象。 如果您要更新订单状态(例如,- "CONFIRMED"到- "SHIPPED"),该对象包含 以下字段:- merchantOrderId- 您在- Order对象中设置的 ID。
- lastUpdateTime- 此更新的时间戳。
- purchase- 包含以下内容的对象: <ph type="x-smartling-placeholder">- </ph>
- status- 订单的状态,显示为- PurchaseStatus。 例如“- SHIPPED”或“- DELIVERED”。
- userVisibleStatusLabel- 面向用户的标签,用于提供 订单状态,如“您的订单已发货,且处于 方式”。
 
 
- userNotification(选填)-- userNotification对象。注意事项 添加此对象并不能保证 用户的设备
以下示例代码显示了一个示例 OrderUpdate,它会更新
DELIVERED 的订单状态:
// Import the 'googleapis' module for authorizing the request.
const {google} = require('googleapis');
// Import the 'request-promise' module for sending an HTTP POST request.
const request = require('request-promise');
// Import the OrderUpdate class from the client library.
const {OrderUpdate} = require('@assistant/conversation');
// Import the service account key used to authorize the request.
// Replacing the string path with a path to your service account key.
// i.e. const serviceAccountKey = require('./service-account.json')
// Create a new JWT client for the Actions API using credentials
// from the service account key.
let jwtClient = new google.auth.JWT(
    serviceAccountKey.client_email,
    null,
    serviceAccountKey.private_key,
    ['https://www.googleapis.com/auth/actions.order.developer'],
    null,
);
// Authorize the client
let tokens = await jwtClient.authorize();
// Declare order update
const orderUpdate = new OrderUpdate({
    updateMask: {
      paths: [
        'purchase.status',
        'purchase.user_visible_status_label'
      ]
    },
    order: {
      merchantOrderId: orderId, // Specify the ID of the order to update
      lastUpdateTime: new Date().toISOString(),
      purchase: {
        status: 'DELIVERED',
        userVisibleStatusLabel: 'Order delivered',
      },
    },
    reason: 'Order status updated to delivered.',
});
// Set up the PATCH request header and body,
// including the authorized token and order update.
let options = {
  method: 'PATCH',
  uri: `https://actions.googleapis.com/v3/orders/${orderId}`,
  auth: {
    bearer: tokens.access_token,
  },
  body: {
    header: {
      isInSandbox: true,
    },
    orderUpdate,
  },
  json: true,
};
// Send the PATCH request to the Orders API.
try {
  await request(options);
} catch (e) {
  console.log(`Error: ${e}`);
}
设置购买状态
订单更新的 status
必须说明订单的当前状态。在您的更新的order.purchase.status中
字段中,请使用以下某个值:
- CREATED- 用户接受订单并“创建”角度 但需要对后端进行手动处理。
- CONFIRMED- 订单处于有效状态,正在接受处理。
- IN_PREPARATION- 订单正在准备发货/交付,比如食品 烹饪或包装的食物等。
- READY_FOR_PICKUP- 订单商品可供收件人自提。
- DELIVERED- 订单已送达收件人
- OUT_OF_STOCK- 订单中的一件或多件商品缺货。
- CHANGE_REQUESTED- 用户请求更改订单,但更改已 处理中。
- RETURNED- 商品送达后,用户已发生退货。
- REJECTED- 如果您无法处理、扣款或其他操作 “启用”订单。
- CANCELLED- 用户取消了订单。
对于与您的 Google 广告相关的每种状态,
交易。例如,如果您的交易需要人工处理
记录订单,发送 CREATED 订单更新,直到
系统会完成额外的处理并非每个订单都需要每个状态值。
测试您的项目
测试项目时,你可以在 Actions 控制台中启用沙盒模式 在不向付款方式收取任何费用的情况下测试您的 Action。 如需启用沙盒模式,请按以下步骤操作:
- 在 Actions 控制台中,点击导航栏中的 Test。
- 点击设置。
- 启用 Development Sandbox 选项。
对于实际交易,您还可以将字段 isInSandbox 设置为 true(位于
您的样本。此操作等同于在
Actions 控制台。如需查看使用 isInSandbox 的代码段,请参阅
发送订单更新部分。
问题排查
如果您在测试期间遇到任何问题,请参阅我们的问题排查步骤 。
