Sie können in Ihrem Fulfillment-System die Möglichkeit hinzufügen, dass Nutzer Essensbestellungen im Voraus planen können. Bevor Sie diese Funktion in der Auftragsausführung implementieren, erstellen Sie einen Inventarfeed für Dienstleistungen, in dem die Zeiten angegeben sind, zu denen Nutzer Vorbestellungen aufgeben können, wie im Inventarfeed-Schema (AdvanceServiceDeliveryHoursSpecification
) beschrieben.
Zeitblöcke für Vorbestellungen
Google schlägt Zeitfenster für die Vorbestellung in 15-Minuten-Schritten bis zu 7 Tage im Voraus vor, basierend auf den Erfüllungszeiten für ein Restaurant oder einen Dienst (wie in AdvanceServiceDeliveryHoursSpecification
definiert).
Um die vorgeschlagenen Zeitfenster für die Vorbestellung abzurufen, verwende an der Kasse die folgenden Werte aus dem Feld fulfillmentPreference
des Objekts FoodCartExtension
:
PickupInfo.pickupTimeIso8601
DeliveryInfo.deliveryTimeIso8601
Vorbestellungen an der Kasse implementieren
In der folgenden Tabelle sind die möglichen Implementierungsmethoden für die Antwort Ihrer Auftragsausführung an der Kasse aufgeführt, wenn Nutzer versuchen, Bestellungen aufzugeben.
Szenario | Auftragsausführung |
---|---|
Die Vorabbestellung kann für den angeforderten Slot ausgeführt werden. | Nimm den P0M - („So bald wie möglich“) oder FUTURE_SLOT -Einkaufswagen an, indem du eine ProposedOrder mit demselben Slot erstellst. Ein Beispiel für eine Checkout-Antwort, in der ein Slot akzeptiert wird, findest du in diesem Code-Snippet. |
Die Vorbestellung kann für den angeforderten Zeitraum nicht ausgeführt werden. | Ihr Fulfillment-Anbieter muss Folgendes tun:
Ein Beispiel für eine Zahlungsbestätigungsantwort mit alternativen Zeitfenstern findest du in diesem Code-Snippet. |
Alternative Zeitblöcke für die Auftragsausführung
Wenn die von Google vorgeschlagenen Zeitfenster für die Vorbestellung an der Kasse nicht geeignet sind, kann Ihr Fulfillment-Anbieter mithilfe des Objekts CheckoutResponseMessage
Alternativen vorschlagen.
Wenn du alternative Zeitfenster für Vorbestellungen angeben möchtest, antworte auf die Zahlungsanfrage mit FoodErrorExtension
und lege die folgenden Werte fest:
- Geben Sie im Parameter
foodOrderErrors
den Fehlertyp an (z. B.UNAVAILABLE_SLOT
,NO_CAPACITY
oderCLOSED
). - Geben Sie im Parameter
correctedProposedOrder
überavailableFulfillmentOptions
alternativeP0M
- oderFUTURE_SLOT
-Werte an.
Die alternativen Zeitfenster sollten für die nächsten sieben Tage ab dem Zeitpunkt der Bestellung gelten und alle Zeitfenster enthalten, in denen der gewünschte Einkaufswagen des Nutzers abgearbeitet werden kann.
Angenommen, das Mittagsangebot ist nur montags bis freitags von 11:00 bis 13:00 Uhr verfügbar. Der Nutzer versucht dann, Mittagsangebote in den Einkaufswagen zu legen, aber der ausgewählte Zeitblock ist nicht verfügbar. In diesem Fall sollte Ihr Fulfillment-Team die Mittagsangebote im Einkaufswagen belassen und für die nächsten sieben Tage nur die Zeiträume von 11:00 bis 13:00 Uhr zurückgeben.
Das Objekt correctedProposedOrder.Cart.fulfillmentPreference
sollte in der Antwort weggelassen werden.
Wenn keine Zeiträume verfügbar sind oder das Restaurant oder der Dienst keine Vorbestellungen unterstützt, müssen Sie keine correctedProposedOrder
angeben.
In den folgenden Beispielen sehen Sie die JSON-Nachrichten zwischen Ihrem Fulfillment-Anbieter und Google während der Zahlungsanfrage und -antwort für eine Vorbestellung, wenn das Restaurant oder der Dienst für Vorbestellungen verfügbar ist.
Beispiel: CheckoutRequest mit Lieferzeitfenster
Das folgende Snippet zeigt ein Beispiel für eine Zahlungsanfrage mit einem Lieferzeitraum für eine Vorbestellung.
{
"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": {
...
}
}
}
}
]
}
]
}
Beispiel: CheckoutResponse, in der der Slot akzeptiert wird
Das folgende Snippet zeigt ein Beispiel für eine Zahlungsantwort, in der Ihr Fulfillment-Anbieter die vorgeschlagenen Zeitfenster für Vorbestellungen akzeptiert.
{
"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": {
...
}
}
}
}
]
}
}
}
Beispiel: CheckoutResponse mit alternativen Zeitfenstern
Das folgende Snippet zeigt ein Beispiel für eine Zahlungsbestätigungsantwort, in der Ihr Fulfillment-Anbieter alternative Zeitfenster für Vorbestellungen vorschlägt. Das correctedProposedOrder.Cart.fulfillmentPreference
-Objekt sollte in deiner Antwort nicht enthalten sein.
{
"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": {
...
}
}
}
}
]
}
}
}
Vorbestellungen beim Einreichen der Bestellung implementieren
Wenn bei der Auftragseinreichung ein Problem mit den Zeitfenstern für Vorbestellungen auftritt, sollte deine SubmitOrderResponseMessage
im RejectionInfo
-Objekt den Grund (z. B. UNAVAILABLE_SLOT
oder UNKNOWN
) enthalten.
Aktualisiere den Status der Bestellung im Objekt OrderState
von CREATED
auf CONFIRMED
, wenn die Bestellung vom Anbieter akzeptiert wurde. Fügen Sie den ausgewählten Zeitraum in die Bestätigungs-E-Mail an den Nutzer ein.
Wenn Ihr Fulfillment-Anbieter die Bestellung später an das Restaurant sendet, senden Sie Google mithilfe der Aktualisierungsaktion für asynchrone Bestellungen ein Update.
Fügen Sie im OrderUpdate
-Objekt der Antwort auf die Auftragserteilung oder in nachfolgenden asynchronen Auftragsaktualisierungen ein estimatedFulfillmentTimeIso8601
mit folgendem Wert ein:
- Wenn der Bestellstatus
CREATED
oderCONFIRMED
ist, legen Sie den Wert auf die Liefer- oder Abholzeit fest, die der Nutzer für seine Vorbestellung geplant hat. - Wenn das Restaurant oder der Lieferservice eine genauere voraussichtliche Lieferdauer angibt, legen Sie den Wert auf die voraussichtliche Liefer- oder Abholzeit fest.
Beispiel: SubmitOrderRequest mit Lieferzeitfenster
Das folgende Snippet zeigt ein Beispiel für eine Bestellanfrage mit dem ausgewählten Zeitfenster für die Vorabbestellung.
{
"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": {
...
}
}
}
}
]
}
]
}
Beispiel: SubmitOrderResponse, in dem die Bestellung akzeptiert wird
Das folgende Snippet zeigt ein Beispiel für eine Antwort auf die Bestellung, in der Ihr Auftragsausführer bestätigt, dass er die Vorabbestellung des Nutzers akzeptiert hat.
{
"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"
}
}
}
}
]
}
}
}
Beispiel: SubmitOrderResponse, in dem die Bestellung aufgrund der Nichtverfügbarkeit eines Zeitfensters abgelehnt wird
Das folgende Snippet zeigt ein Beispiel für eine Antwort auf die Bestellung, in der die Auftragsausführung die Vorbestellung eines Nutzers aufgrund eines nicht verfügbaren Zeitblocks ablehnt.
{
"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": [
...
]
}
}
}
]
}
}
}
Beispiele für Vorbestellungen
Mit dem Typ AdvanceServiceDeliveryHoursSpecification
können Sie die Liefer- oder Abholzeiten angeben, damit Nutzer ihre Bestellung im Voraus planen können.
Hinweis : Sie müssen zwei separate Zeitfenster für die Diensterfüllung angeben: das Bestellfenster, das angibt, wann Nutzer eine Bestellung aufgeben können, und das Ausführungszeitraum, das angibt, wann die Bestellung ausgeführt wird. Das
-Objekt definiert, wann der Nutzer die Bestellung aufgeben kann. Die untergeordneten Ausführungszeiten (OpeningHoursSpecification
oder ServiceDeliveryHoursSpecification
) geben an, wann die Bestellung ausgeführt werden kann.AdvanceServiceDeliveryHoursSpecification
Im folgenden Beispiel werden die Öffnungszeiten für die Annahme von Vorbestellungen mit 15-minütigen Serviceintervallen definiert.
{ "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" } } ] } ] }
Im folgenden Beispiel wird gezeigt, wie Sie angeben können, dass der Dienst an Heiligabend für Bestellungen am selben Tag geöffnet, aber für vorbestellte Lieferungen an diesem Tag geschlossen ist. Dieses Beispiel unterstützt die folgenden Szenarien:
- Nutzer können am 25. Dezember eine Bestellung für die Lieferung am selben Tag aufgeben.
- Nutzer können am 25. Dezember eine Vorbestellung für die Lieferung am 27. Dezember aufgeben.
- Nutzer können am 22. Dezember keine Vorbestellung für die Lieferung am 25. Dezember aufgeben.
{ "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" } }
Im folgenden Beispiel wird gezeigt, wie Sie angeben können, dass der Dienst für Bestellungen am selben Tag oder für Vorbestellungen, die für den 1. Weihnachtstag geplant sind, geschlossen, aber für Vorbestellungen, die für einen späteren Tag geplant sind, geöffnet ist. Dieses Beispiel unterstützt die folgenden Szenarien:
- Am 25. Dezember können Nutzer keine Bestellungen für die Lieferung am selben Tag aufgeben.
- Nutzer können am 25. Dezember eine Vorbestellung für die Lieferung am 27. Dezember aufgeben.
- Nutzer können am 22. Dezember keine Vorbestellung für die Lieferung am 25. Dezember aufgeben.
{ "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" } ] }
Der folgende Beispieldienst nimmt Bestellungen rund um die Uhr entgegen und liefert an Wochentagen von 10:00 bis 23:59:59 Uhr:
... { "@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" } } } ...
Für den folgenden Beispieldienst werden Bestellungen täglich von 8:00 bis 16:59 Uhr entgegengenommen. Kunden können sich entweder für eine Lieferung innerhalb einer Stunde oder für einen der Zeiträume entscheiden:
... { "@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" } } ] } ...
Im folgenden Beispiel ist der Laden wochentags von 8:00 bis 16:59 Uhr und am Wochenende von 8:00 bis 18:59 Uhr geöffnet. Bestellungen werden nicht rund um die Uhr entgegengenommen.
... { // 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" } } ] } ...