ميزة "الطلب المسبق" من الإصدار 1

يمكنك إضافة دعم في عملية تسليم الطلب ليتمكّن المستخدمون من تحديد موعد لاستلام الطلب طلبات الطعام وتوصيلها مسبقًا. قبل تطبيق هذا الدعم في التنفيذ، يجب إنشاء خلاصة مستودع الخدمة التي تحدّد ساعات العمل لتقديم طلبات مسبقة، كما هو موضّح في مخطط خلاصة المستودع (AdvanceServiceDeliveryHoursSpecification).

خانات الطلبات المسبقة

تقترح Google خانات طلبات مسبقة بزيادات تبلغ 15 دقيقة ولمدة تصل إلى 7 أيام. مستقبلية، بناءً على أوقات التوصيل لمطعم أو خدمة (كما هو محدد في AdvanceServiceDeliveryHoursSpecification).

لاسترداد خانات الترتيب المسبق المقترحة، استخدم القيم التالية من الحقل fulfillmentPreference للعنصر FoodCartExtension عند الدفع:

  • PickupInfo.pickupTimeIso8601
  • DeliveryInfo.deliveryTimeIso8601

تنفيذ الطلبات المسبقة عند الدفع

يسرد الجدول أدناه الطرق المحتملة التي يمكنك من خلالها تنفيذ معايير تنفيذ عملية الشراء. الرد في وقت الدفع عندما يحاول المستخدمون تقديم الطلبات.

السيناريو سلوك توصيل الطلبات
يمكن تنفيذ الطلب المسبق للخانة المطلوبة. يُرجى قبول P0M ("في أقرب وقت ممكن") أو سلة تسوّق FUTURE_SLOT من خلال إنشاء ProposedOrder باستخدام الخانة ذاتها. للاطّلاع على مثال لاستجابة دفع تقبل خانة، راجِع هذا مقتطف الرمز.
لا يمكن تنفيذ الطلب المُسبَق للخانة المطلوبة. يجب أن تستوفي عملية توصيل الطلب ما يلي:
  1. رفض P0M أو FUTURE_SLOT المطلوبَين سلة التسوق، والإشارة إلى سبب عدم إمكانية الوفاء بالطلب في الكائن FoodErrorExtension.
    • إذا تعذّرت تلبية الطلب بسبب السعة، حدِّد FoodOrderError من نوع الخطأ NO_CAPACITY.
    • إذا تعذر إتمام الطلب لأن المطعم مغلق، حدِّد FoodOrderError لنوع الخطأ CLOSED
    • إذا تعذّر توصيل الطلب لسبب آخر تحديد FoodOrderError لنوع الخطأ UNAVAILABLE_SLOT
  2. يُرجى تقديم P0M أو بديل، إن أمكن. قيم FUTURE_SLOT في correctedProposedOrder. يجب أن تكون هذه القيم جميع خانات التنفيذ الصالحة للأيام الـ 7 التالية أيام بدءًا من الوقت الحالي. تضمين الخانة P0M متى أمكن ذلك.

للحصول على مثال لاستجابة دفع تقترح خانات بديلة، يمكنك مراجعة هذا مقتطف الرمز.

خانات بديلة لتوصيل الطلبات

عند الدفع، إذا لم تكن الخانات المسبقة التي اقترحتها Google مناسبة، يمكن أن يقترح توصيل الطلبات بدائل باستخدام CheckoutResponseMessage الخاص بك.

لتحديد خانات بديلة للطلبات المسبقة، يُرجى الردّ على طلب الدفع باستخدام FoodErrorExtension واضبط القيم التالية:

  1. في المعلمة foodOrderErrors، حدد نوع الخطأ (مثل UNAVAILABLE_SLOT أو NO_CAPACITY أو CLOSED).
  2. في المعلَمة correctedProposedOrder، قدِّم P0M البديل أو قيمة FUTURE_SLOT عبر availableFulfillmentOptions.

يجب أن تكون الخانات البديلة خلال الأيام الـ 7 التالية من وقت الطلب. موضع الإعلان، وتشمل كل الخانات التي يمكن أن تحتوي عربة التسوق التي يطلبها المستخدم تحققه.

لنفترض مثلاً أنّ العروض الخاصة على الغداء متاحة من الاثنين إلى الجمعة فقط. من 11 ص إلى 1 بعد الظهر. يحاول المستخدم بعد ذلك إضافة عروض غداء خاصة إلى عربة التسوق ولكن الخانة التي اخترتها غير متاحة. في هذه الحالة، يجب أن يكون تنفيذ الاحتفاظ بعروض الغداء الخاصة في عربة التسوق، وإرجاع الخانات من الساعة 11 صباحًا إلى 1 ظهرًا فقط للأيام الـ 7 القادمة

يجب حذف الكائن correctedProposedOrder.Cart.fulfillmentPreference. في ردك.

إذا لم تكن هناك خانات متاحة، أو إذا لم يكن لدى المطعم أو الخدمة خانات الطلبات المسبقة، فلن تحتاج إلى تقديم correctedProposedOrder

يمكنك الاطّلاع على الأمثلة أدناه حول رسائل JSON بين عملية تنفيذ الطلب وGoogle. أثناء طلب الدفع وتدفق الاستجابة للطلب المسبق، عندما أن يكون المطعم أو الخدمة متاحًا لتلقّي الطلبات المُسبقة

مثال: طلب الدفع مع خانة التسليم

يعرض المقتطف أدناه مثالاً على طلب دفع يتضمّن طلبًا مسبقًا خانة التسليم.

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

مثال: قبول CheckoutResponse للخانة

يعرض المقتطف أدناه مثالاً على الرد على عملية الدفع، حيث تكون عملية توصيل الطلب خانات الطلبات المسبقة المقترحة.

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

مثال: CheckoutResponse مع خانات بديلة

يعرض المقتطف أدناه مثالاً على الرد على عملية الدفع، حيث تكون عملية توصيل الطلب وتقترح خانات بديلة للطلبات المسبقة. لاحظ أن يجب حذف الكائن correctedProposedOrder.Cart.fulfillmentPreference في ردك.

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

تنفيذ الطلبات المسبقة عند إرسال الطلب

عند إرسال الطلب، إذا كانت هناك مشكلة في خانات الطلبات المُسبَقة، يجب يجب أن يتضمن SubmitOrderResponseMessage السبب (مثل UNAVAILABLE_SLOT أو UNKNOWN) في الكائن RejectionInfo.

تعديل حالة الطلب من CREATED إلى CONFIRMED في المنتج OrderState عند قبول الطلب من قِبل مقدّم الخدمة. تضمين الفترة الزمنية التي اخترتها في رسالة التأكيد الإلكترونية المرسلة إلى المستخدم.

في حال إرسال سمة طريقة توفّر الطلب الطلب إلى المطعم في وقت لاحق، أرسِل إلى Google باستخدام إجراء تعديل الطلب غير المتزامن.

في الكائن OrderUpdate الخاص بنموذج الردّ على الطلب الذي أرسلته، أو أو تحديثات الطلب غير المتزامنة اللاحقة، بما في ذلك estimatedFulfillmentTimeIso8601 مع ضبط القيمة على النحو التالي:

  • عندما تكون حالة الطلب هي CREATED أو CONFIRMED، اضبط القيمة على وقت التسليم أو الاستلام الذي حدده المستخدم لطلبه المسبق.
  • عندما يكون هناك وقت مقدر أكثر دقة للتوصيل من المطعم أو خدمة، اضبط القيمة على الوقت المقدّر للتسليم أو وقت الاستلام.

مثال: SendOrderRequest مع خانة تسليم

يوضح المقتطف أدناه مثالاً لطلب إرسال يشير إلى خانة الطلب المسبق التي حددها المستخدم.

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

مثال: إرسال طلب إعادة النظر بقبول الطلب

يوضح المقتطف أدناه مثالاً على رد على إرسال طلب حيث يؤكد تنفيذ الطلب أنه قد قبل الطلب المسبق الذي قدمه المستخدم.

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

مثال: SendOrderResponse رفض الطلب بسبب عدم توفّر الخانة.

يوضح المقتطف أدناه مثالاً على استجابة إرسال طلب حيث تؤدي عملية التنفيذ إلى رفض طلب المستخدم المسبق بسبب عدم توفُّر خانة.

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

أمثلة على الطلبات المسبقة

يمكن استخدام النوع AdvanceServiceDeliveryHoursSpecification لتحديد ساعات التسليم أو الاستلام للمستخدمين لجدولة طلبهم مسبقًا.

ملاحظة: هناك فترتان زمنيتان منفصلتان يجب تحديدهما لتنفيذ الخدمة: فترة الطلب التي تحدّد الوقت الذي يمكن فيه للمستخدمين إجراء وفترة توصيل الطلب التي تحدّد وقت توصيل الطلب. تشير رسالة الأشكال البيانية يحدّد كائن OpeningHoursSpecification الحالات التي يقرّر فيها المستخدم تقديم الطلب. أوقات توصيل الطلب الفرعية (ServiceDeliveryHoursSpecification) أو AdvanceServiceDeliveryHoursSpecification) تحدّد الوقت الذي يمكن فيه تنفيذ الطلب تحقق.

يحدد المثال التالي ساعات الخدمة لقبول الطلبات المسبقة، مع فواصل خدمة مدتها 15 دقيقة.

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

يوضح المثال التالي كيفية تحديد أن الخدمة متاحة من أجل الطلبات في اليوم نفسه في يوم عيد الميلاد ولكن تم إغلاقها للطلبات المتقدّمة التي تم تحديد موعد لها في ذلك اليوم. يتوافق هذا المثال مع السيناريوهات التالية:

  • يمكن للمستخدمين تقديم طلب في 25 كانون الأول (ديسمبر) للتوصيل في اليوم نفسه.
  • يمكن للمستخدمين تقديم طلب مُسبق في 25 كانون الأول (ديسمبر) لتحديد موعد تسليمه. يوم 27 ديسمبر.
  • لا يمكن للمستخدمين تقديم طلب مسبق في 22 كانون الأول (ديسمبر) لتحديد موعد تسليمه. في 25 ديسمبر.
{
  "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"
  }
}

يوضح المثال التالي كيفية تحديد أن الخدمة مغلقة بسبب تقديم الطلبات في اليوم نفسه أو الطلبات المسبقة المجدولة في يوم عيد الميلاد، ولكن تكون مفتوحة للطلبات المتقدمة التي تمت جدولتها في يوم لاحق. يدعم هذا المثال ما يلي: السيناريوهات:

  • ولا يمكن للمستخدمين تقديم طلب في 25 كانون الأول (ديسمبر) للتوصيل في اليوم نفسه.
  • يمكن للمستخدمين تقديم طلب مُسبق في 25 كانون الأول (ديسمبر) لتحديد موعد تسليمه. يوم 27 ديسمبر.
  • لا يمكن للمستخدمين تقديم طلب مسبق في 22 كانون الأول (ديسمبر) لتحديد موعد تسليمه. في 25 ديسمبر.
{
  "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"
    }
  ]
}

تقبل الخدمة النموذجية التالية الطلبات على مدار 24 ساعة طوال أيام الأسبوع ويتم تسليمها من من 10 صباحًا حتى 2:59:59 مساءً خلال أيام الأسبوع:

...
{
  "@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"
    }
  }
}
...

يقبل نموذج الخدمة التالي الطلبات يوميًا من الساعة 8 صباحًا إلى الساعة 4:59:59 مساءً، يمكن للعملاء إما اختيار التوصيل في غضون ساعة، أو اختيار إحدى الخانات:

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

يعرض النموذج التالي حالة يفتح فيها المتجر من الساعة 8 صباحًا إلى الساعة 4:59:59 مساءً في أيام العمل ما عدا من الساعة 8 صباحًا حتى 6:59 مساءً في عطلات نهاية الأسبوع. لا يتم قبول الطلبات على مدار 24 ساعة طوال أيام الأسبوع.

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