Transactions API станет устаревшим 3 мая 2023 года, а 13 июня 2023 года прекращается действие диалоговых действий. Дополнительные сведения см. в разделе Прекращение диалоговых действий .

Создавайте физические транзакции с помощью Google Pay

Это руководство проведет вас через процесс разработки проекта Actions, который включает транзакции для физических товаров и использует Google Pay для оплаты.

Поток транзакций

Когда ваш проект Actions обрабатывает физические транзакции с использованием платежей, управляемых продавцом, он использует следующий процесс:

  1. Сбор информации (необязательно) — в зависимости от характера вашей транзакции вы можете захотеть получить от пользователя следующую информацию в начале разговора:
    1. Проверка требований к транзакции . В начале разговора убедитесь, что пользователь соответствует требованиям для совершения транзакции, например правильно настроена и доступна платежная информация, прежде чем создавать свою корзину.
    2. Запросить адрес доставки . Если для транзакции требуется адрес доставки, получите его от пользователя.
  2. Создайте заказ — проведите пользователя через «корзину», где он выбирает, какие товары он хочет приобрести.
  3. Предложить заказ . Как только корзина будет заполнена, предложите заказ пользователю, чтобы он мог подтвердить его правильность. Если заказ подтвержден, вы получите ответ с деталями заказа и платежным токеном.
  4. Завершите оформление заказа и отправьте квитанцию . После подтверждения заказа обновите отслеживание запасов или другие службы выполнения, а затем отправьте квитанцию ​​пользователю.
  5. Отправлять обновления заказа . В течение всего срока выполнения заказа предоставляйте пользователю обновления заказа, отправляя запросы PATCH в Orders API.

Ограничения и правила проверки

Имейте в виду, что к действиям с транзакциями применяются дополнительные политики. Проверка действий с транзакциями может занять до шести недель, поэтому учитывайте это время при планировании графика выпуска. Чтобы упростить процесс проверки, убедитесь, что вы соблюдаете правила и рекомендации для транзакций , прежде чем отправлять действие на проверку.

Вы можете развертывать Действия, которые продают физические товары, только в следующих странах:

Австралия
Бразилия
Канада
Индонезия
Япония
Мексика
Россия
Сингапур
Таиланд
Турция
Великобритания
Соединенные Штаты

Создайте свой проект

Подробные примеры транзакционных диалогов см. в примере транзакций Node.js.

Настраивать

При создании Action необходимо указать, что вы хотите выполнять транзакции в консоли Actions .

Чтобы настроить свой проект и выполнение, сделайте следующее:

  1. Создайте новый проект или импортируйте существующий проект.
  2. Перейдите к разделу «Развертывание» > «Информация о каталоге» .
  3. В разделе «Дополнительная информация» > «Транзакции» > установите флажок «Используют ли ваши действия API транзакций для выполнения транзакций с физическими товарами?».

1. Соберите информацию (необязательно)

1а. Проверка требований к транзакции (необязательно)

Как только пользователь указал, что хочет совершить покупку, вы должны проверить, сможет ли он выполнить транзакцию. Например, при вызове ваше Действие может спросить: «Вы хотите заказать обувь или проверить баланс своего счета?» Если пользователь говорит «заказать обувь», вы должны убедиться, что он может продолжить, и дать ему возможность исправить любые настройки, препятствующие продолжению транзакции. Для этого вы должны перейти к сцене, которая выполняет проверку требований транзакции.

Создайте сцену проверки требований к транзакции
  1. На вкладке Scenes добавьте новую сцену с именем TransactionRequirementsCheck .
  2. В разделе Заполнение слота нажмите + , чтобы добавить новый слот.
  3. В разделе Выберите тип выберите в качестве типа слота actions.type.TransactionRequirementsCheckResult .
  4. В поле имени слота дайте слоту имя TransactionRequirementsCheck .
  5. Установите флажок Настроить обратную запись значения слота (включен по умолчанию).
  6. Нажмите Сохранить .

Проверка требований к транзакции приведет к одному из следующих результатов:

  • Если требования соблюдены, параметр сеанса устанавливается с условием успеха и можно приступать к формированию заказа пользователя.
  • Если одно или несколько требований не могут быть выполнены, параметр сеанса устанавливается с условием отказа. В этом случае вам следует отвести разговор от транзакционного опыта или закончить разговор.
    • Если какие-либо ошибки, приводящие к состоянию сбоя, могут быть устранены пользователем, ему будет предложено решить эти проблемы на своем устройстве. Если разговор происходит на поверхности только для голоса, передача обслуживания будет инициирована на телефон пользователя.

Обработать требования к транзакции Проверить результат

  1. На вкладке «Сцены» выберите только что созданную сцену TransactionRequirementsCheck .
  2. В разделе Условие нажмите + , чтобы добавить новое условие.
  3. В текстовом поле введите следующий синтаксис условия, чтобы проверить условие успеха:

    scene.slots.status == "FINAL" && session.params.TransactionRequirementsCheck.resultType == "CAN_TRANSACT"
    
  4. Наведите курсор на только что добавленное условие и щелкните стрелку вверх, чтобы поместить его перед if scene.slots.status == "FINAL" .

  5. Включите запросы на отправку и предоставьте пользователю простое уведомление о том, что он готов совершить транзакцию:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                You are ready to purchase physical goods.
    
  6. В разделе «Переход» выберите другую сцену, позволяющую пользователю продолжить разговор и совершить транзакцию.

  7. Выберите условие else if scene.slots.status == "FINAL" .

  8. Включите запросы на отправку и предоставьте пользователю простое уведомление о том, что он не может выполнить транзакцию:

    candidates:
      - first_simple:
          variants:
            - speech: Transaction requirements check failed.
    
  9. В разделе «Переход» выберите «Завершить беседу» , чтобы завершить беседу, если пользователь не может совершать транзакции.

Запросить адрес доставки

Если для вашей транзакции требуется адрес доставки пользователя, вы должны запросить его у пользователя. Это может быть полезно для определения общей цены, места доставки/получения или для проверки того, что пользователь находится в вашем регионе обслуживания. Для этого вам следует перейти к сцене, которая запрашивает у пользователя адрес доставки.

Создать сцену адреса доставки

  1. На вкладке «Сцены» добавьте новую сцену с именем DeliveryAddress .
  2. В разделе Заполнение слота нажмите + , чтобы добавить новый слот.
  3. В разделе Выберите тип выберите в качестве типа слота actions.type.DeliveryAddressValue .
  4. В поле имени слота дайте слоту имя TransactionDeliveryAddress .
  5. Установите флажок Настроить обратную запись значения слота (включен по умолчанию).
  6. Нажмите Сохранить .

При настройке слота вы можете указать reason , которая позволяет предварять запрос Помощника на получение адреса строкой. Строка причины по умолчанию — «чтобы знать, куда отправить заказ». Поэтому Помощник может спросить пользователя: «Чтобы знать, куда отправить заказ, мне нужно узнать ваш адрес доставки».

  • На поверхностях с экраном пользователь будет выбирать, какой адрес он хочет использовать для транзакции. Если они ранее не давали адрес, они смогут ввести новый адрес.
  • На голосовых поверхностях помощник запросит у пользователя разрешение поделиться своим адресом по умолчанию для транзакции. Если они ранее не дали адрес, разговор будет передан на телефон для записи.

Чтобы обработать результат «Адрес доставки», выполните следующие действия:

  1. На вкладке «Сцены» выберите только что созданную сцену DeliveryAddress .
  2. В разделе Условие нажмите + , чтобы добавить новое условие.
  3. В текстовом поле введите следующий синтаксис условия, чтобы проверить условие успеха:

    scene.slots.status == "FINAL" && session.params.TransactionDeliveryAddress.userDecision == "ACCEPTED"
    
  4. Наведите курсор на только что добавленное условие и щелкните стрелку вверх, чтобы поместить его перед if scene.slots.status == "FINAL" .

  5. Включите отправку запросов и предоставьте пользователю простое уведомление о том, что вы получили его адрес:

    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
    
  6. В разделе «Переход» выберите другую сцену, позволяющую пользователю продолжить разговор.

  7. Выберите условие else if scene.slots.status == "FINAL" .

  8. Включите запросы на отправку и предоставьте пользователю простое уведомление о том, что он не может выполнить транзакцию:

    candidates:
      - first_simple:
          variants:
            - speech: I failed to get your delivery address.
    
  9. В разделе «Переход» выберите «Завершить беседу» , чтобы завершить беседу, если пользователь не может совершать транзакции.

Построить заказ

Получив необходимую информацию о пользователе, вы создадите процесс «сборки корзины», который поможет пользователю создать заказ. Каждое действие будет иметь несколько иной процесс сборки корзины, соответствующий их продукту или услуге.

В самом простом опыте сборки тележки пользователь выбирает элементы из списка, чтобы добавить их в свой заказ, хотя вы можете спроектировать диалог, чтобы упростить взаимодействие с пользователем. Вы можете создать процесс сборки корзины, который позволит пользователю повторно заказать свою последнюю покупку с помощью простого вопроса «да» или «нет». Вы также можете представить пользователю карусель или карточку со списком самых популярных или рекомендуемых элементов.

Мы рекомендуем использовать расширенные ответы для визуального представления вариантов пользователя, а также спланировать беседу таким образом, чтобы пользователь мог создавать свою корзину, используя только свой голос. Некоторые рекомендации и примеры качественной сборки тележки см. в Руководстве по проектированию .

Создать заказ

На протяжении всего разговора вам нужно будет собирать предметы, которые пользователь хочет приобрести, а затем создавать объект 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"
}
BLUE_MEDIA
"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"
}
CHASE_PAYMENTECH
"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"
}
FIRST_DATA
"parameters": {
  "gateway": "firstdata",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}
ГЛОБАЛЬНЫЕ_ПЛАТЕЖИ
"parameters": {
  "gateway": "globalpayments",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}
ГОПАЙ
"parameters": {
  "gateway": "gopay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
HITRUST
"parameters": {
  "gateway": "hitrustpay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
НЕРЕШЕННЫЕ РЕШЕНИЯ
"parameters": {
  "gateway": "imsolutions",
  "gatewayMerchantId": "YOUR_MERCHANT_ID"
}
ЛИРА
"parameters": {
  "gateway": "lyra",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
MPGS
"parameters": {
  "gateway": "mpgs",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
MONEY_MAIL_RU
"parameters": {
  "gateway": "moneymailru",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
NEWEBPAY
"parameters": {
  "gateway": "newebpay",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
НЕКСИ
"parameters": {
  "gateway": "nexi",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
НМИ
"parameters": {
  "gateway": "creditcall",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
PAYSAFE
"parameters": {
  "gateway": "paysafe",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
ОПЛАТА
"parameters": {
  "gateway": "payture",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
ПАЮ
"parameters": {
  "gateway": "payu",
  "gatewayMerchantId": "YOUR_GATEWAY_MERCHANT_ID"
}
PRZELEWY24
"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"
}
WORLDPAY
"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
};

Предложить заказ

После того, как вы создали заказ, вы должны представить его пользователю для подтверждения или отклонения. Для этого вы должны перейти к сцене, которая выполняет решение о транзакции.

Создать сцену принятия решения о сделке

  1. На вкладке Scenes добавьте новую сцену с именем TransactionDecision .
  2. В разделе Заполнение слота нажмите + , чтобы добавить новый слот.
  3. В разделе Select type выберите в качестве типа слота actions.type.TransactionDecisionValue .
  4. В поле имени слота дайте слоту имя TransactionDecision .
  5. Установите флажок Настроить обратную запись значения слота (включен по умолчанию).
  6. В разделе «Настроить слот» выберите «Использовать параметр сеанса» в раскрывающемся списке.
  7. В разделе «Настройка слота» введите имя параметра сеанса, используемого для хранения заказа, в текстовое поле (например, $session.params.order ).
  8. Нажмите Сохранить .

Пытаясь заполнить слот TransactionDecisionValue , Помощник инициирует встроенный процесс, в котором переданный вами Order отображается непосредственно на «карточке предварительного просмотра корзины». Пользователь может сказать «разместить заказ», отклонить транзакцию, изменить способ оплаты, например кредитную карту или адрес, или запросить изменение содержимого заказа.

На этом этапе пользователь также может запросить изменения в заказе. В этом случае вы должны убедиться, что ваше выполнение может обрабатывать запросы на изменение заказа после завершения сборки тележки.

Обработать результат принятия решения о сделке

Когда слот TransactionDecisionValue заполнен, ответ пользователя на решение о транзакции будет сохранен в параметре сеанса. Это значение содержит следующее:

  • ORDER_ACCEPTED ,
  • ORDER_REJECTED ,
  • DELIVERY_ADDRESS_UPDATED ,
  • CART_CHANGE_REQUESTED
  • USER_CANNOT_TRANSACT .

Чтобы обработать результат решения транзакции:

  1. На вкладке «Сцены» выберите только что созданную сцену TransactionDecision .
  2. В разделе Условие нажмите + , чтобы добавить новое условие.
  3. В текстовом поле введите следующий синтаксис условия, чтобы проверить условие успеха:

    scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  4. Наведите курсор на только что добавленное условие и щелкните стрелку вверх, чтобы поместить его перед if scene.slots.status == "FINAL" .

  5. Включите запросы на отправку и предоставьте пользователю простое уведомление о том, что его заказ выполнен:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction completed! Your order
                $session.params.TransactionDecision.order.merchantOrderId is all
                set!
    
  6. В разделе «Переход» выберите «Завершить разговор» , чтобы завершить разговор.

  7. В разделе Условие нажмите + , чтобы добавить новое условие.

  8. В текстовом поле введите следующий синтаксис условия, чтобы проверить условия сбоя:

      scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_REJECTED"
    
  9. Наведите курсор на только что добавленное условие и щелкните стрелку вверх, чтобы поместить его перед if scene.slots.status == "FINAL" .

  10. Включите запросы на отправку и предоставьте пользователю простое уведомление об отклонении заказа:

    candidates:
      - first_simple:
          variants:
            - speech: Look like you don't want to order anything. Goodbye.
    
  11. В разделе «Переход» выберите «Завершить разговор» , чтобы завершить разговор.

  12. Выберите условие else if scene.slots.status == "FINAL" .

  13. Включите запросы на отправку и предоставьте пользователю простое уведомление о том, что он не может выполнить транзакцию:

    candidates:
      - first_simple:
          variants:
            - speech: >-
                Transaction failed with status
                $session.params.TransactionDecision.transactionDecision
    
  14. В разделе «Переход» выберите «Завершить беседу» , чтобы завершить беседу, если пользователь не может совершать транзакции.

Завершите заказ и отправьте квитанцию

Когда слот TransactionDecisionValue возвращает результат ORDER_ACCEPTED , вы должны немедленно выполнить любую обработку, необходимую для «подтверждения» заказа (например, сохранить его в своей собственной базе данных и взимать плату с пользователя).

Вы можете закончить разговор этим ответом, но вы должны включить простой ответ, чтобы разговор продолжался. Когда вы предоставите этот первоначальный orderUpdate , пользователь увидит «свернутую карточку квитанции» вместе с остальной частью вашего ответа. Эта карта будет отражать квитанцию, которую пользователь находит в своей истории заказов.

Во время подтверждения заказа ваш объект заказа может включать userVisibleOrderId , который является идентификатором заказа, который видит пользователь. Вы можете повторно использовать merchantOrderId для этого поля.

Часть объекта OrderUpdate должна содержать объект последующего действия, который проявляется в виде кнопок URL в нижней части сведений о заказе, которые пользователь может найти в истории заказов помощника.

  • Вы должны предоставить как минимум VIEW_DETAILS последующее действие с каждым заказом. Он должен содержать глубокую ссылку на представление заказа в вашем мобильном приложении или на веб-сайте.
  • Вы также должны отправить по электронной почте официальную квитанцию, отвечающую всем юридическим требованиям для проведения транзакции, в дополнение к карточке квитанции в разговоре вашего Действия.

Чтобы отправить первоначальное обновление заказа:

  1. На вкладке «Сцены» выберите сцену TransactionDecision .
  2. В разделе Condition выберите условие, которое проверяет результат успеха, ORDER_ACCEPTED :

      scene.slots.status == "FINAL" && session.params.TransactionDecision.transactionDecision == "ORDER_ACCEPTED"
    
  3. Для этого условия включите Call your webhook и укажите имя обработчика намерений, например update_order .

  4. В код веб-перехватчика добавьте обработчик намерений для отправки первоначального обновления заказа:

    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-запросы PATCH в Orders API со статусом и подробностями заказа.

Настройте асинхронные запросы к Orders API

Запросы на обновление заказов к Orders API авторизуются токеном доступа. Чтобы ИСПРАВИТЬ обновление заказа в Orders API, загрузите ключ служебной учетной записи JSON, связанный с вашим проектом Actions Console, а затем замените ключ служебной учетной записи маркером носителя, который можно передать в заголовке Authorization HTTP-запроса.

Чтобы получить ключ учетной записи службы, выполните следующие действия:

  1. В консоли Google Cloud выберите Меню ☰ > API и службы > Учетные данные > Создать учетные данные > Ключ сервисной учетной записи .
  2. В разделе «Учетная запись службы» выберите «Новая учетная запись службы» .
  3. Задайте для учетной записи службы значение service-account .
  4. Установите для роли Project > Owner .
  5. Установите тип ключа на JSON .
  6. Выберите Создать .
  7. Ключ частной служебной учетной записи JSON будет загружен на ваш локальный компьютер.

В коде обновления вашего заказа вы можете обменять свой служебный ключ на токен носителя, используя клиентскую библиотеку Google API и область действия «https://www.googleapis.com/auth/actions.order.developer» . Шаги и примеры установки вы можете найти на странице GitHub клиентской библиотеки API.

Вы также можете сослаться на order-update.js в нашем образце Node.js для примера обмена ключами.

Отправлять обновления заказа

После обмена ключа сервисной учетной записи на токен носителя OAuth вы можете отправлять обновления заказов в виде авторизованных запросов PATCH к Orders API.

URL-адрес 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 .
    • 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 заказа до тех пор, пока не будет выполнена дополнительная обработка. Не для каждого заказа требуется каждое значение статуса.

Протестируйте свой проект

При тестировании своего проекта вы можете включить режим песочницы в консоли действий, чтобы протестировать действие без взимания платы за способ оплаты. Чтобы включить режим песочницы, выполните следующие действия:

  1. В консоли «Действия» щелкните «Тест» в области навигации.
  2. Щелкните Настройки .
  3. Включите опцию «Песочница разработки» .

Для физических транзакций вы также можете установить для поля isInSandbox значение true в своем образце. Это действие эквивалентно включению режима песочницы в консоли действий. Фрагмент кода, использующий isInSandbox , см. в разделе «Отправка обновлений заказа» .

Поиск неисправностей

Если у вас возникнут какие-либо проблемы во время тестирования, вам следует прочитать наши шаги по устранению неполадок для транзакций.