v1 قابلیت سفارش از پیش

می‌توانید برای انجام سفارشات خود، پشتیبانی اضافه کنید تا کاربران از قبل سفارش‌های دریافت و تحویل غذا را برنامه‌ریزی کنند. قبل از اجرای این پشتیبانی در تکمیل، یک فید موجودی خدمات ایجاد کنید که ساعت‌هایی را برای کاربران برای ثبت سفارش‌های قبلی مشخص می‌کند، همانطور که در طرح فید موجودی توضیح داده شده است ( AdvanceServiceDeliveryHoursSpecification ).

اسلات های پیش خرید

Google بر اساس زمان انجام یک رستوران یا خدمات (همانطور که در AdvanceServiceDeliveryHoursSpecification ) تعریف شده است، اسلات های سفارش اولیه را در 15 دقیقه افزایش، تا 7 روز آینده پیشنهاد می کند.

برای بازیابی شکاف‌های سفارش پیشنهادی، از مقادیر زیر در فیلد fulfillmentPreference شی FoodCartExtension در هنگام پرداخت استفاده کنید:

  • PickupInfo.pickupTimeIso8601
  • DeliveryInfo.deliveryTimeIso8601

اجرای سفارشات پیش از پرداخت

جدول زیر راه‌های ممکنی را فهرست می‌کند که می‌توانید در زمان تسویه‌حساب، هنگامی که کاربران سعی می‌کنند سفارش دهند، پاسخ انجام خود را پیاده‌سازی کنید.

سناریو رفتار تحقق
برای اسلات درخواستی می توان سفارش قبلی را انجام داد. با ایجاد یک ProposedOrder با همان شکاف، سبد P0M ("در اسرع وقت") یا FUTURE_SLOT را بپذیرید. برای نمونه ای از پاسخ تسویه حساب که یک اسلات را می پذیرد، این قطعه کد را ببینید.
سفارش قبلی برای اسلات درخواستی قابل انجام نیست. تحقق شما باید موارد زیر را انجام دهد:
  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 بعد از ظهر موجود است. سپس کاربر سعی می کند غذاهای ویژه ناهار را به سبد خرید خود اضافه کند اما جایگاه انتخابی او در دسترس نیست. در این صورت، اجناس شما باید تخفیف‌های ویژه ناهار را در سبد خرید نگه دارد و فقط اسلات‌های ۱۱ صبح تا ۱ بعد از ظهر را برای ۷ روز آینده بازگرداند.

شما باید شیء correctedProposedOrder.Cart.fulfillmentPreference را در پاسخ خود حذف کنید.

اگر اسلات های موجود وجود ندارد، یا اگر رستوران یا خدمات از سفارشات قبلی پشتیبانی نمی کند، نیازی به ارائه یک correctedProposedOrder ندارید.

مثال‌های زیر را برای پیام‌های JSON بین انجام شما و Google در طول درخواست تسویه‌حساب و جریان پاسخ برای سفارش قبلی، زمانی که رستوران یا سرویس برای دریافت پیش‌سفارش در دسترس است، ببینید.

مثال: CheckoutRequest با اسلات تحویل

قطعه زیر نمونه ای از درخواست تسویه حساب با شکاف تحویل سفارش را نشان می دهد.

{
  "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 ، مقدار را روی زمان تحویل یا تحویل که کاربر برای سفارش قبلی خود برنامه ریزی کرده است، تنظیم کنید.
  • زمانی که زمان تحویل تخمینی دقیق تری از رستوران یا سرویس وجود دارد، مقدار را روی زمان تخمینی تحویل یا زمان تحویل قرار دهید.

مثال: SubmitOrderRequest با اسلات تحویل

قطعه زیر نمونه‌ای از درخواست ارسال سفارش را نشان می‌دهد که نشان‌دهنده شکاف سفارش قبلی است که کاربر انتخاب کرده است.

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

مثال: SubmitOrderResponse پذیرش سفارش

قطعه زیر نمونه‌ای از پاسخ ارسال سفارش را نشان می‌دهد که در آن انجام شما تأیید می‌کند که سفارش قبلی کاربر را پذیرفته است.

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

مثال: SubmitOrderResponse سفارش را به دلیل در دسترس نبودن اسلات رد می کند

قطعه زیر نمونه ای از پاسخ سفارش ارسال را نشان می دهد که در آن انجام شما به دلیل در دسترس نبودن اسلات، سفارش پیشبرد کاربر را رد می کند.

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

سرویس نمونه زیر سفارشات را 24x7 می پذیرد و از ساعت 10 صبح تا 14: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 بعد از ظهر باز است. سفارش 24x7 پذیرفته نمی شود.

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