Настроить кассу

Процесс оформления заказа вызывается, когда пользователь создает корзину. Содержимое корзины пользователя и сведения о заказе отправляются в вашу сквозную веб-службу заказов. Эта информация проверяется вашим веб-сервисом, после чего вы можете либо продолжить, либо внести необходимые изменения в корзину.

Обработчик оформления заказа для вашего веб-сервиса должен отвечать на запросы POST. Когда клиент решает оформить заказ, Google отправляет сквозной веб-службе заказа тело запроса JSON в форме CheckoutRequestMessage , которое содержит сведения о Cart клиента. Затем ваш веб-сервис отвечает сообщением CheckoutResponseMessage . Следующая диаграмма иллюстрирует этот процесс.

CheckoutResponseMessage возвращает неизмененную корзину клиента или ошибку.

После получения запроса на оформление заказа ваша сквозная веб-служба заказа должна выполнить следующее:

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

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

Сообщение с запросом на оформление заказа

Чтобы проверить корзину клиента, когда клиент решает оформить заказ, Google отправляет запрос в ваш веб-сервис с телом JSON в форме CheckoutRequestMessage . Заказ клиента не отправляется до более позднего этапа сквозного процесса заказа.

Данные, содержащиеся в CheckoutRequestMessage включают следующее:

  • Намерение: поле inputs[0].intent каждого тела запроса на оформление содержит строковое значение actions.foodordering.intent.CHECKOUT .
  • Корзина: поле inputs[0].arguments[0].extension запроса оформления заказа содержит объект Cart , который представляет корзину покупателя.
  • Доставка или вынос. Поле расширения объекта Cart содержит объект FoodCartExtension , который определяет свойства доставки или выноса:
    • Для заказов на доставку объект FoodCartExtension включает адрес доставки.
    • Для заказов на самовывоз или на вынос объект FoodCartExtension не содержит никакой информации о местоположении.
  • Песочница: поле isInSandbox запроса на оформление заказа содержит логическое значение, которое указывает, использует ли транзакция платежи в песочнице.

Пример запроса на оформление заказа

Ниже приведен пример CheckoutRequestMessage :

{
    "user": {},
    "conversation": {
        "conversationId": "CTZbZfUlHCybEdcz_5PB3Ttf"
    },
    "inputs": [
        {
            "intent": "actions.foodordering.intent.CHECKOUT",
            "arguments": [
                {
                    "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.Cart",
                        "merchant": {
                            "id": "restaurant/Restaurant/QWERTY",
                            "name": "Tep Tep Chicken Club"
                        },
                        "lineItems": [
                            {
                                "name": "Spicy Fried Chicken",
                                "type": "REGULAR",
                                "id": "299977679",
                                "quantity": 2,
                                "price": {
                                    "type": "ESTIMATE",
                                    "amount": {
                                        "currencyCode": "AUD",
                                        "units": "39",
                                        "nanos": 600000000
                                    }
                                },
                                "offerId": "MenuItemOffer/QWERTY/scheduleId/496/itemId/143",
                                "extension": {
                                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                                }
                            }
                        ],
                        "extension": {
                            "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
                            "fulfillmentPreference": {
                                "fulfillmentInfo": {
                                    "delivery": {
                                        "deliveryTimeIso8601": "P0M"
                                    }
                                }
                            },
                            "location": {
                                "coordinates": {
                                    "latitude": -33.8376441,
                                    "longitude": 151.0868736
                                },
                                "formattedAddress": "Killoola St, 1, Concord West NSW 2138",
                                "zipCode": "2138",
                                "city": "Concord West",
                                "postalAddress": {
                                    "regionCode": "AU",
                                    "postalCode": "2138",
                                    "administrativeArea": "NSW",
                                    "locality": "Concord West",
                                    "addressLines": [
                                        "Killoola St",
                                        "1"
                                    ]
                                }
                            }
                        }
                    }
                }
            ]
        }
    ],
    "directActionOnly": true,
    "isInSandbox": true
}

Ответное сообщение при оформлении заказа

После получения запроса от сквозной службы заказа ваша веб-служба оформления заказа должна обработать его и ответить сообщением CheckoutResponseMessage . CheckoutResponseMessage должен охватывать успешный или неудачный запрос.

Успешный запрос

Если запрос на оформление заказа успешен, CheckoutResponseMessage должен включить ProposedOrder и PaymentOptions :

  • ProposedOrder

    • cart : объект cart , идентичный корзине, указанной в CheckoutRequestMessage . Если какое-либо содержимое корзины необходимо изменить, CheckoutResponseMessage вместо этого должен включать FoodErrorExtension с исправленным ProposedOrder .
    • otherItems : элементы, добавленные поставщиком, такие как стоимость доставки, налоги и другие сборы. Может также содержать чаевые, добавленные пользователем.
    • totalPrice : общая стоимость заказа.
    • extension : FoodOrderExtension , определяющий информацию о выполнении заказа, например время доставки.
  • PaymentOptions

    • Настройка обработки платежей описана далее в разделе «Настройка Google Pay» . Вы можете использовать заполнитель JSON в своем CheckoutResponseMessage , пока не будете готовы реализовать обработку платежей.
    • Чтобы добавить варианты оплаты-заполнителя в CheckoutResponseMessage , обратитесь к примеру ниже, в котором используется пример платежного шлюза для PaymentOptions .

Пример успешного ответа

{
    "finalResponse": {
        "richResponse": {
            "items": [
                {
                    "structuredResponse": {
                        "checkoutResponse": {
                            "proposedOrder": {
                                "cart": {
                                    "merchant": {
                                        "id": "restaurant/Restaurant/QWERTY",
                                        "name": "Tep Tep Chicken Club"
                                    },
                                    "lineItems": [
                                        {
                                            "name": "Spicy Fried Chicken",
                                            "type": "REGULAR",
                                            "id": "299977679",
                                            "quantity": 2,
                                            "price": {
                                                "type": "ESTIMATE",
                                                "amount": {
                                                    "currencyCode": "AUD",
                                                    "units": "39",
                                                    "nanos": 600000000
                                                }
                                            },
                                            "offerId": "MenuItemOffer/QWERTY/scheduleId/496/itemId/143",
                                            "extension": {
                                                "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                                            }
                                        }
                                    ],
                                    "extension": {
                                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
                                        "fulfillmentPreference": {
                                            "fulfillmentInfo": {
                                                "delivery": {
                                                    "deliveryTimeIso8601": "P0M"
                                                }
                                            }
                                        },
                                        "location": {
                                            "coordinates": {
                                                "latitude": -33.8376441,
                                                "longitude": 151.0868736
                                            },
                                            "formattedAddress": "Killoola St, 1, Concord West NSW 2138",
                                            "zipCode": "2138",
                                            "city": "Concord West",
                                            "postalAddress": {
                                                "regionCode": "AU",
                                                "postalCode": "2138",
                                                "administrativeArea": "NSW",
                                                "locality": "Concord West",
                                                "addressLines": [
                                                    "Killoola St",
                                                    "1"
                                                ]
                                            }
                                        }
                                    }
                                },
                                "totalPrice": {
                                    "type": "ESTIMATE",
                                    "amount": {
                                        "currencyCode": "AUD",
                                        "units": "43",
                                        "nanos": 100000000
                                    }
                                },
                                "extension": {
                                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension",
                                    "availableFulfillmentOptions": [
                                        {
                                            "fulfillmentInfo": {
                                                "delivery": {
                                                    "deliveryTimeIso8601": "P0M"
                                                }
                                            }
                                        }
                                    ]
                                },
                                "otherItems": [
                                    {
                                        "name": "Delivery fee",
                                        "price": {
                                            "type": "ESTIMATE",
                                            "amount": {
                                                "currencyCode": "AUD",
                                                "units": "3",
                                                "nanos": 500000000
                                            }
                                        },
                                        "type": "DELIVERY"
                                    }
                                ]
                            },
                            "paymentOptions": {
                                "googleProvidedOptions": {
                                    "facilitationSpecification": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"merchantName\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\"],\"allowedCardNetworks\":[\"VISA\",\"MASTERCARD\"],\"billingAddressRequired\":true,\"cvcRequired\":false},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gatewayMerchantId\":\"YOUR_MERCHANT_ID\",\"gateway\":\"cybersource\"}}}],\"transactionInfo\":{\"currencyCode\":\"AUD\",\"totalPriceStatus\":\"ESTIMATED\",\"totalPrice\":\"43.1\"}} "
                                }
                            },
                            "additionalPaymentOptions": [
                                {
                                    "actionProvidedOptions": {
                                        "paymentType": "ON_FULFILLMENT",
                                        "displayName": "Pay when you get your food.",
                                        "onFulfillmentPaymentData": {
                                            "supportedPaymentOptions": []
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }
}

Неудачный запрос

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

Пример неудачного ответа

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "error": {
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
              "foodOrderErrors": [
                {
                  "error": "CLOSED",
                  "description": "The restaurant is closed."
                }
              ]
            }
          }
        }
      ]
    }
  }
}

Реализация оформления заказа

При осуществлении оформления заказа необходимо предпринять следующие шаги.

Подтвердить услугу

Возвращает FoodOrderError для первой обнаруженной ошибки обслуживания. Эти ошибки не подлежат восстановлению, поэтому должна быть возвращена первая обнаруженная ошибка. См. раздел «Обработка ошибок» для описания устранимых ошибок.

  1. Прочтите свойство FulfillmentOptionInfo в запросе, чтобы определить, является ли тип выполнения delivery или pickup .
  2. При необходимости верните следующие типы ошибок:

    Тип ошибки Вариант использования
    НЕВЕРНЫЙ Недопустимый тип выполнения.
    НЕ НАЙДЕНО Тип выполнения не найден.
    ЗАКРЫТО
    • Для заказа нет окон OperationHours .
    • Это заказ ASAP, и на текущий момент времени ASAP ServiceHours нет.
    • Произошло аварийное закрытие или для параметра isDisabled установлено значение true.
    Обратите внимание, что специальные окна имеют приоритет над обычными окнами. См. примеры заказа проверки окна и временного удаления сервисных объектов .
    UNAVAILABLE_SLOT Заказ заранее не может быть выполнен.
    NO_CAPACITY Ресторан сейчас занят и заказы не принимает.
    OUT_OF_SERVICE_AREA Заказ не может быть доставлен на адрес пользователя. Пример см. в разделе Проверка адреса доставки .
    NO_COURIER_AVAILABLE Заказ не может быть доставлен из-за ограниченного персонала доставки.

Подтвердить и оценить корзину

  1. Посмотрите каждую корзину . lineItems и сверить их с текущими данными в вашей системе или в системе продавца. MenuItemOffer . Значение sku из объекта фида включается как LineItem . offerId . При необходимости создайте FoodOrderError для каждой позиции. Создайте максимум одну ошибку для каждого элемента. При необходимости верните следующие типы ошибок:

    Тип ошибки Вариант использования восстанавливаемый
    НЕВЕРНЫЙ Данные элемента или любые данные опций недействительны. Нет
    НЕ НАЙДЕНО Товар или какой-либо из вариантов не найден. Нет
    PRICE_CHANGED Цена предмета или комбинации дополнений изменилась. Эту ошибку можно рассматривать как исправимую. Да
    AVAILABILITY_CHANGED Сумма, запрошенная для позиций, или какой-либо из вариантов недоступна. Да
    ТРЕБОВАНИЯ_НЕ_МЕТ Минимальный или максимальный заказ не достигнут. Это можно определить, проверив, находится ли цена корзины ниже комиссии . eligibleTransactionVolumeMin или выше комиссии . eligibleTransactionVolumeMax . См. пример проверки минимальной суммы заказа . Нет
  2. Верните проверенный список lineItems с LineItemType REGULAR . Сумма цен всех позиций корзины — это цена корзины или SUBTOTAL .

См. примеры в проверке товаров в корзине .

Рассчитать стоимость услуги

  1. Найдите правильный объект Fee для услуги на основе eligibleRegion , validFrom , validThrough и priority .
  2. Рассчитайте сумму комиссии в зависимости от того, была ли сущность определена с помощью свойства price , percentageOfCart или pricePerMeter .
  3. Возвратите комиссию за доставку или вынос в виде LineItem с LineItemType DELIVERY или FEE соответственно. Добавьте плату в корзину . список otherItems .

Применить промоакции

  1. Найдите сущность Deal на основе соответствия Promotion . Стоимость coupon по сделке . dealCode .
  2. Подтвердите сделку и при необходимости верните FoodOrderError . Эти ошибки можно рассматривать как исправимые. При необходимости верните следующие типы ошибок:

    Тип ошибки Вариант использования
    PROMO_NOT_RECOGNIZED Код купона не был распознан.
    ПРОМО_EXPIRED Срок действия сделки истек.
    PROMO_ORDER_INELIGIBLE На заказ не распространяется действие купона.
    PROMO_NOT_APPLICABLE Любая другая причина.
  3. Рассчитайте сумму цены сделки на основе Deal . discount или сделка . discountPercentage .

  4. Примените сумму цены сделки, используя общую сумму корзины или общую сумму комиссии в зависимости от сделки . dealType .

  5. Верните тележку . promotions с примененным продвижением.

  6. Верните рекламную акцию как LineItem с LineItemType DISCOUNT . Добавьте скидку в корзину . Список otherItems с отрицательной ценой.

Вернуть ответ

  1. Создайте предложенный заказ . cart , корзина ответа такая же, как и корзина запроса, если во время проверки не обнаружено ошибок.
  2. Верните ProposeOrder . Список otherItems , включая налоги, сборы, чаевые и скидки, если они применяются. Дополнительные сведения о настройке элемента вознаграждения см. в разделе « Бесплатные» .
  3. Включите ProposeOrder . totalPrice добавив цену корзины, сборы, скидки, налоги и чаевые.
  4. Верните FoodOrderExtension . availableFulfillmentOptions с соответствующим FulfillmentOption . Обновите предполагаемое время получения или доставки до ожидаемого времени.
  5. Если в результате предыдущих проверок были сгенерированы ошибки FoodOrderErrors:
    • Включите структурированный ответ . error и список ошибок в FoodErrorExtension . foodOrderErrors .
    • Верните ProposeOrder в поле correctedProposedOrder , если все ошибки можно исправить.
    • Верните PaymentOptions в поле paymentOptions , если все ошибки можно исправить.
    • При необходимости добавьте additionalPaymentOptions , если доступны другие варианты оплаты и все ошибки можно исправить.
  6. Если ошибок проверки нет, верните proposedOrder и paymentOptions в объекте CheckoutResponse . При необходимости добавьте additionalPaymentOptions , если доступны другие варианты оплаты.