Процесс оформления заказа вызывается, когда пользователь создает корзину. Содержимое корзины пользователя и сведения о заказе отправляются в вашу сквозную веб-службу заказов. Эта информация проверяется вашим веб-сервисом, после чего вы можете либо продолжить, либо внести необходимые изменения в корзину.
Обработчик оформления заказа для вашего веб-сервиса должен отвечать на запросы POST. Когда клиент решает оформить заказ, Google отправляет сквозной веб-службе заказа тело запроса JSON в форме CheckoutRequestMessage
, которое содержит сведения о Cart
клиента. Затем ваш веб-сервис отвечает сообщением 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
.
- Настройка обработки платежей описана далее в разделе «Настройка Google Pay» . Вы можете использовать заполнитель JSON в своем
Пример успешного ответа
{
"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 для первой обнаруженной ошибки обслуживания. Эти ошибки не подлежат восстановлению, поэтому должна быть возвращена первая обнаруженная ошибка. См. раздел «Обработка ошибок» для описания устранимых ошибок.
- Прочтите свойство FulfillmentOptionInfo в запросе, чтобы определить, является ли тип выполнения
delivery
илиpickup
. При необходимости верните следующие типы ошибок:
Тип ошибки Вариант использования НЕВЕРНЫЙ Недопустимый тип выполнения. НЕ НАЙДЕНО Тип выполнения не найден. ЗАКРЫТО - Для заказа нет окон OperationHours .
- Это заказ ASAP, и на текущий момент времени ASAP ServiceHours нет.
- Произошло аварийное закрытие или для параметра
isDisabled
установлено значение true.
UNAVAILABLE_SLOT Заказ заранее не может быть выполнен. NO_CAPACITY Ресторан сейчас занят и заказы не принимает. OUT_OF_SERVICE_AREA Заказ не может быть доставлен на адрес пользователя. Пример см. в разделе Проверка адреса доставки . NO_COURIER_AVAILABLE Заказ не может быть доставлен из-за ограниченного персонала доставки.
Подтвердить и оценить корзину
Посмотрите каждую корзину .
lineItems
и сверить их с текущими данными в вашей системе или в системе продавца. MenuItemOffer . Значениеsku
из объекта фида включается как LineItem .offerId
. При необходимости создайте FoodOrderError для каждой позиции. Создайте максимум одну ошибку для каждого элемента. При необходимости верните следующие типы ошибок:Тип ошибки Вариант использования восстанавливаемый НЕВЕРНЫЙ Данные элемента или любые данные опций недействительны. Нет НЕ НАЙДЕНО Товар или какой-либо из вариантов не найден. Нет PRICE_CHANGED Цена предмета или комбинации дополнений изменилась. Эту ошибку можно рассматривать как исправимую. Да AVAILABILITY_CHANGED Сумма, запрошенная для позиций, или какой-либо из вариантов недоступна. Да ТРЕБОВАНИЯ_НЕ_МЕТ Минимальный или максимальный заказ не достигнут. Это можно определить, проверив, находится ли цена корзины ниже комиссии . eligibleTransactionVolumeMin
или выше комиссии .eligibleTransactionVolumeMax
. См. пример проверки минимальной суммы заказа .Нет Верните проверенный список lineItems с LineItemType
REGULAR
. Сумма цен всех позиций корзины — это цена корзины илиSUBTOTAL
.
См. примеры в проверке товаров в корзине .
Рассчитать стоимость услуги
- Найдите правильный объект Fee для услуги на основе
eligibleRegion
,validFrom
,validThrough
иpriority
. - Рассчитайте сумму комиссии в зависимости от того, была ли сущность определена с помощью свойства
price
,percentageOfCart
илиpricePerMeter
. - Возвратите комиссию за доставку или вынос в виде LineItem с LineItemType
DELIVERY
илиFEE
соответственно. Добавьте плату в корзину . списокotherItems
.
Применить промоакции
- Найдите сущность Deal на основе соответствия Promotion . Стоимость
coupon
по сделке .dealCode
. Подтвердите сделку и при необходимости верните FoodOrderError . Эти ошибки можно рассматривать как исправимые. При необходимости верните следующие типы ошибок:
Тип ошибки Вариант использования PROMO_NOT_RECOGNIZED Код купона не был распознан. ПРОМО_EXPIRED Срок действия сделки истек. PROMO_ORDER_INELIGIBLE На заказ не распространяется действие купона. PROMO_NOT_APPLICABLE Любая другая причина. Рассчитайте сумму цены сделки на основе Deal .
discount
или сделка .discountPercentage
.Примените сумму цены сделки, используя общую сумму корзины или общую сумму комиссии в зависимости от сделки .
dealType
.Верните тележку .
promotions
с примененным продвижением.Верните рекламную акцию как LineItem с LineItemType
DISCOUNT
. Добавьте скидку в корзину . СписокotherItems
с отрицательной ценой.
Вернуть ответ
- Создайте предложенный заказ .
cart
, корзина ответа такая же, как и корзина запроса, если во время проверки не обнаружено ошибок. - Верните ProposeOrder . Список
otherItems
, включая налоги, сборы, чаевые и скидки, если они применяются. Дополнительные сведения о настройке элемента вознаграждения см. в разделе « Бесплатные» . - Включите ProposeOrder .
totalPrice
добавив цену корзины, сборы, скидки, налоги и чаевые. - Верните FoodOrderExtension .
availableFulfillmentOptions
с соответствующим FulfillmentOption . Обновите предполагаемое время получения или доставки до ожидаемого времени. - Если в результате предыдущих проверок были сгенерированы ошибки FoodOrderErrors:
- Включите структурированный ответ .
error
и список ошибок в FoodErrorExtension .foodOrderErrors
. - Верните ProposeOrder в поле
correctedProposedOrder
, если все ошибки можно исправить. - Верните PaymentOptions в поле
paymentOptions
, если все ошибки можно исправить. - При необходимости добавьте
additionalPaymentOptions
, если доступны другие варианты оплаты и все ошибки можно исправить.
- Включите структурированный ответ .
- Если ошибок проверки нет, верните
proposedOrder
иpaymentOptions
в объекте CheckoutResponse . При необходимости добавьтеadditionalPaymentOptions
, если доступны другие варианты оплаты.