Możesz dodać pomoc do swojej realizacji, aby użytkownicy mogli zaplanować odbiór
dostawy jedzenia z wyprzedzeniem, Przed wdrożeniem tej funkcji pomocy w
dla realizacji, utwórz plik danych o asortymencie usług, który będzie określał godziny otwarcia
w celu składania zamówień z wyprzedzeniem, zgodnie ze schematem pliku danych o asortymencie
(AdvanceServiceDeliveryHoursSpecification
).
Przedziały zamówień z wyprzedzeniem
Google proponuje przedziały dla zamówień składanych z wyprzedzeniem co 15 minut (maksymalnie 7 dni)
z wyprzedzeniem, na podstawie czasu realizacji zamówienia w restauracji lub usłudze (zgodnie z definicją w
AdvanceServiceDeliveryHoursSpecification
).
Aby pobrać proponowane zamówienie z wyprzedzeniem, użyj następujących wartości z
Pole fulfillmentPreference
obiektu FoodCartExtension
w momencie płatności:
PickupInfo.pickupTimeIso8601
DeliveryInfo.deliveryTimeIso8601
Wdrażanie zamówień z wyprzedzeniem w momencie płatności
Tabela poniżej zawiera możliwe sposoby implementacji w momencie płatności, gdy użytkownicy próbują złożyć zamówienie.
Scenariusz | Zachowanie realizacji |
---|---|
Zamówienie z wyprzedzeniem może zostać zrealizowane dla żądanego przedziału. | Zaakceptuj P0M („jak najszybciej”) lub
FUTURE_SLOT , tworząc ProposedOrder za pomocą
w tym samym boksie. Przykładową odpowiedź dotyczącą płatności przyjmującą przedział znajdziesz tutaj
ten fragment kodu. |
Nie można zrealizować zamówienia z wyprzedzeniem dla żądanego przedziału. | Proces realizacji powinien:
Przykładową odpowiedź dotyczącą płatności proponującą alternatywne przedziały czasu znajdziesz tutaj: ten fragment kodu. |
Alternatywne terminy realizacji zamówienia
Jeśli w momencie płatności zaproponowane przez Google zamówienie z wyprzedzeniem nie jest odpowiednie,
Realizacja może sugerować alternatywne rozwiązania za pomocą funkcji CheckoutResponseMessage
obiektu.
Aby określić alternatywne przedziały czasowe zamówień z wyprzedzeniem, odpowiedz na żądanie płatności za pomocą atrybutu
FoodErrorExtension
i ustaw te wartości:
- W parametrze
foodOrderErrors
podaj typ błędu (np.UNAVAILABLE_SLOT
,NO_CAPACITY
lubCLOSED
). - W parametrze
correctedProposedOrder
podaj zmiennąP0M
lubFUTURE_SLOT
wartości za pośrednictwemavailableFulfillmentOptions
.
Alternatywne przedziały czasu powinny obejmować następne 7 dni od momentu złożenia zamówienia i uwzględnić wszystkie boksy, w których żądany koszyk użytkownika wypełnione.
Załóżmy na przykład, że oferty obiadowe są dostępne tylko od poniedziałku do piątku. od 11:00 do 13:00. Następnie próbuje dodać do koszyka specjały obiadowe, ale wybrany przez niego przedział jest niedostępny. W tym przypadku realizacja powinna zostawić specjalności na lunch i wrócić tylko między 11:00 a 13:00 na następne 7 dni
Pomiń obiekt correctedProposedOrder.Cart.fulfillmentPreference
w swojej odpowiedzi.
Jeśli nie ma dostępnych miejsc albo jeśli restauracja lub obsługa
obsługuje zamówienia z wyprzedzeniem, nie musisz przesyłać
correctedProposedOrder
Zapoznaj się z poniższymi przykładami wiadomości JSON przesyłanych między Twoją realizację a Google w procesie realizacji żądania i odpowiedzi w przypadku zamówienia z wyprzedzeniem, restauracji lub firmy świadczącej usługi w przedsprzedaży.
Przykład: CheckoutRequest z przedziałem czasu na dostawę
Poniższy fragment kodu zawiera przykład żądania płatności z zamówieniem z wyprzedzeniem terminu dostawy.
{
"inputs": [
{
"intent": "actions.foodordering.intent.CHECKOUT",
"arguments": [
{
"extension": {
"@type": "type.googleapis.com/google.actions.v2.orders.Cart",
"merchant": {
"id": "https://www.exampleprovider.com/merchant/id1",
"name": "Cucina Venti"
},
"lineItems": [
{
"name": "Sizzling Prawns Dinner",
"type": "REGULAR",
"id": "sample_item_offer_id_1",
"offerId": "https://www.exampleprovider.com/menu/item/offer/id1",
"quantity": 1,
"price": {
"type": "ESTIMATE",
"amount": {
"currencyCode": "USD",
"units": "16",
"nanos": 750000000
}
},
}
],
"extension": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
"fulfillmentPreference": {
"fulfillmentInfo": {
"delivery": {
// Deliver at 6:30PM.
"deliveryTimeIso8601": "2017-12-14T18:30:00-07:00"
}
}
},
"location": {
...
}
}
}
}
]
}
]
}
Przykład: akceptacja przedziału czasu przez CheckoutResponse
Poniższy fragment kodu zawiera przykładową odpowiedź dotyczącą procesu płatności, w której akceptuje proponowane przedziały zamówień zaliczeniowych.
{
"expectUserResponse": false,
"finalResponse": {
"richResponse": {
"items": [
{
"structuredResponse": {
"checkoutResponse": {
"proposedOrder": {
"id": "sample_proposed_order_id_1",
"cart": {
"merchant": {
"id": "https://www.exampleprovider.com/merchant/id1",
"name": "Falafel Bite"
},
"lineItems": [
{
"name": "Sizzling Prawns Dinner",
"type": "REGULAR",
"id": "sample_item_offer_id_1",
"offerId": "https://www.exampleprovider.com/menu/item/offer/id1",
"quantity": 1,
"price": {
"type": "ESTIMATE",
"amount": {
"currencyCode": "USD",
"units": "16",
"nanos": 750000000
}
},
}
],
"extension": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
"fulfillmentPreference": {
"fulfillmentInfo": {
"delivery": {
// Same as the time in the request.
"deliveryTimeIso8601": "2017-12-14T18:30:00-07:00"
}
}
},
"location": {
...
}
}
},
"totalPrice": {
"type": "ESTIMATE",
"amount": {
// Represents $16.75
"currencyCode": "USD",
"units": "16",
"nanos": 750000000
}
},
"extension": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension",
// Send whole proposed order back.
"availableFulfillmentOptions": [
"fulfillmentInfo": {
"delivery": {
// Same as the time in the request.
"deliveryTimeIso8601": "2017-12-14T18:30:00-07:00"
}
}
]
}
},
"paymentOptions": {
...
}
}
}
}
]
}
}
}
Przykład: CheckoutResponse z alternatywnymi przedziałami
Poniższy fragment kodu zawiera przykładową odpowiedź dotyczącą procesu płatności, w której
proponuje alternatywne przedziały czasu dla zamawiania z góry. Pamiętaj, że parametr
correctedProposedOrder.Cart.fulfillmentPreference
obiekt powinien zostać pominięty w
odpowiedź na Twoje pytanie.
{
"expectUserResponse": false,
"finalResponse": {
"richResponse": {
"items": [
{
"structuredResponse": {
"error": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
"foodOrderErrors": [
{
"error": "UNAVAILABLE_SLOT", // Cart level error
"description": "The restaurant is closed."
}
],
"correctedProposedOrder": {
// Send whole original cart back,
// without the fulfillmentPreference.
"cart": {
...
},
"otherItems": {
...
},
"totalPrice": {
...
},
"extension": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension",
"availableFulfillmentOptions": [
"fulfillmentInfo": {
"delivery": {
"deliveryTimeIso8601": "2017-12-14T19:00:00-07:00"
}
},
"fulfillmentInfo": {
"delivery": {
"deliveryTimeIso8601": "2017-12-14T19:30:00-07:00"
}
},
"fulfillmentInfo": {
"delivery": {
"deliveryTimeIso8601": "2017-12-14T20:00:00-07:00"
}
}
]
}
},
"paymentOptions": {
...
}
}
}
}
]
}
}
}
Wdrażanie zamówień z wyprzedzeniem podczas składania zamówień
Jeśli podczas przesyłania zamówienia wystąpi problem z terminami zamówień z wyprzedzeniem,
Pole SubmitOrderResponseMessage
powinno zawierać przyczynę (np.
UNAVAILABLE_SLOT
lub UNKNOWN
) w obiekcie RejectionInfo
.
Zaktualizuj stan zamówienia z CREATED
na CONFIRMED
w
OrderState
, gdy dostawca zaakceptuje zamówienie. Dołącz
wybrany przedział czasu w e-mailu z potwierdzeniem wysłanym do użytkownika.
Jeśli w ramach realizacji zamówienia później zamówienie zostanie wysłane do restauracji, wyślij do Google zaktualizować za pomocą asynchronicznego działania aktualizacji zamówienia.
w obiekcie OrderUpdate
odpowiedzi na przesłanie zamówienia w związku z Twoją realizacją lub
w kolejnych asynchronicznych aktualizacjach zamówień,
estimatedFulfillmentTimeIso8601
z wartością ustawioną w ten sposób:
- Gdy stan zamówienia to
CREATED
lubCONFIRMED
, jako wartość ustaw czas dostawy lub odbioru, który użytkownik zaplanował na zamówienie z wyprzedzeniem. - Gdy istnieje dokładniejszy przewidywany czas dostawy z restauracji lub usługę, ustaw wartość na szacowany czas dostawy lub odbioru.
Przykład: SubmitOrderRequest z terminem dostawy
Poniższy fragment kodu zawiera przykład żądania przesłania zamówienia, które wskazuje wybrany przez użytkownika przedział zamówienia z rezerwacją.
{
"inputs": [
{
"intent": "actions.intent.TRANSACTION_DECISION",
"arguments": [
{
"transactionDecisionValue": {
"order": {
"finalOrder": {
"cart": {
"notes": "Guest prefers their food to be hot when it is delivered.",
"merchant": {
"id": "https://www.exampleprovider.com/merchant/id1",
"name": "Cucina Venti"
},
"lineItems": [
{
"name": "Sizzling Prawns Dinner",
"type": "REGULAR",
"id": "sample_item_offer_id_1",
"offerId": "https://www.exampleprovider.com/menu/item/offer/id1",
"quantity": 1,
"price": {
"type": "ESTIMATE",
"amount": {
"currencyCode": "USD",
"units": "16",
"nanos": 750000000
}
}
}
],
"extension": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
"fulfillmentPreference": {
"fulfillmentInfo": {
"delivery": {
"deliveryTimeIso8601": "2017-12-14T18:30:00-07:00"
}
}
}
"contact": {
...
}
}
},
"totalPrice": {
"type": "ESTIMATE",
"amount": {
"currencyCode": "USD",
"units": "16",
"nanos": 750000000
}
},
"id": "sample_final_order_id",
"extension": {
// Send whole proposed order back.
"availableFulfillmentOptions": [
"fulfillmentInfo": {
"delivery": {
"deliveryTimeIso8601": "2017-12-14T18:30:00-07:00"
}
]
}
},
"googleOrderId": "sample_google_order_id",
"orderDate": "2017-07-17T12:00:00Z",
"paymentInfo": {
...
}
}
}
}
]
}
]
}
Przykład: SubmitOrderResponse akceptując zamówienie
Poniższy fragment kodu zawiera przykładową odpowiedź na przesłanie zamówienia, w której potwierdza, że firma zaakceptowała zamówienie użytkownika.
{
"expectUserResponse": false,
"finalResponse": {
"richResponse": {
"items": [
{
"structuredResponse": {
"orderUpdate": {
"actionOrderId": "sample_action_order_id",
"orderState": {
"state": "CREATED",
"label": "Order placed"
},
"receipt": {
"userVisibleOrderId": "userVisibleId1234"
},
"updateTime": "2017-07-17T12:00:00Z",
"orderManagementActions": [
...
],
"infoExtension": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
// Same as the user selected time.
"estimatedFulfillmentTimeIso8601": "2017-12-14T18:30:00-07:00"
}
}
}
}
]
}
}
}
Przykład: SubmitOrderResponse odrzuca zamówienie z powodu niedostępności przedziału
Poniższy fragment kodu zawiera przykładową odpowiedź na przesłanie zamówienia, w której realizacja odrzuca zamówienie użytkownika z wyprzedzeniem z powodu niedostępności przedziału.
{
"expectUserResponse": false,
"finalResponse": {
"richResponse": {
"items": [
{
"structuredResponse": {
"orderUpdate": {
"actionOrderId": "sample_action_order_id",
"orderState": {
"state": "REJECTED",
"label": "Unavailable slot"
},
"rejectionInfo": {
// Note that this UNAVAILABLE_SLOT is different from the enum
// with the same name proposed for FoodOrderError.
"state": "UNAVAILABLE_SLOT",
"label": "Unavailable slot"
},
"updateTime": "2017-07-17T12:00:00Z",
"orderManagementActions": [
...
]
}
}
}
]
}
}
}
Przykładowe zamówienia z wyprzedzeniem
Za pomocą typu AdvanceServiceDeliveryHoursSpecification
można określić
godziny dostawy lub odbioru, aby umożliwić użytkownikom wcześniejsze zaplanowanie zamówienia.
Uwaga: musisz określić 2 osobne przedziały czasowe.
w przypadku realizacji usługi: okres składania zamówień, który określa, kiedy użytkownicy mogą
zamówienie oraz okres realizacji, który określa, kiedy zamówienie zostanie zrealizowane.
Obiekt
określa, kiedy użytkownik
może złożyć zamówienie. Czas realizacji zamówień podrzędnych (OpeningHoursSpecification
lub ServiceDeliveryHoursSpecification
) określają, kiedy można
zrealizowano.AdvanceServiceDeliveryHoursSpecification
W poniższym przykładzie określono godziny pracy świadczenia usługi, w których przyjmujemy zamówienia z wyprzedzeniem: z 15-minutowymi odstępami czasu.
{ "hoursAvailable": [ { "@type": "OpeningHoursSpecification", "opens": "T00:00:00", // Ordering available 24 hours "closes": "T23:59:59", "deliveryHours": [ { "@type": "ServiceDeliveryHoursSpecification", "opens": "T09:00:00", // ASAP orders b/w 9am and 8:59:59pm "closes": "T21:00:00", "deliveryLeadTime": { "value": "60", "unitCode": "MIN" } }, { "@type": "AdvanceServiceDeliveryHoursSpecification", "opens": "T10:00:00", // Delivery between 10AM and 7:59:59PM "closes": "T20:00:00", "serviceTimeInterval": "PT15M", // in slots spaced 15 minutes apart (ISO8601) "advanceBookingRequirement": { "minValue": 60, // The slot should be at least 60 mins away "maxValue": 8640, // but not more than 6 days away "unitCode": "MIN" } } ] } ] }
Poniższy przykład pokazuje, jak określić, że usługa jest otwarta dla: zamówienia złożone tego samego dnia w Boże Narodzenie, ale zamknięte w przypadku zamówień z wyprzedzeniem zaplanowanych na tego dnia. Ten przykład obsługuje następujące scenariusze:
- Użytkownicy mogą złożyć zamówienie na dostawę tego samego dnia 25 grudnia.
- Użytkownicy mogą złożyć zamówienie z wyprzedzeniem 25 grudnia, aby otrzymać zaplanowaną dostawę 27 grudnia.
- Użytkownicy nie mogą składać zamówień na zaplanowaną dostawę 22 grudnia 25 grudnia.
{ "specialOpeningHoursSpecification": { "@type": "AdvanceServiceDeliveryHoursSpecification", "validFrom": "2018-12-25T00:00:00-07:00", "validThrough": "2018-12-26T00:00:00-07:00", "opens": "T00:00:00", // No advance ordering "closes": "T00:00:00" } }
W poniższym przykładzie możesz określić, jak określić, że usługa jest zamknięta zamówień tego samego dnia lub z wyprzedzeniem zaplanowanych na Boże Narodzenie, ale otwarte są zamówień złożonych na późniejszy dzień. Ten przykład obsługuje: scenariusze:
- Użytkownicy nie mogą składać zamówień na dostawę tego samego dnia 25 grudnia.
- Użytkownicy mogą złożyć zamówienie z wyprzedzeniem 25 grudnia, aby otrzymać zaplanowaną dostawę 27 grudnia.
- Użytkownicy nie mogą składać zamówień na zaplanowaną dostawę 22 grudnia 25 grudnia.
{ "specialOpeningHoursSpecification": [ { "@type": "ServiceDeliveryHoursSpecification", "validFrom": "2018-12-25T00:00:00-07:00", "validThrough": "2018-12-26T00:00:00-07:00", "opens": "T00:00:00", // No ASAP ordering on Christmas "closes": "T00:00:00" }, { "@type": "AdvanceServiceDeliveryHoursSpecification", "validFrom": "2018-12-25T00:00:00-07:00", "validThrough": "2018-12-26T00:00:00-07:00", "opens": "T00:00:00", // Orders cannot be scheduled for Christmas "closes": "T00:00:00" } ] }
Poniższa przykładowa usługa akceptuje zamówienia przez całą dobę, 7 dni w tygodniu i jest dostarczana z 10:00–14:59:59 w dni powszednie:
... { "@type": "OpeningHoursSpecification", "opens": "T00:00:00", "closes": "T23:59:59", "deliveryHours": { "@type": "AdvanceServiceDeliveryHoursSpecification", "opens": "T10:00:00", // Delivery starts at 10:00AM "closes": "T15:00:00", // Delivery ends at 3:00PM. Delivery from 10AM-2:59:59PM. "dayOfWeek": [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ], "serviceTimeInterval": "PT15M", // in slots spaced 15 minutes apart "advanceBookingRequirement": { "minValue": 60, // The slot should be at least 60 mins away "maxValue": 8640, // but not more than 6 days away "unitCode": "MIN" } } } ...
Ta przykładowa usługa przyjmuje zamówienia codziennie od 8:00 do 16:59:59: klienci mogą zdecydować się na dostawę w ciągu godziny lub wybrać przedziały:
... { "@type": "OpeningHoursSpecification", "opens": "T08:00:00", // Ordering opens at 8:00AM "closes": "T17:00:00", // Ordering closes at 5:00PM, last order at 4:59:59PM "deliveryHours": [ { "@type": "ServiceDeliveryHoursSpecification", "opens": "T08:00:00", "closes": "T17:00:00", "deliveryLeadTime": { "@type": "QuantitativeValue", "value": "60", // If no exact deliveryLeadTime, put a maximum time "unitCode": "MIN" } }, { "@type": "AdvanceServiceDeliveryHoursSpecification", "opens": "T08:00:00", "closes": "T17:00:00", "serviceTimeInterval": "PT15M", // in slots spaced 15 minutes apart "advanceBookingRequirement": { "minValue": 90, // The slot should be at least 90 mins away "maxValue": 8640, // but not more than 6 days away "unitCode": "MIN" } } ] } ...
Ten przykład przedstawia przypadek, gdy sklep jest otwarty w dniu 8:00–16:59:59 w dni robocze, ale w weekendy o 8:00–18:59. Zamówienia nie są przyjmowane przez całą dobę, 7 dni w tygodniu.
... { // On weekdays, ordering open from 8AM-4:59:59PM. "@type": "OpeningHoursSpecification", "opens": "T08:00:00", "closes": "T17:00:00", "dayOfWeek": [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ], "deliveryHours": [ { // Fulfillment between 8AM-4:59:59PM on weekdays. "@type": "AdvanceServiceDeliveryHoursSpecification", "opens": "T08:00:00", "closes": "T17:00:00", "dayOfWeek": [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ], "serviceTimeInterval": "PT15M", "advanceBookingRequirement": { "minValue": 60, "maxValue": 8640, "unitCode": "MIN" } }, { // Fulfillment between 8AM-6:59:59PM on weekends (even for orders placed on a // weekday). "@type": "AdvanceServiceDeliveryHoursSpecification", "opens": "T08:00:00", "closes": "T19:00:00", "dayOfWeek": [ "Saturday", "Sunday" ], "serviceTimeInterval": "PT15M", "advanceBookingRequirement": { "minValue": 60, "maxValue": 8640, "unitCode": "MIN" } } ] }, { // On weekends, one can place orders upto 6:59:59PM. "@type": "OpeningHoursSpecification", "opens": "T08:00:00", "closes": "T19:00:00", "dayOfWeek": [ "Saturday", "Sunday" ], "deliveryHours": [ { // But fulfillment on weekdays is only till 4:59:59PM. "@type": "AdvanceServiceDeliveryHoursSpecification", "opens": "T08:00:00", "closes": "T17:00:00", "dayOfWeek": [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ], "serviceTimeInterval": "PT15M", "advanceBookingRequirement": { "minValue": 60, "maxValue": 8640, "unitCode": "MIN" } }, { // Fulfillment on weekends is till 6:59:59PM. "@type": "AdvanceServiceDeliveryHoursSpecification", "opens": "T08:00:00", "closes": "T19:00:00", "dayOfWeek": [ "Saturday", "Sunday" ], "serviceTimeInterval": "PT15M", "advanceBookingRequirement": { "minValue": 60, "maxValue": 8640, "unitCode": "MIN" } } ] } ...