Sie können Nutzern in der Auftragsausführung die Möglichkeit bieten, Essensbestellungen im Voraus abzuholen oder zu liefern. Bevor Sie diese Unterstützung bei der Auftragsausführung implementieren, müssen Sie einen Dienstinventarfeed erstellen, in dem die Zeiten angegeben sind, zu denen Nutzer Vorbestellungen aufgeben können, wie im Inventarfeedschema (AdvanceServiceDeliveryHoursSpecification
) beschrieben.
Vorabbestellpositionen
Google schlägt Ihnen anhand der Lieferzeiten für ein Restaurant oder eine Dienstleistung (wie in AdvanceServiceDeliveryHoursSpecification
definiert) Vorabbestellungen in 15-Minuten-Schritten für bis zu 7 Tage im Voraus vor.
Verwenden Sie an der Kasse die folgenden Werte aus dem Feld fulfillmentPreference
des Objekts FoodCartExtension
, um die vorgeschlagenen Slots für Vorbestellungen abzurufen:
PickupInfo.pickupTimeIso8601
DeliveryInfo.deliveryTimeIso8601
Vorbestellungen an der Kasse implementieren
Die folgende Tabelle enthält die möglichen Möglichkeiten, die Antwort der Auftragsausführung an der Kasse zu implementieren, wenn Nutzer versuchen, Bestellungen aufzugeben.
Szenario | Verhalten der Auftragsausführung |
---|---|
Die Vorabbestellung kann für den angeforderten Slot ausgeführt werden. | Akzeptieren Sie den P0M - (so bald wie möglich) oder FUTURE_SLOT -Einkaufswagen, indem Sie einen ProposedOrder mit demselben Slot erstellen. Ein Beispiel für eine Zahlungsantwort, die einen Slot akzeptiert, findest du in diesem Code-Snippet. |
Vorabbestellung kann für den angeforderten Slot nicht ausgeführt werden. | Die Auftragsausführung sollte Folgendes tun:
Ein Beispiel für eine Zahlungsantwort, die alternative Slots vorschlägt, findest du in diesem Code-Snippet. |
Alternative Slots für die Auftragsabwicklung
Wenn die von Google vorgeschlagenen Slots für Vorbestellungen nicht geeignet sind, kann die Auftragsausführung mit dem Objekt CheckoutResponseMessage
Alternativen vorschlagen.
Wenn Sie alternative Slots für Vorbestellungen angeben möchten, antworten Sie auf die Zahlungsanfrage mit einem FoodErrorExtension
und legen Sie die folgenden Werte fest:
- Geben Sie im Parameter
foodOrderErrors
den Fehlertyp an, z. B.UNAVAILABLE_SLOT
,NO_CAPACITY
oderCLOSED
. - Geben Sie im Parameter
correctedProposedOrder
alternativeP0M
- oderFUTURE_SLOT
-Werte überavailableFulfillmentOptions
an.
Die alternativen Slots sollten ab dem Zeitpunkt der Bestellung für die nächsten 7 Tage verfügbar sein und alle Slots enthalten, in denen der vom Nutzer angeforderte Einkaufswagen bedient werden kann.
Angenommen, die Mittagsangebote sind 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 Slot ist nicht verfügbar. In diesem Fall sollte die Auftragsausführung die Mittagsangebote im Einkaufswagen behalten und für die nächsten 7 Tage nur von 11:00 bis 13:00 Uhr zurückkehren.
Sie sollten das Objekt correctedProposedOrder.Cart.fulfillmentPreference
in Ihrer Antwort weglassen.
Wenn es keine verfügbaren Zeitblöcke gibt oder das Restaurant oder der Service keine Vorbestellungen unterstützt, müssen Sie keine correctedProposedOrder
angeben.
In den folgenden Beispielen findest du die JSON-Nachrichten zwischen deiner Auftragsausführung und Google während des Bezahlvorgangs für eine Vorabbestellung, wenn das Restaurant oder der Service für Vorbestellungen verfügbar ist.
Beispiel: CheckoutRequest mit Lieferbereich
Das folgende Snippet zeigt ein Beispiel für eine Zahlungsanfrage mit einem Slot für die Vorabbestellung.
{
"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 akzeptiert den Slot
Das folgende Snippet zeigt ein Beispiel für eine Antwort an den Bezahlvorgang, bei der die Auftragsausführung die vorgeschlagenen Slots 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 Anzeigenflächen
Das folgende Snippet zeigt ein Beispiel für eine Zahlungsantwort, bei der die Auftragsausführung alternative Slots für Vorbestellungen vorschlägt. Das Objekt correctedProposedOrder.Cart.fulfillmentPreference
sollte in der Antwort weggelassen werden.
{
"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": {
...
}
}
}
}
]
}
}
}
Vorabbestellungen beim Aufgeben der Bestellung implementieren
Wenn bei der Auftragsübermittlung ein Problem mit den Slots für Vorabbestellungen auftritt, sollte der SubmitOrderResponseMessage
den Grund (z. B. UNAVAILABLE_SLOT
oder UNKNOWN
) im RejectionInfo
-Objekt enthalten.
Aktualisiere den Status der Bestellung im OrderState
-Objekt von CREATED
zu CONFIRMED
, wenn die Bestellung vom Anbieter akzeptiert wird. Fügen Sie den ausgewählten Zeitraum in die Bestätigungs-E-Mail an den Nutzer ein.
Wenn die Bestellung von der Auftragsausführung später an das Restaurant gesendet wird, senden Sie Google mit der Aktion zur asynchronen Bestellaktualisierung eine Aktualisierung.
Fügen Sie in das Objekt OrderUpdate
der Bestellantwort der Auftragsausführung oder nachfolgender asynchroner Bestellaktualisierungen eine estimatedFulfillmentTimeIso8601
mit folgendem Wert ein:
- Wenn der Bestellstatus
CREATED
oderCONFIRMED
lautet, lege den Wert auf die Liefer- oder Abholzeit fest, die der Nutzer für seine Vorausbestellung geplant hat. - Wenn es eine genauere voraussichtliche Lieferzeit vom Restaurant oder Service gibt, legen Sie den Wert auf die voraussichtliche Liefer- oder Abholzeit fest.
Beispiel: „SubmitOrderRequest“ mit einem Lieferbereich
Das folgende Snippet zeigt ein Beispiel für eine Bestellanfrage, die den vom Nutzer ausgewählten Slot für eine erweiterte Bestellung angibt.
{
"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" zur Annahme der Bestellung
Das folgende Snippet zeigt ein Beispiel für eine Antwort auf „Bestellung senden“, bei der die Auftragsausführung bestätigt, dass die Vorabbestellung des Nutzers angenommen wurde.
{
"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“ lehnt die Bestellung aufgrund der Nichtverfügbarkeit eines Slots ab
Das folgende Snippet zeigt ein Beispiel für eine Bestellantwort, bei der die Auftragsausführung die Vorabbestellung eines Nutzers aufgrund eines nicht verfügbaren Slots 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 die Liefer- oder Abholzeiten angegeben werden, damit Nutzer ihre Bestellung im Voraus planen können.
Hinweis : Es gibt zwei separate Zeitfenster, die Sie für die Auftragsausführung angeben müssen: das Bestellfenster, das angibt, wann Nutzer eine Bestellung aufgeben können, und das Auftragsausführungsfenster, das angibt, wann die Bestellung ausgeführt wird. Das
-Objekt definiert, wann der Nutzer die Bestellung aufgeben kann. Die Auftragsausführungszeiten für untergeordnete Elemente (OpeningHoursSpecification
oder ServiceDeliveryHoursSpecification
) legen fest, wann die Bestellung ausgeführt werden kann.AdvanceServiceDeliveryHoursSpecification
Im folgenden Beispiel werden die Öffnungszeiten eines Betriebs für die Annahme von Vorbestellungen in 15-minütigen Intervallen 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" } } ] } ] }
Das folgende Beispiel zeigt, wie Sie angeben können, dass der Service am 1. Weihnachtstag für Bestellungen am selben Tag geöffnet ist, aber für Vorabbestellungen geschlossen ist, die für diesen Tag geplant sind. Dieses Beispiel unterstützt die folgenden Szenarien:
- Nutzer können am 25. Dezember eine Bestellung aufgeben, um am selben Tag geliefert zu werden.
- Nutzer können am 25. Dezember im Voraus eine Bestellung aufgeben, die für den 27. Dezember geplant ist.
- Nutzer können am 22. Dezember keine Vorbestellungen für eine 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" } }
Das folgende Beispiel zeigt, wie Sie angeben können, dass der Service für Bestellungen am selben Tag oder für Vorbestellungen, die für 1. Weihnachtstag geplant sind, geschlossen ist, aber für erweiterte Bestellungen geöffnet ist, die für einen späteren Tag geplant sind. In diesem Beispiel werden die folgenden Szenarien unterstützt:
- Nutzer können am 25. Dezember keine Bestellung aufgeben, wenn sie am selben Tag geliefert werden soll.
- Nutzer können am 25. Dezember im Voraus eine Bestellung aufgeben, die für den 27. Dezember geplant ist.
- Nutzer können am 22. Dezember keine Vorbestellungen für eine 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 an und liefert an Wochentagen von 10:00 bis 14: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" } } } ...
Der folgende Beispieldienst nimmt Bestellungen täglich von 8:00 bis 16:59:59 Uhr an. Kunden können sich für eine Lieferung innerhalb einer Stunde entscheiden oder eine der Slots auswählen:
... { "@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" } } ] } ...
Das folgende Beispiel zeigt einen Fall, bei dem das Geschäft an Wochentagen von 8:00 bis 16:59:59 Uhr, am Wochenende jedoch von 8:00 bis 18:59 Uhr geöffnet ist. Bestellungen werden nicht rund um die Uhr angenommen.
... { // 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" } } ] } ...