v1-Funktion zur Vorbestellungen

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:
  1. Lehne den angeforderten P0M- oder FUTURE_SLOT-Einkaufswagen ab und gib im FoodErrorExtension-Objekt den Grund an, warum die Bestellung nicht ausgeführt werden kann.
    • Wenn die Bestellung aufgrund der Kapazität nicht ausgeführt werden kann, geben Sie einen FoodOrderError vom Fehlertyp NO_CAPACITY an.
    • Wenn die Bestellung nicht ausgeführt werden kann, weil das Restaurant geschlossen ist, gib einen FoodOrderError vom Fehlertyp CLOSED an.
    • Wenn die Bestellung aus einem anderen Grund nicht ausgeführt werden kann, geben Sie einen FoodOrderError vom Fehlertyp UNAVAILABLE_SLOT an.
  2. Geben Sie nach Möglichkeit alternative P0M- oder FUTURE_SLOT-Werte in correctedProposedOrder an. Diese Werte sollten alle gültigen Auftragsausführungsslots für die nächsten 7 Tage ab der aktuellen Uhrzeit sein. Fügen Sie gegebenenfalls den Slot P0M hinzu.

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:

  1. Geben Sie im Parameter foodOrderErrors den Fehlertyp an, z. B. UNAVAILABLE_SLOT, NO_CAPACITY oder CLOSED.
  2. Geben Sie im Parameter correctedProposedOrder alternative P0M- oder FUTURE_SLOT-Werte über availableFulfillmentOptions 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 oder CONFIRMED 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 OpeningHoursSpecification-Objekt definiert, wann der Nutzer die Bestellung aufgeben kann. Die Auftragsausführungszeiten für untergeordnete Elemente (ServiceDeliveryHoursSpecification oder AdvanceServiceDeliveryHoursSpecification) legen fest, wann die Bestellung ausgeführt werden kann.

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"
      }
    }
  ]
}
...