Anda dapat menambahkan dukungan dalam fulfillment untuk pengguna guna menjadwalkan pesanan makanan untuk diambil dan
dikirimkan terlebih dahulu. Sebelum menerapkan dukungan ini dalam
fulfillment, buat feed inventaris layanan yang menentukan jam bagi pengguna
untuk melakukan pemesanan awal, seperti yang dijelaskan dalam skema feed inventaris
(AdvanceServiceDeliveryHoursSpecification
).
Slot praorder
Google mengusulkan slot pemesanan awal dengan penambahan 15 menit, hingga 7 hari
mendatang, berdasarkan waktu pemenuhan untuk restoran atau layanan (seperti yang ditentukan dalam
AdvanceServiceDeliveryHoursSpecification
).
Untuk mengambil slot pemesanan di muka yang diusulkan, gunakan nilai berikut dari
kolom fulfillmentPreference
objek FoodCartExtension
saat checkout:
PickupInfo.pickupTimeIso8601
DeliveryInfo.deliveryTimeIso8601
Menerapkan praorder saat checkout
Tabel di bawah ini mencantumkan kemungkinan cara untuk menerapkan respons fulfillment pada waktu checkout saat pengguna mencoba melakukan pemesanan.
Skenario | Perilaku fulfillment |
---|---|
Pesanan di muka dapat dipenuhi untuk slot yang diminta. | Terima keranjang P0M ("sesegera mungkin") atau
FUTURE_SLOT dengan membuat ProposedOrder dengan
slot yang sama. Untuk contoh respons checkout yang menerima slot, lihat
cuplikan kode ini. |
Pesanan awal tidak dapat dipenuhi untuk slot yang diminta. | Fulfillment Anda harus melakukan hal berikut:
Untuk contoh respons checkout yang mengusulkan slot alternatif, lihat cuplikan kode ini. |
Slot alternatif untuk pemenuhan pesanan
Saat checkout, jika slot pemesanan di muka yang diusulkan oleh Google tidak sesuai, fulfillment
Anda dapat menyarankan alternatif menggunakan objek
CheckoutResponseMessage
.
Untuk menentukan slot pemesanan awal alternatif, respons permintaan checkout dengan
FoodErrorExtension
dan tetapkan nilai berikut:
- Pada parameter
foodOrderErrors
, tentukan jenis error (sepertiUNAVAILABLE_SLOT
,NO_CAPACITY
, atauCLOSED
). - Di parameter
correctedProposedOrder
, berikan nilaiP0M
atauFUTURE_SLOT
alternatif melaluiavailableFulfillmentOptions
.
Slot alternatif harus berlaku selama 7 hari ke depan sejak waktu penempatan pesanan, dan menyertakan semua slot tempat keranjang yang diminta pengguna dapat dipenuhi.
Misalnya, menu spesial makan siang hanya tersedia dari Senin hingga Jumat dari pukul 11.00 hingga 13.00. Kemudian, pengguna mencoba menambahkan menu spesial makan siang ke keranjang, tetapi slot yang dipilih tidak tersedia. Dalam hal ini, fulfillment Anda harus mempertahankan menu spesial makan siang di keranjang, dan hanya menampilkan slot pukul 11.00 hingga 13.00 untuk 7 hari ke depan
Anda harus menghapus objek correctedProposedOrder.Cart.fulfillmentPreference
dalam respons.
Jika tidak ada slot yang tersedia, atau jika restoran atau layanan tidak
mendukung pemesanan di muka, Anda tidak perlu memberikan
correctedProposedOrder
.
Lihat contoh di bawah untuk pesan JSON antara fulfillment Anda dan Google selama alur permintaan dan respons checkout untuk pesanan di muka, saat restoran atau layanan tersedia untuk menerima praorder.
Contoh: CheckoutRequest dengan slot pengiriman
Cuplikan di bawah menunjukkan contoh permintaan checkout dengan slot pengiriman pesanan di muka.
{
"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": {
...
}
}
}
}
]
}
]
}
Contoh: CheckoutResponse yang menerima slot
Cuplikan di bawah menunjukkan contoh respons checkout tempat fulfillment Anda menerima slot pemesanan awal yang diusulkan.
{
"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": {
...
}
}
}
}
]
}
}
}
Contoh: CheckoutResponse dengan slot alternatif
Cuplikan di bawah menunjukkan contoh respons checkout tempat fulfillment Anda
mengusulkan slot pemesanan awal alternatif. Perhatikan bahwa
objek correctedProposedOrder.Cart.fulfillmentPreference
harus dihilangkan dalam
respons Anda.
{
"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": {
...
}
}
}
}
]
}
}
}
Mengimplementasikan praorder saat mengirimkan pesanan
Saat pengiriman pesanan, jika ada masalah dengan slot pesanan awal, SubmitOrderResponseMessage
Anda harus menyertakan alasannya (seperti
UNAVAILABLE_SLOT
atau UNKNOWN
) dalam objek RejectionInfo
.
Perbarui status pesanan dari CREATED
menjadi CONFIRMED
di
objek OrderState
saat pesanan disetujui oleh penyedia. Sertakan
slot waktu yang dipilih dalam email konfirmasi Anda kepada pengguna.
Jika fulfillment Anda mengirimkan pesanan ke restoran nanti, kirimkan update ke Google menggunakan Tindakan Pembaruan Pesanan Asinkron.
Dalam objek OrderUpdate
dari respons kirim pesanan fulfillment atau
update pesanan asinkron berikutnya, sertakan
estimatedFulfillmentTimeIso8601
dengan nilai yang ditetapkan sebagai berikut:
- Jika status pesanan adalah
CREATED
atauCONFIRMED
, tetapkan nilai ke waktu pengiriman atau pengambilan yang dijadwalkan pengguna untuk pesanan di muka. - Jika ada perkiraan waktu pengiriman yang lebih akurat dari restoran atau layanan, tetapkan nilai ke perkiraan waktu pengiriman atau waktu pengambilan.
Contoh: SubmitOrderRequest dengan slot pengiriman
Cuplikan di bawah menunjukkan contoh permintaan kirim pesanan yang menunjukkan slot pesanan awal yang dipilih pengguna.
{
"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": {
...
}
}
}
}
]
}
]
}
Contoh: SubmitOrderResponse yang menyetujui pesanan
Cuplikan di bawah menunjukkan contoh respons kirim pesanan saat fulfillment Anda mengonfirmasi bahwa pesanan awal pengguna telah diterima.
{
"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"
}
}
}
}
]
}
}
}
Contoh: SubmitOrderResponse menolak pesanan karena slot tidak tersedia
Cuplikan di bawah menunjukkan contoh respons pengiriman pesanan saat fulfillment Anda menolak pesanan awal pengguna karena slot tidak tersedia.
{
"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": [
...
]
}
}
}
]
}
}
}
Contoh pemesanan awal
Jenis AdvanceServiceDeliveryHoursSpecification
dapat digunakan untuk menentukan
jam pengiriman atau pengambilan bagi pengguna untuk menjadwalkan pesanan mereka terlebih dahulu.
Catatan: Ada dua periode waktu terpisah yang harus Anda tentukan
untuk fulfillment layanan: periode pemesanan yang menentukan kapan pengguna dapat melakukan
pesanan, dan periode fulfillment yang menentukan kapan pesanan akan dipenuhi. Objek
menentukan kapan pengguna
dapat melakukan pemesanan. Waktu fulfillment turunannya (OpeningHoursSpecification
atau ServiceDeliveryHoursSpecification
) menentukan kapan pesanan dapat
dipenuhi.AdvanceServiceDeliveryHoursSpecification
Contoh berikut menentukan jam layanan untuk menerima pesanan awal, dengan interval layanan 15 menit.
{ "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" } } ] } ] }
Contoh berikut menunjukkan cara menentukan bahwa layanan buka untuk pesanan pada hari yang sama pada hari Natal, tetapi tutup untuk pesanan awal yang dijadwalkan untuk hari itu. Contoh ini mendukung skenario berikut:
- Pengguna dapat melakukan pemesanan pada 25 Desember untuk pengiriman pada hari yang sama.
- Pengguna dapat melakukan pemesanan di muka pada 25 Desember untuk pengiriman yang dijadwalkan pada 27 Desember.
- Pengguna tidak dapat melakukan pemesanan di muka pada 22 Desember untuk pengiriman yang dijadwalkan pada 25 Desember.
{ "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" } }
Contoh berikut menunjukkan cara menentukan bahwa layanan ditutup untuk pesanan pada hari yang sama atau pesanan awal yang dijadwalkan untuk hari Natal, tetapi buka untuk pesanan awal yang dijadwalkan untuk hari berikutnya. Contoh ini mendukung skenario berikut:
- Pengguna tidak dapat melakukan pemesanan pada 25 Desember untuk pengiriman pada hari yang sama.
- Pengguna dapat melakukan pemesanan di muka pada 25 Desember untuk pengiriman yang dijadwalkan pada 27 Desember.
- Pengguna tidak dapat melakukan pemesanan di muka pada 22 Desember untuk pengiriman yang dijadwalkan pada 25 Desember.
{ "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" } ] }
Contoh Layanan berikut menerima pesanan 24x7 dan mengirimkan dari pukul 10.00-23.59 pada hari kerja:
... { "@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" } } } ...
Contoh Layanan berikut menerima pesanan setiap hari mulai pukul 08.00-23.59, dan pelanggan dapat memilih pengiriman dalam waktu satu jam, atau memilih salah satu slot:
... { "@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" } } ] } ...
Contoh berikut menunjukkan kasus saat toko buka pukul 08.00-20.59.59 pada hari kerja, tetapi pukul 08.00-18.59 pada akhir pekan. Pesanan tidak diterima 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" } } ] } ...