Anda dapat menambahkan dukungan di pemenuhan pesanan agar pengguna dapat menjadwalkan pengambilan dan
untuk mengirim
pesanan makanan di muka. Sebelum menerapkan dukungan ini di
fulfillment, buat feed inventaris layanan yang menentukan jam buka untuk pengguna
untuk melakukan pemesanan di awal, seperti yang dijelaskan dalam skema feed inventaris
(AdvanceServiceDeliveryHoursSpecification
)
Slot pesanan di awal
Google mengusulkan slot pesanan di muka dengan kelipatan 15 menit, hingga 7 hari
sebelumnya, berdasarkan waktu pemenuhan untuk restoran atau layanan (sebagaimana dijelaskan dalam
AdvanceServiceDeliveryHoursSpecification
).
Untuk mengambil slot pesanan di muka yang diusulkan, gunakan nilai berikut dari
Kolom fulfillmentPreference
dari objek FoodCartExtension
saat checkout:
PickupInfo.pickupTimeIso8601
DeliveryInfo.deliveryTimeIso8601
Menerapkan pesanan di muka saat checkout
Tabel di bawah ini mencantumkan kemungkinan cara mengimplementasikan fungsi fulfillment Anda respons pada waktu {i>checkout<i} ketika pengguna mencoba melakukan pemesanan.
Skenario | Perilaku pemenuhan pesanan |
---|---|
Pesanan di awal dapat dipenuhi untuk slot yang diminta. | Setujui P0M ("sesegera mungkin") atau
FUTURE_SLOT keranjang dengan membuat ProposedOrder menggunakan
slot yang sama. Untuk contoh respons checkout yang menerima slot, lihat
cuplikan kode ini. |
Pesanan di 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 pesanan di muka yang diusulkan Google tidak sesuai,
fulfillment dapat menyarankan alternatif menggunakan CheckoutResponseMessage
.
Untuk menentukan slot pesanan di muka alternatif, tanggapi permintaan checkout dengan
FoodErrorExtension
, lalu tetapkan nilai berikut:
- Di parameter
foodOrderErrors
, tentukan jenis error (sepertiUNAVAILABLE_SLOT
,NO_CAPACITY
, atauCLOSED
). - Di parameter
correctedProposedOrder
, berikanP0M
atau NilaiFUTURE_SLOT
melaluiavailableFulfillmentOptions
.
Slot alternatif harus untuk 7 hari ke depan sejak waktu pemesanan dan menyertakan semua slot di mana keranjang yang diminta pengguna terpenuhi.
Misalnya, promo makan siang hanya tersedia dari Senin hingga Jumat dari pukul 11.00 hingga 13.00. Pengguna kemudian mencoba menambahkan makan siang spesial ke keranjang mereka tetapi slot yang dipilih tidak tersedia. Dalam hal ini, fulfillment Anda harus simpan spesial makan siang di keranjang, dan kembalikan hanya slot pukul 11.00 - 13.00 selama 7 hari ke depan
Anda harus menghapus objek correctedProposedOrder.Cart.fulfillmentPreference
dalam respons Anda.
Jika tidak ada slot yang tersedia, atau jika restoran atau layanan tidak
mendukung pesanan di muka, maka Anda tidak perlu menyediakan
correctedProposedOrder
.
Lihat contoh di bawah untuk pesan JSON antara fulfillment Anda dan Google selama alur permintaan {i>checkout<i} dan respons untuk pesanan di muka, ketika restoran atau layanan tersedia untuk menerima praorder.
Contoh: CheckoutRequest dengan slot pengiriman
Cuplikan di bawah ini menampilkan contoh permintaan checkout dengan pesanan di muka slot pengiriman.
{
"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 menerima slot
Cuplikan di bawah ini menunjukkan contoh respons checkout di mana fulfillment Anda menerima slot pesanan 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 ini menunjukkan contoh respons checkout di mana fulfillment Anda
menawarkan slot pesanan awal alternatif. Perhatikan bahwa
Objek correctedProposedOrder.Cart.fulfillmentPreference
harus dihilangkan di
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": {
...
}
}
}
}
]
}
}
}
Menerapkan pesanan di muka pada saat pengiriman
Saat pengiriman pesanan, jika ada masalah dengan slot pesanan di awal,
SubmitOrderResponseMessage
harus menyertakan alasan (seperti
UNAVAILABLE_SLOT
atau UNKNOWN
) dalam objek RejectionInfo
.
Perbarui status pesanan dari CREATED
menjadi CONFIRMED
di
OrderState
jika pesanan diterima oleh penyedia. Sertakan
slot waktu yang dipilih dalam email konfirmasi Anda kepada pengguna.
Jika {i>fulfillment <i}Anda mengirimkan pesanan ke restoran nanti, kirimkan lakukan update menggunakan Tindakan Pembaruan Pesanan Asinkron.
Di objek OrderUpdate
respons pesanan kirim pemenuhan Anda atau
pembaruan urutan asinkron berikutnya, termasuk
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. - Saat ada estimasi waktu pengiriman yang lebih akurat dari restoran atau layanan, tetapkan nilai ke estimasi waktu pengiriman atau pengambilan.
Contoh: SubmitOrderRequest dengan slot penayangan
Cuplikan di bawah ini menampilkan contoh permintaan pengiriman yang mengindikasikan 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 menyetujui pesanan
Cuplikan di bawah ini menunjukkan contoh respons kirim pesanan di mana pemenuhan pesanan mengonfirmasi bahwa telah menerima pesanan di muka dari pengguna.
{
"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 ini menunjukkan contoh respons kirim pesanan di mana fulfillment menolak pesanan di muka pengguna karena slot yang 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 pesanan di awal
Jenis AdvanceServiceDeliveryHoursSpecification
dapat digunakan untuk menentukan
waktu pengiriman atau pengambilan bagi pengguna
untuk menjadwalkan pesanan mereka terlebih dahulu.
Catatan: Ada dua periode waktu terpisah yang harus Anda tentukan
untuk pemenuhan layanan: periode pemesanan yang menentukan kapan pengguna dapat menempatkan
pesanan, dan periode pemenuhan pesanan yang menentukan kapan pesanan dipenuhi. Tujuan
Objek
menentukan kapan pengguna
dapat melakukan pemesanan. Waktu fulfillment turunannya (OpeningHoursSpecification
atau ServiceDeliveryHoursSpecification
) tentukan kapan urutan dapat
terpenuhi.AdvanceServiceDeliveryHoursSpecification
Contoh berikut menentukan jam layanan untuk menerima pesanan di muka, dengan interval servis 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 menetapkan bahwa layanan telah dibuka untuk pesanan di hari yang sama pada hari Natal tetapi ditutup untuk pesanan lanjutan yang dijadwalkan pada hari itu. Contoh ini mendukung skenario berikut:
- Pengguna dapat melakukan pemesanan pada tanggal 25 Desember untuk pengiriman di hari yang sama.
- Pengguna dapat melakukan pemesanan di awal pada tanggal 25 Desember untuk pengiriman terjadwal untuk 27 Desember.
- Pengguna tidak dapat melakukan pemesanan di awal pada tanggal 22 Desember untuk pengiriman terjadwal 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 menetapkan bahwa layanan akan ditutup untuk pesanan pada hari yang sama atau pesanan di muka yang dijadwalkan untuk hari Natal, tetapi terbuka pesanan di muka yang dijadwalkan untuk hari berikutnya. Contoh ini mendukung hal berikut skenario:
- Pengguna tidak dapat melakukan pemesanan pada tanggal 25 Desember untuk pengiriman di hari yang sama.
- Pengguna dapat melakukan pemesanan di awal pada tanggal 25 Desember untuk pengiriman terjadwal untuk 27 Desember.
- Pengguna tidak dapat melakukan pemesanan di awal pada tanggal 22 Desember untuk pengiriman terjadwal 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 24/7 dan dikirim dari 10.00-14.59.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-16.59.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 menampilkan kasus saat toko buka pukul 08.00-16.59.59 pada hari kerja tetapi pukul 08.00-18.59 pada akhir pekan. Pesanan tidak diterima dalam waktu 24/7.
... { // 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" } } ] } ...