Feed menu pemetaan dan item keranjang pemenuhan
Ketika pelanggan menambahkan item dari feed Menu ke keranjang mereka dan melakukan {i>check out<i}, Google mengirimkan item tersebut ke endpoint pemenuhan Anda untuk memverifikasi harga dan ketersediaan tinggi. Setelah harga dan ketersediaan divalidasi, pelanggan dapat melakukan pemesanan. Bagian ini mengilustrasikan cara memetakan elemen feed menu ke item keranjang pemenuhan.
Contoh di bagian ini adalah versi feed Menu dan Keranjang yang disederhanakan
skema. Hanya kolom yang relevan untuk menggambarkan pemetaan antara feed Menu dan
objek Cart ditampilkan. Untuk skema lengkap, lihat Menu
dan Cart
.
Item di feed Menu
yang ditambahkan ke keranjang dikirim di Cart
untuk checkout dan pengiriman pesanan.
MenuItem
sederhana direpresentasikan sebagaiLineItem
dilineItems
array denganofferId
menjadioffer.id
item menu yang dipilih di Menu feed Anda.MenuItem
denganMenuItemOption
yang diperlukan direpresentasikan sebagaiLineItem
dalam arraylineItems
denganofferId
yang dipilih menu itemoffer.id
dari umpan Menu.AddOnMenuItem
dariLineItem
direpresentasikan sebagaiFoodItemOption
dalam arrayoptions
dariFoodItemExtension
. Setiap opsi memilikiofferId
yang sesuai dengan menu add-on yang dipilihoffer.id
item dari feed Menu. Perhatikan bahwa AddOnMenuItem juga dapat memiliki AddOnMenuItem bertingkat yang ditampilkan sebagaisubOptions
di dalam setiap sebelumnya.
Contoh berikut memetakan item menu antara feed menu dan fulfillment keranjang.
JSON
Contoh ini berisi daftar item menu sederhana.
Item menu di Feed menu:
{ "@type": "Menu", "@id": "menu_id", "hasMenuItem": [ { "@type": "MenuItem", "@id": "menuitem_id_1", "offers": [ { "@type": "Offer", "@id": "menuitem_offer_id_1", "price": "p_1", "priceCurrency": "USD" } ] }, { "@type": "MenuItem", "@id": "menuitem_id_2", "offers": [ { "@type": "Offer", "@id": "menuitem_offer_id_2", "price": "p_2", "priceCurrency": "USD" } ] } ] }
Item menu yang dipetakan ke keranjang pemenuhan pesanan:
{ "@type": "Cart", "lineItems": [ { "offerId": "menuitem_offer_id_1", "price": { "amount": { "currencyCode": "USD", "units": "dollar(q_1*p_1)", "nanos": "cent(q_1*p_1)" } }, "quantity": "q_1" }, { "offerId": "menuitem_offer_id_2", "price": { "amount": { "currencyCode": "USD", "units": "dollar(q_2*p_2)", "nanos": "cent(q_2*p_2)" } }, "quantity": "q_2" } ] }
JSON
Contoh ini berisi item menu dengan satu atau beberapa AddOnMenuItems.
Item menu di Feed menu:
{ "@type": "Menu", "@id": "menu_id", "hasMenuItem": [ { "@type": "MenuItem", "@id": "menuitem_id_1", "offers": [ { "@type": "Offer", "@id": "menuitem_offer_id_1", "price": "p_1", "priceCurrency": "USD" } ], "menuAddOn": [ { "@type": "MenuAddOnSection", "@id": "menuaddon_section_id_1", "hasMenuItem": [ { "@type": "AddOnMenuItem", "@id": "menuitem_addon_id_1", "offers": [ { "@type": "Offer", "@id": "menuitem_addon_offer_id_1", "price": "addon_p_1", "priceCurrency": "USD" } ] }, { "@type": "AddOnMenuItem", "@id": "menuitem_addon_id_2", "offers": [ { "@type": "Offer", "@id": "menuitem_addon_offer_id_2", "price": "addon_p_2", "priceCurrency": "USD" } ] } ] } ] }, { "@type": "MenuItem", "@id": "menuitem_id_2", "offers": [ { "@type": "Offer", "@id": "menuitem_offer_id_2", "price": "p_2", "priceCurrency": "USD" } ] } ] }
Item menu yang dipetakan ke keranjang pemenuhan pesanan:
{ "@type": "Cart", "lineItems": [ { "offerId": "menuitem_offer_id_1", "price": { "amount": { "currencyCode": "USD", "units": "dollar(q_1*(p_1 + addon_q_1*addon_p_1 + addon_q_2*addon_p_2))", "nanos": "cent(q_1*(p_1 + addon_q_1*addon_p_1 + addon_q_2*addon_p_2))" } }, "quantity": "q_1", "extension": { "@type": "FoodItemExtension", "options": [ { "offerId": "menuitem_addon_offer_id_1", "price": { "currencyCode": "USD", "units": "dollar(addon_q_1*addon_p_1)", "nanos": "cent(addon_q_1*addon_p_1)" }, "quantity": "addon_q_1" }, { "offerId": "menuitem_addon_offer_id_2", "price": { "currencyCode": "USD", "units": "dollar(addon_q_2*addon_p_2)", "nanos": "cent(addon_q_2*addon_p_2)" }, "quantity": "addon_q_2" } ] } }, { "offerId": "menuitem_offer_id_2", "price": { "amount": { "currencyCode": "USD", "units": "dollar(q_2*p_2)", "nanos": "cent(q_2*p_2)" } }, "quantity": "q_2" } ] }
JSON
Contoh ini berisi item menu dengan opsi item menu, AddOnMenuItems, dan AddOnMenuItems bertingkat
Item menu di Feed menu:
{ "@type": "MenuItem", "@id": "menuitem_id_1", "hasMenuItemOptions": [ { "@type": "MenuItemOption", "value": { "@type": "PropertyValue", "name": "OPTION", "value": "Large", "offers": [ { "@type": "Offer", "@id": "menuitem_option_offer_id_1", "price": "p_1", "priceCurrency": "USD" } ], "menuAddOn": [ { "@type": "AddOnMenuSection", "@id": "menuitem_option_addon_section_id_1", "hasMenuItem": [ { "@type": "AddOnMenuItem", "@id": "menuitem_option_addon_id_1", "offers": [ { "@type": "Offer", "@id": "menuitem_option_addon_offer_id_1", "price": "addon_p_1", "priceCurrency": "USD" } ] }, { "@type": "AddOnMenuItem", "@id": "menuitem_option_addon_id_2", "offers": [ { "@type": "Offer", "@id": "menuitem_option_addon_offer_id_2", "price": "addon_p_2", "priceCurrency": "USD" } ], "menuAddOn": [ { "@type": "AddOnMenuSection", "@id": "menuitem_option_subaddon_section_id_1", "hasMenuItem": [ { "@type": "AddOnMenuItem", "@id": "menuitem_option_subaddon_id_1", "offers": [ { "@type": "Offer", "@id": "menuitem_option_subaddon_offer_id_1", "price": "subaddon_p_1", "priceCurrency": "USD" } ] } ] } ] } ] } ] } } ] }
Item menu yang dipetakan ke keranjang pemenuhan pesanan:
{ "@type": "Cart", "lineItems": [ { "offerId": "menuitem_option_offer_id_1", "price": { "amount": { "currencyCode": "USD", "units": "dollar(q_1*(p_1 + addon_q_1*addon_p_1 + addon_q_2*(addon_p_2 + subaddon_q_1*subaddon_p_1)))", "nanos": "cent(q_1*(p_1 + addon_q_1*addon_p_1 + addon_q_2*(addon_p_2 + subaddon_q_1*subaddon_p_1)))" } }, "quantity": "q_1", "extension": { "@type": "FoodItemExtension", "options": [ { "offerId": "menuitem_option_addon_offer_id_1", "price": { "currencyCode": "USD", "units": "dollar(addon_q_1*addon_p_1)", "nanos": "cent(addon_q_1*addon_p_1)" }, "quantity": "addon_q_1" }, { "offerId": "menuitem_option_addon_offer_id_2", "price": { "currencyCode": "USD", "units": "dollar(addon_q_2*(addon_p_2 + subaddon_q_1*subaddon_p_1))", "nanos": "cent(addon_q_2*(addon_p_2 + subaddon_q_1*subaddon_p_1))" }, "quantity": "addon_q_2", "subOptions": [ { "offerId": "menuitem_option_subaddon_offer_id_1", "price": { "currencyCode": "USD", "units": "dollar(subaddon_q_1*subaddon_p_1)", "nanos": "cent(subaddon_q_1*subaddon_p_1)" }, "quantity": "subaddon_q_1" } ] } ] } } ] }
Menangani error
Jika mengalami masalah saat memproses CheckoutRequestMessage
, Anda
dapat merespons dengan CheckoutResponseMessage
yang berisi
FoodErrorExtension
, bukan CheckoutResponse. Anda dapat menggunakan
respons untuk mengidentifikasi satu atau
lebih kesalahan yang terjadi selama pemrosesan.
Ada 2 cara untuk menangani error:
- Kesalahan yang dapat dipulihkan: Pengguna tidak diharuskan mengedit keranjang untuk mengirim
pesanan. Misalnya, jika Anda menentukan bahwa item dalam
Cart
memiliki perubahan harga, Anda dapat merespons denganFoodOrderError
jenis errorPRICE_CHANGED
, besertacorrectedProposedOrder
danpaymentOptions
. Google memberi tahu pengguna tentang perubahan tersebut, tetapi mengizinkan pengguna mengirimkan dengancorrectedProposedOrder
. Pengguna juga dapat kembali dan mengedit keranjang mereka jika yang diinginkan. Anda akan menerimaCheckoutRequestMessage
baru atauSubmitOrderRequestMessage
. - Error yang tidak dapat dipulihkan: Pengguna diwajibkan untuk mengedit keranjang sebelum
mengirimkan pesanan. Misalnya, jika Anda menentukan
bahwa restoran tersebut
ditutup, Anda dapat merespons dengan
FoodOrderError
jenis errorCLOSED
. Google akan memberi tahu pengguna dan mengelola interaksi untuk diperbarui ke interaksi restoran. Anda akan menerimaCheckoutRequestMessage
baru untuk keranjang.
Secara umum, buat error tingkat keranjang tidak dapat dipulihkan dan error tingkat item
dapat dipulihkan. Untuk daftar lengkap jenis kesalahan dan artinya, lihat
FoodOrderError
Menangani perubahan harga
Perubahan harga saat checkout
Jika Anda mengalami masalah harga saat memproses checkout pelanggan , lakukan hal berikut:
- Respons
CheckoutRequestMessage
denganCheckoutResponseMessage
yang berisiFoodErrorExtension
, sebagai yang dijelaskan dalam Menangani error. - Dalam respons error, gunakan
correctedProposedOrder.cart
untuk memperbarui harga ke nilai yang benar. Google menerima pesanan yang telah diperbaiki dan dapat menerbitkanCheckoutRequestMessage
Setelah {i>checkout<i}, Google menampilkan
halaman konfirmasi pesanan kepada pengguna akhir,
terlepas dari apakah ProposedOrder
telah diubah atau tidak.
Jika Usulan Pesanan dikoreksi, Google dapat menampilkan peringatan tambahan kepada
menginformasikan perubahan
tersebut kepada pengguna. Jika pengguna setuju untuk melakukan pemesanan,
tidak akan ada lagi permintaan checkout. Alurnya berlanjut ke urutan pengiriman, dengan
ProposedOrder
yang sudah dikoreksi.
Namun, pengguna selalu dapat berubah pikiran dan mengedit keranjang mereka lagi. Kapan
memperbarui keranjangnya dengan cara ini, Google mengirimkan CheckoutRequestMessage
baru.
Perubahan harga selama pesanan pengiriman
Jika Anda mengalami masalah harga saat memproses pengiriman pesanan
(intent actions.intent.TRANSACTION_DECISION
dipicu), jangan respons
dengan error atau memperbarui harga dalam respons Anda. Jika harga, jumlah,
atau detail lainnya di SubmitOrderRequestMessage
tidak sesuai dengan
data Anda, respons dengan orderState
yang disetel ke REJECTED
untuk menunjukkan bahwa
pesanan tidak dapat dilakukan seperti yang diminta.
Kemudian, jika detail pesanan dan pembayaran valid, tetapkan orderState
ke CREATED
atau CONFIRMED
. Selain itu, sertakan actionOrderId
untuk mewakili ID pesanan di
sistem Anda. ID ini harus digunakan saat mengirimkan update berikutnya.
Jika Anda tidak dapat memproses pembayaran dan telah mengirimkan
SubmitOrderRequestMessage
, Anda dapat mengirim
AsyncOrderUpdateRequestMessage
dengan orderState
ditetapkan ke REJECTED
untuk mengizinkan
pengguna tahu bahwa
pesanan tidak akan diselesaikan.
Perubahan harga setelah pesanan dikirim
Jika Anda menentukan bahwa harga telah berubah dari harga yang digunakan saat pelanggan
mengirimkan pesanannya, Anda dapat menerbitkan AsyncOrderUpdateRequestMessage
, sebagai
yang dijelaskan dalam Menerapkan Pembaruan Pesanan Asinkron dengan harga baru.
Untuk memperbarui harga menggunakan pembaruan pesanan asinkron:
- Ubah harga dalam
lineItemUpdates[x].price
. Ini mencerminkan total biaya item, termasuk {i>add-on<i} dan dengan kuantitas. (Untuk informasi selengkapnya, lihat deskripsi Kolomprice
dariLineItem
.) - Masukkan penjelasan dalam bahasa
lineItemUpdates[x].reason
. - Setel
lineItemUpdates[x].orderState
keCONFIRMED
.
Anda dapat mencoba menagih instrumen pembayaran sebelum atau setelah mengirimkan
AsyncOrderUpdateRequestMessage, sesuai pertimbangan Anda. Jika transaksi gagal
(mungkin karena delta harga terlalu tinggi), kirim
AsyncOrderUpdateRequestMessage dengan setelan berikut pada
OrderUpdate
untuk memberi tahu Google tentang kegagalan tersebut:
- Tetapkan
orderState
keREJECTED
. - Jelaskan kegagalan di kolom
label
.
Validasi checkout
Seperti yang dibahas di Langkah 4: Terapkan Checkout,
fulfillment endpoint harus melakukan validasi pada setiap
CheckoutRequestMessage
, dan balas dengan CheckoutResponseMessage
.
Berikut contoh CheckoutResponseMessage
untuk
validasi:
Kasus penggunaan | Cara menerapkan |
---|---|
Kasus penggunaan 1: Validasi berhasil | Kembalikan CheckoutResponse . Harus memiliki
ProposedOrder dan PaymentOptions .
ProposedOrder sudah termasuk pajak, biaya, dan harga total
keranjang. |
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "checkoutResponse": { "proposedOrder": { "id": "sample_proposed_order_id_1", "otherItems": [ { "name":"New customer discount", "price": { "type":"ESTIMATE", "amount": { "currencyCode":"USD", "units":"-5", "nanos": -500000000 } }, "type": "DISCOUNT" }, { "name": "Delivery fee", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "3", "nanos": 500000000 } }, "type": "DELIVERY" }, { "name": "Tax", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "1", "nanos": 500000000 } }, "type": "TAX" } ], "cart": { "merchant": { "id": "https://www.exampleprovider.com/merchant/id1", "name": "Falafel Bite" }, "lineItems": [ { "name": "Pita Chips", "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": "2", "nanos": 750000000 } }, "subLines": [ { "note": "Notes for this item." } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension", "options": [ { "id": "sample_addon_offer_id_1", "offerId": "https://www.exampleprovider.com/menu/item/addon/offer/id1", "name": "Honey Mustard", "price": { "currencyCode": "USD" }, "quantity": 1 }, { "id": "sample_addon_offer_id_2", "offerId": "https://www.exampleprovider.com/menu/item/addon/offer/id2", "name": "BBQ Sauce", "price": { "currencyCode": "USD", "nanos": 500000000 }, "quantity": 1 } ] } }, { "name": "Chicken Shwarma Wrap", "type": "REGULAR", "id": "sample_item_offer_id_2", "offerId": "https://www.exampleprovider.com/menu/item/offer/id2", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "8" } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } }, { "name": "Greek Salad", "type": "REGULAR", "id": "sample_item_offer_id_3", "offerId": "https://www.exampleprovider.com/menu/item/offer/id3", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "9", "nanos": 990000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } }, { "name": "Prawns Biryani", "type": "REGULAR", "id": "sample_item_offer_id_4", "offerId": "https://www.exampleprovider.com/menu/item/offer/id4", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "15", "nanos": 990000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension", "fulfillmentPreference": { "fulfillmentInfo": { "delivery": { "deliveryTimeIso8601": "P90M" } } }, "location": { "coordinates": { "latitude": 37.788783, "longitude": -122.41384 }, "formattedAddress": "1350 CHARLESTON ROAD, MOUNTAIN VIEW, CA, United States", "zipCode": "94043", "city": "Mountain View", "postalAddress": { "regionCode": "US", "postalCode": "94043", "administrativeArea": "CA", "locality": "Mountain View", "addressLines": [ "1350 Charleston Road" ] }, "notes": "Gate code is #111" } } }, "totalPrice": { "type": "ESTIMATE", "amount": { // Represents $36.73 "currencyCode": "USD", "units": "36", "nanos": 730000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension", "availableFulfillmentOptions": [ { "fulfillmentInfo": { "delivery": { "deliveryTimeIso8601": "P90M" } }, "expiresAt": "2017-07-17T12:30:00Z" } ] } }, "paymentOptions": { "googleProvidedOptions": { "tokenizationParameters": { "tokenizationType": "PAYMENT_GATEWAY", "parameters": { "gateway": "stripe", "stripe:publishableKey": "pk_live_stripe_client_key", "stripe:version": "2017-04-06" } }, "supportedCardNetworks": [ "AMEX", "DISCOVER", "MASTERCARD", "JCB", "VISA" ], "prepaidCardDisallowed": true } } } } } ] } } }
Validasi alamat pengiriman
Endpoint pemenuhan Anda harus memvalidasi alamat pengiriman yang ada di setiap
CheckoutRequestMessage
Jika ada masalah dengan alamat pengiriman, seperti berada di luar jangkauan
layanan pengiriman, CheckoutResponseMessage
yang ditampilkan oleh
fulfillment harus berisi FoodOrderError
dari jenis yang sesuai.
Kasus penggunaan | Cara menerapkan |
---|---|
Kasus penggunaan 1: Validasi gagal karena alamat pengiriman tidak ditemukan rentang atau ada masalah dengan alamat pengiriman | Kembalikan FoodErrorExtension dengan FoodOrderError
dari jenis error OUT_OF_SERVICE_AREA . |
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "OUT_OF_SERVICE_AREA", "description": "Sorry, the restaurant cannot deliver to your address." } ] } } } ] } } }
Validasi nilai pesanan minimum
Endpoint pemenuhan Anda harus memvalidasi nilai pesanan minimum masing-masing
CheckoutRequestMessage
Jika nilai pesanan minimum tidak terpenuhi, CheckoutResponseMessage
yang ditampilkan oleh fulfillment Anda harus berisi FoodOrderError
jenis error
REQUIREMENTS_NOT_MET
.
Kasus penggunaan | Cara menerapkan |
---|---|
Kasus penggunaan 1: Validasi gagal karena nilai pesanan minimum tidak terpenuhi | Kembalikan FoodErrorExtension dengan FoodOrderError
dari jenis error REQUIREMENTS_NOT_MET . |
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "REQUIREMENTS_NOT_MET", "description": "The cart subtotal must be over $20." } ] } } } ] } } }
Validasi periode pemesanan
Endpoint pemenuhan Anda harus memvalidasi faktor apa pun yang dapat memengaruhi
periode pemesanan untuk setiap CheckoutRequestMessage
.
Misalnya, jika restoran tutup atau tidak lagi menerima pesanan di
saat ini, CheckoutResponseMessage
yang ditampilkan oleh fulfillment Anda akan
berisi FoodOrderError
jenis error CLOSED
atau NO_CAPACITY
,
secara berurutan.
Kasus penggunaan | Cara menerapkan |
---|---|
Kasus penggunaan 1: Validasi gagal karena restoran tutup atau tidak lagi didukung | Kembalikan FoodErrorExtension dengan FoodOrderError
dari jenis error CLOSED . |
Kasus penggunaan 2: Validasi gagal karena restoran sedang sibuk dan tidak menerima pesanan saat ini | Kembalikan FoodErrorExtension dengan FoodOrderError
dari jenis error NO_CAPACITY . |
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "CLOSED", "description": "The restaurant is closed." } ] } } } ] } } }
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "NO_CAPACITY", "description": "Sorry, the restaurant is busy at the moment." } ] } } } ] } } }
Validasi item keranjang
Endpoint pemenuhan Anda harus memvalidasi harga dan ketersediaan masing-masing
item keranjang yang ada dalam CheckoutRequestMessage
.
Jika ketersediaan atau harga telah berubah, CheckoutResponseMessage
yang ditampilkan oleh fulfillment Anda harus berisi FoodOrderError
jenis error
AVAILABILITY_CHANGED
atau PRICE_CHANGED
.
Kasus penggunaan | Cara menerapkan |
---|---|
Kasus penggunaan 1: Validasi gagal karena beberapa item menu dan/atau penyesuaiannya tidak valid atau stoknya habis | Kembalikan FoodErrorExtension dengan correctedProposedOrder ,
PaymentOptions , dan FoodOrderError dari jenis error
AVAILABILITY_CHANGED . Item yang tidak valid harus dihapus dari
CorrectedProposedOrder . |
Kasus penggunaan 2: Validasi gagal karena beberapa item menu dan/atau penyesuaiannya tidak valid atau stoknya habis. Keranjang yang diperbaiki tidak lagi memenuhi persyaratan nilai pesanan minimum. | Kembalikan FoodErrorExtension dengan FoodOrderError
jenis error AVAILABILITY_CHANGED dan
REQUIREMENTS_NOT_MET . |
Kasus penggunaan 3: Validasi gagal karena beberapa item menu dan/atau harga penyesuaian telah berubah | Kembalikan FoodErrorExtension dengan correctedProposedOrder ,
PaymentOptions , dan FoodOrderError dari jenis error
PRICE_CHANGED . Harga lama harus diperbarui dalam
CorrectedProposedOrder . |
Kasus penggunaan 4: Validasi gagal karena beberapa item menu dan/atau harga penyesuaian telah berubah. Keranjang yang diperbaiki tidak lagi memenuhi persyaratan nilai pesanan minimum | Kembalikan FoodErrorExtension dengan FoodOrderError
jenis error PRICE_CHANGED dan
REQUIREMENTS_NOT_MET . |
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "AVAILABILITY_CHANGED", "id": "sample_item_offer_id_1", "description": "The item is no longer available." }, { "error": "AVAILABILITY_CHANGED", "id": "sample_item_offer_id_2", "description": "The item is no longer available." } ], "correctedProposedOrder": { "id": "sample_corrected_proposed_order_id_1", "otherItems": [ { "name":"New customer discount", "price": { "type":"ESTIMATE", "amount": { "currencyCode":"USD", "units":"-5", "nanos": -500000000 } }, "type": "DISCOUNT" }, { "name": "Delivery fee", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "3", "nanos": 500000000 } }, "type": "DELIVERY" }, { "name": "Tax", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "1", "nanos": 500000000 } }, "type": "TAX" } ], "cart": { "merchant": { "id": "https://www.exampleprovider.com/merchant/id1", "name": "Falafel Bite" }, "lineItems": [ { "name": "Greek Salad", "type": "REGULAR", "id": "sample_item_offer_id_3", "offerId": "https://www.exampleprovider.com/menu/item/offer/id3", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "9", "nanos": 990000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } }, { "name": "Prawns Biryani", "type": "REGULAR", "id": "sample_item_offer_id_4", "offerId": "https://www.exampleprovider.com/menu/item/offer/id4", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "15", "nanos": 990000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension", "fulfillmentPreference": { "fulfillmentInfo": { "delivery": { "deliveryTimeIso8601": "P90M" } } }, "location": { "coordinates": { "latitude": 37.788783, "longitude": -122.41384 }, "formattedAddress": "1350 CHARLESTON ROAD, MOUNTAIN VIEW, CA, United States", "zipCode": "94043", "city": "Mountain View", "postalAddress": { "regionCode": "US", "postalCode": "94043", "administrativeArea": "CA", "locality": "Mountain View", "addressLines": [ "1350 Charleston Road" ] }, "notes": "Gate code is #111" } } }, "totalPrice": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "36", "nanos": 730000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension", "availableFulfillmentOptions": [ { "fulfillmentInfo": { "delivery": { "deliveryTimeIso8601": "P90M" } }, "expiresAt": "2017-07-17T12:30:00Z" } ] } }, "paymentOptions": { "googleProvidedOptions": { "tokenizationParameters": { "tokenizationType": "PAYMENT_GATEWAY", "parameters": { "gateway": "stripe", "stripe:publishableKey": "pk_live_stripe_client_key", "stripe:version": "2017-04-06" } }, "supportedCardNetworks": [ "AMEX", "DISCOVER", "MASTERCARD", "JCB", "VISA" ], "prepaidCardDisallowed": true } } } } } ] } } }
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "REQUIREMENTS_NOT_MET", "description": "The cart subtotal must be over $20." }, { "error": "AVAILABILITY_CHANGED", "id": "cart_lineitem_id" "description": "cart_lineitem_id is no longer available." } ] } } } ] } } }
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "PRICE_CHANGED", "id": "sample_item_offer_id_1", "description": "The price has changed.", "updatedPrice": { "currencyCode": "USD", "units": "2", "nanos": 750000000 } }, { "error": "PRICE_CHANGED", "id": "sample_item_offer_id_2", "description": "The price has changed.", "updatedPrice": { "currencyCode": "USD", "units": "8" } } ], "correctedProposedOrder": { "id": "sample_corrected_proposed_order_id_1", "otherItems": [ { "name":"New customer discount", "price": { "type":"ESTIMATE", "amount": { "currencyCode":"USD", "units":"-5", "nanos": -500000000 } }, "type": "DISCOUNT" }, { "name": "Delivery fee", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "3", "nanos": 500000000 } }, "type": "DELIVERY" }, { "name": "Tax", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "1", "nanos": 500000000 } }, "type": "TAX" } ], "cart": { "merchant": { "id": "https://www.exampleprovider.com/merchant/id1", "name": "Falafel Bite" }, "lineItems": [ { "name": "Pita Chips", "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": "2", "nanos": 750000000 } }, "subLines": [ { "note": "Notes for this item." } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension", "options": [ { "id": "sample_addon_offer_id_1", "offerId": "https://www.exampleprovider.com/menu/item/addon/offer/id1", "name": "Honey Mustard", "price": { "currencyCode": "USD" }, "quantity": 1 }, { "id": "sample_addon_offer_id_2", "offerId": "https://www.exampleprovider.com/menu/item/addon/offer/id2", "name": "BBQ Sauce", "price": { "currencyCode": "USD", "nanos": 500000000 }, "quantity": 1 } ] } }, { "name": "Chicken Shwarma Wrap", "type": "REGULAR", "id": "sample_item_offer_id_2", "offerId": "https://www.exampleprovider.com/menu/item/offer/id2", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "8" } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } }, { "name": "Greek Salad", "type": "REGULAR", "id": "sample_item_offer_id_3", "offerId": "https://www.exampleprovider.com/menu/item/offer/id3", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "9", "nanos": 990000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } }, { "name": "Prawns Biryani", "type": "REGULAR", "id": "sample_item_offer_id_4", "offerId": "https://www.exampleprovider.com/menu/item/offer/id4", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "15", "nanos": 990000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension", "fulfillmentPreference": { "fulfillmentInfo": { "delivery": { "deliveryTimeIso8601": "P90M" } } }, "location": { "coordinates": { "latitude": 37.788783, "longitude": -122.41384 }, "formattedAddress": "1350 CHARLESTON ROAD, MOUNTAIN VIEW, CA, United States", "zipCode": "94043", "city": "Mountain View", "postalAddress": { "regionCode": "US", "postalCode": "94043", "administrativeArea": "CA", "locality": "Mountain View", "addressLines": [ "1350 Charleston Road" ] }, "notes": "Gate code is #111" } } }, "totalPrice": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "36", "nanos": 730000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension", "availableFulfillmentOptions": [ { "fulfillmentInfo": { "delivery": { "deliveryTimeIso8601": "P90M" } }, "expiresAt": "2017-07-17T12:30:00Z" } ] } }, "paymentOptions": { "googleProvidedOptions": { "tokenizationParameters": { "tokenizationType": "PAYMENT_GATEWAY", "parameters": { "gateway": "stripe", "stripe:publishableKey": "pk_live_stripe_client_key", "stripe:version": "2017-04-06" } }, "supportedCardNetworks": [ "AMEX", "DISCOVER", "MASTERCARD", "JCB", "VISA" ], "prepaidCardDisallowed": true } } } } } ] } } }
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "REQUIREMENTS_NOT_MET", "description": "The cart subtotal must be over $20." }, { "error": "PRICE_CHANGED", "id": "cart_lineitem_id" "description": "cart_lineitem_id price has been updated." "updatedPrice": { "currencyCode": "USD", "units": "2", "nanos": 750000000 } } ] } } } ] } } }
Mengirimkan validasi pesanan
Seperti yang dibahas di Langkah 7: Terapkan Pesanan Pengiriman,
fulfillment endpoint harus melakukan validasi pada setiap
SubmitOrderRequestMessage
, lalu merespons dengan
SubmitOrderResponseMessage
Berikut contoh SubmitOrderResponseMessage
untuk
validasi:
Kasus penggunaan | Cara menerapkan |
---|---|
Kasus penggunaan 1: Pesanan berhasil dibuat | SubmitOrderResponseMessage dengan pesanan CREATED
status. URL harus memiliki actionOrderId ,
userVisibleId , orderManagementActions , dan
estimatedFulfillmentTime . |
Kasus penggunaan 2: Pesanan ditolak karena masalah pembayaran | SubmitOrderResponseMessage dengan pesanan REJECTED
status. URL harus memiliki actionOrderId ,
userVisibleId , orderManagementActions , dan
rejectionInfo dari jenis PAYMENT_DECLINED . |
Kasus penggunaan 3: Pesanan ditolak karena pengguna ditandai sebagai diblokir | SubmitOrderResponseMessage dengan pesanan REJECTED
. URL harus memiliki actionOrderId ,
userVisibleId , orderManagementActions , dan
rejectionInfo dari jenis INELIGIBLE . |
Kasus penggunaan 4: Pesanan ditolak karena informasi pengguna tidak lengkap atau tidak valid | SubmitOrderResponseMessage dengan pesanan REJECTED
status. URL harus memiliki actionOrderId ,
userVisibleId , orderManagementActions , dan
rejectionInfo dari jenis INELIGIBLE . |
Kasus penggunaan 5: Pesanan ditolak karena alasan yang tidak diketahui | SubmitOrderResponseMessage dengan pesanan REJECTED
status. URL harus memiliki actionOrderId ,
userVisibleId , orderManagementActions , dan
rejectionInfo dari jenis UNKNOWN . |
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "CREATED", "label": "Order received" }, "updateTime": "2017-05-10T02:30:00.000Z", "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:person@example.com" } } }, { "type": "CALL", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+16505554679" } } }, { "type": "VIEW_DETAILS", "button": { "title": "View order", "openUrlAction": { "url": "https://orderview.partner.com?orderid=sample_action_order_id" } } } ] } } } ] } } }
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "REJECTED", "label": "Order rejected" }, "updateTime": "2017-05-10T02:30:00.000Z", "rejectionInfo": { "type": "PAYMENT_DECLINED", "reason": "Insufficient funds" }, "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:person@example.com" } } }, { "type": "CALL", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+16505554679" } } }, { "type": "VIEW_DETAILS", "button": { "title": "View order", "openUrlAction": { "url": "https://orderview.partner.com?orderid=sample_action_order_id" } } } ] } } } ] } } }
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "REJECTED", "label": "Order rejected" }, "updateTime": "2017-05-10T02:30:00.000Z", "rejectionInfo": { "type": "INELIGIBLE", "reason": "Sorry, we are not able to take orders from this user" }, "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:person@example.com" } } }, { "type": "CALL", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+16505554679" } } }, { "type": "VIEW_DETAILS", "button": { "title": "View order", "openUrlAction": { "url": "https://orderview.partner.com?orderid=sample_action_order_id" } } } ] } } } ] } } }
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "REJECTED", "label": "Order rejected" }, "updateTime": "2017-05-10T02:30:00.000Z", "rejectionInfo": { "type": "INELIGIBLE", "reason": "Sorry, the phone number must not be blank" }, "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:person@example.com" } } }, { "type": "CALL", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+16505554679" } } }, { "type": "VIEW_DETAILS", "button": { "title": "View order", "openUrlAction": { "url": "https://orderview.partner.com?orderid=sample_action_order_id" } } } ] } } } ] } } }
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "REJECTED", "label": "Order rejected" }, "updateTime": "2017-05-10T02:30:00.000Z", "rejectionInfo": { "type": "UNKNOWN", "reason": "Sorry, there is something wrong with this order." }, "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:person@example.com" } } }, { "type": "CALL", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+16505554679" } } }, { "type": "VIEW_DETAILS", "button": { "title": "View order", "openUrlAction": { "url": "https://orderview.partner.com?orderid=sample_action_order_id" } } } ] } } } ] } } }