本指南將逐步引導您完成 Actions 專案的開發程序 整合實體商品交易,並使用 Google Pay 付款。
交易流程
當您的 Actions 專案透過商家管理的付款處理實體交易時, 使用下列流程:
- 收集資訊 (選填) - 視貴機構的性質而定
建議您在開始執行時向使用者收集下列資訊
對話主題:
- 驗證交易需求條件:在對話開始時, 驗證使用者是否符合交易的需求條件,例如 前提是先前必須正確設定付款資訊 建構購物車
- 要求寄送地址:如果交易需要寄送地址 向使用者收集電子郵件地址。
 
- 建立訂單:引導使用者逐步完成 「購物車組件」選購要購買哪些商品
- 提出訂單:購物車完成後,建議訂單 使用者以便確認資訊正確無誤。一旦訂單確認 接收包含訂單詳細資料和付款代碼的回應。
- 完成訂單並傳送收據:訂單確認後,請更新 庫存追蹤或其他出貨服務,然後傳送收據 以便傳達給使用者
- 傳送訂單最新資料:在訂單出貨期限內, 傳送 PATCH 要求給訂單,提供使用者訂單更新 也能使用 Google Cloud CLI 或 Compute Engine API
限制和評論規範
提醒您,其他政策適用於「含有交易的動作」。這項服務 我們最多可能需要六週的時間 才能審查含有交易的動作 。為了減輕審查程序 請務必遵守 交易政策與規範 ,再將動作送交審查。
您只能部署在下列國家/地區銷售實體商品的動作:
| 澳洲 巴西 加拿大 印尼 | 日本 墨西哥 俄羅斯 | 新加坡 泰國 土耳其 英國 美國 | 
建構您的專案
如需交易對話的詳盡範例,請參閱 Node.js 交易 範例。
設定
建立動作時,您必須指定要執行交易 動作控制台。
如要設定專案和執行要求,請按照下列步驟操作:
- 建立新專案或匯入現有專案。
- 瀏覽至「部署」>「部署」目錄資訊:
- 在「其他資訊」部分查看交易 >勾選「執行動作」方塊 交易 API 來執行實體商品交易?」  
1. 收集資訊 (選用)
1a.驗證交易需求條件 (選用)
使用者指出想購買的商品後 您應檢查並確認他們能夠進行交易。 舉例來說,在叫用時,您的動作可能會詢問:「您是否想訂鞋、 或查看帳戶餘額?」如果使用者說「訂鞋」,請設法確保他們 能夠繼續操作 無法繼續交易如要這麼做,您應該轉換至 執行交易需求檢查的情境
建立交易要求檢查場景
- 在「Scees」(情境) 分頁中,新增名稱為 TransactionRequirementsCheck的新場景。
- 按一下「運算單元填充」下方的「+」來新增運算單元。
- 在「選取類型」下方,選取 actions.type.TransactionRequirementsCheckResult。 做為版位類型
- 在版位名稱欄位中,為版位命名 TransactionRequirementsCheck。
- 勾選「自訂運算單元值回傳式曝光」核取方塊 (預設為啟用)。
 
- 按一下 [儲存]。
交易需求條件檢查會產生下列其中一種結果:
- 若符合這些條件,工作階段參數就會設定成功 ,即可繼續建立使用者的訂單。
- 如果無法滿足一或多項條件,就會設定 session 參數。
並帶有失敗條件在此情況下,建議您把對話轉向
或是結束對話
- 如果使用者可以修正導致失敗狀態的錯誤, 系統會提示他們在裝置上解決這些問題。如果 對話是在純語音的介面上進行, 自動發送給使用者的電話。
 
處理交易需求條件檢查結果
- 在「Scenes」分頁中,選取新建立的
TransactionRequirementsCheck個場景。
- 在「條件」下方,按一下「+」新增條件。
- 在文字欄位中輸入下列條件語法來檢查 成功條件: - scene.slots.status == "FINAL" && session.params.TransactionRequirementsCheck.resultType == "CAN_TRANSACT"
- 將滑鼠遊標懸停在剛剛新增的條件上,然後按一下向上箭頭 放在 - if scene.slots.status == "FINAL"之前。
- 啟用「傳送提示」,並提供簡單的提示給使用者 請問: - candidates: - first_simple: variants: - speech: >- You are ready to purchase physical goods.
- 在「Transition」下方選取其他場景,可讓使用者繼續執行 並繼續完成交易  
- 選取條件 - else if scene.slots.status == "FINAL"。
- 啟用「傳送提示」,並提供簡單的提示給使用者 無法進行交易: - candidates: - first_simple: variants: - speech: Transaction requirements check failed.
- 在「轉換」下方選取「結束對話」即可結束對話。 使用者就無法完成交易  
索取寄送地址
如果交易需要使用者的寄送地址,你則應要求提供地址 而非使用者的問題這有助於判斷總價 送貨/取貨地點,或確保使用者位於你的服務區域內。 為此,您應該轉換至提示使用者輸入內容的場景 寄送地址
建立寄送地址場景
- 在「Scenes」分頁中,新增名稱為 DeliveryAddress的新場景。
- 按一下「運算單元填充」下方的「+」來新增運算單元。
- 在「選取類型」下方,選取 actions.type.DeliveryAddressValue做為版位類型。
- 在版位名稱欄位中,為版位命名 TransactionDeliveryAddress。
- 勾選「自訂運算單元值回傳式曝光」核取方塊 (預設為啟用)。
- 按一下「儲存」。
 
設定運算單元時,您可以提供 reason
前方加上 Google 助理的要求,以取得內含字串的地址。預設值
原因字串「得知訂單的寄送目的地」。因此,Google 助理
可能會詢問使用者:「為了知道訂購商品在哪裡,我需要取得寄送地址」。
- 在顯示螢幕上的介面上,使用者可以選擇想使用的地址 這筆交易如果他們先前沒有提供地址, 就能輸入新地址
- 在純語音介面上,Google 助理會要求使用者授予下列權限: 分享交易的預設地址建立目錄 將對話轉接給手機進行輸入。
如要處理寄送地址結果,請按照下列步驟操作:
- 在「Scenes」分頁中,選取新建立的 DeliveryAddress場景。
- 在「條件」下方,按一下「+」新增條件。
- 在文字欄位中輸入下列條件語法來檢查 成功條件: - scene.slots.status == "FINAL" && session.params.TransactionDeliveryAddress.userDecision == "ACCEPTED"
- 將滑鼠遊標懸停在剛剛新增的條件上,然後按一下向上箭頭 放在 - if scene.slots.status == "FINAL"之前。
- 啟用「傳送提示」,並提供簡單的提示給使用者 確認已收到他們的地址: - 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
- 在「Transition」下方選取其他場景,可讓使用者繼續操作 就能與會談。  
- 選取條件 - else if scene.slots.status == "FINAL"。
- 啟用「傳送提示」,並提供簡單的提示給使用者 無法進行交易: - candidates: - first_simple: variants: - speech: I failed to get your delivery address.
- 選取「轉換」下方的「結束對話」即可結束對話。 使用者無法完成交易時  
建立訂單
取得需要的使用者資訊後,您可以建立一個「購物車」 組合引導使用者下單每次動作都會 消費者的購物車組裝流程可能稍有不同 他們的感受和心得
最基本的購物車組裝體驗可讓使用者從清單中挑選要新增的商品 依照自己的順序設計對話,藉此簡化 使用者體驗您可以建立購物車組裝體驗 使用者透過簡單的是非問題來重新下單。 您也可以向使用者顯示熱門「精選」的輪轉介面或清單資訊卡或 「推薦」項目。
我們建議您使用 rich 回應,顯示使用者的選項 還要設計對話的介面,讓使用者可以 進而輕鬆分享生活點滴如需 優質的購物車組裝體驗 設計指南。
建立一筆訂單
在對話過程中,您需要收集使用者想要的商品
然後建構 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"
}將訂單資料儲存至工作階段參數
從執行要求中,將訂單資料儲存到工作階段參數。訂單 物件將用於同一工作階段的不同情境
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)。
- 按一下「儲存」。
 
Google 助理嘗試填入 TransactionDecisionValue 時段時,會啟動
內建體驗,可將您傳遞的 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"之前。
- 啟用「傳送提示」,並提供簡單的提示給使用者 下列訂單已完成: - 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"之前。
- 啟用「傳送提示」,並提供簡單的提示給使用者 訂單遭到拒絕: - candidates: - first_simple: variants: - speech: Look like you don't want to order anything. Goodbye.
- 選取「轉換」下方的「結束對話」即可結束對話。  
- 選取條件 - else if scene.slots.status == "FINAL"。
- 啟用「傳送提示」,並提供簡單的提示給使用者 他們無法進行交易: - 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場景。
- 在「Condition」(條件) 下方,選取檢查成功結果的條件。 - ORDER_ACCEPTED:- scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
- 針對這個條件,啟用「Call your Webhook」(呼叫 Webhook),並提供意圖 處理常式名稱,例如 - update_order。 
- 在 Webhook 程式碼中,新增用於傳送初始順序的意圖處理常式 更新: - 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 Console 專案相關聯的服務帳戶金鑰,然後交換
不記名權杖的服務帳戶金鑰,可傳遞至
HTTP 要求的 Authorization 標頭。
如要擷取服務帳戶金鑰,請執行下列步驟:
- 前往 Google Cloud 控制台, 依序輕觸「選單」圖示 ⋮ >。API 與服務 >憑證 >建立憑證 >服務帳戶金鑰。
- 在「服務帳戶」下方,選取「新增服務帳戶」。
- 將服務帳戶設為 service-account。
- 將角色設定為 專案 >擁有者。
- 將金鑰類型設為「JSON」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- 包含以下內容的物件:- 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- 使用者取消訂單。
請針對與您商家相關的每個狀態,傳送最新的訂單狀態
交易。舉例來說,如果交易需要手動處理
下單後,請記錄 CREATED 訂單更新項目,直到
完成額外處理程序後並非所有訂單都需要所有狀態值。
測試專案
測試專案時,你可以在「Actions」主控台啟用沙箱模式 ,即可在不扣款付款方式的情況下測試動作。 如要啟用沙箱模式,請按照下列步驟操作:
- 在動作控制台中,按一下導覽列的「測試」。
- 按一下 [設定]。
- 啟用「Development Sandbox」選項。
如果是實體交易,您也可以將欄位 isInSandbox 設為 true
樣本。這項操作等同於在
使用 Actions 主控台。如要查看使用 isInSandbox 的程式碼片段,請參閱
「傳送訂單最新資訊」部分。
疑難排解
如果在測試期間遇到任何問題,請參閱疑難排解步驟 交易類型
