การแมปฟีดเมนูและรายการในรถเข็นที่ดำเนินการตามคำสั่งซื้อ
เมื่อลูกค้าเพิ่มสินค้าจากฟีด "เมนู" ลงในรถเข็นและชำระเงิน Google จะส่งสินค้าดังกล่าวไปยังปลายทางการดำเนินการตามคำสั่งซื้อเพื่อยืนยันราคาและความพร้อมจำหน่ายสินค้า เมื่อมีการตรวจสอบราคาและความพร้อมจำหน่ายสินค้าแล้ว ลูกค้าจะสั่งซื้อได้ ส่วนนี้จะแสดงวิธีแมปรายการฟีดเมนูกับรายการในรถเข็นที่ดำเนินการตามคำสั่งซื้อ
ตัวอย่างในส่วนนี้คือฟีดเมนูและสคีมารถเข็นแบบย่อ จะแสดงเฉพาะช่องที่เกี่ยวข้องเพื่อแสดงการแมประหว่างฟีดเมนูและออบเจ็กต์รถเข็น ดูสคีมาฉบับเต็มได้ที่ Menu
และ Cart
สินค้าในฟีด Menu
ที่เพิ่มลงในรถเข็นจะส่งไปในออบเจ็กต์ Cart
สำหรับทั้งการส่งการชำระเงินและคำสั่งซื้อ
MenuItem
แบบง่ายจะแสดงเป็นLineItem
ในอาร์เรย์lineItems
โดยมีofferId
เป็นoffer.id
ของรายการเมนูที่เลือกไว้ในฟีดเมนูMenuItem
ที่มีMenuItemOption
ที่ต้องระบุจะแสดงเป็นLineItem
ในอาร์เรย์lineItems
โดยมีofferId
เป็นoffer.id
ของตัวเลือกรายการเมนูที่เลือกไว้จากฟีดเมนูAddOnMenuItem
ของLineItem
จะแสดงเป็นFoodItemOption
ในอาร์เรย์options
ของFoodItemExtension
แต่ละตัวเลือกจะมีofferId
ที่สอดคล้องกับoffer.id
ของรายการในเมนูส่วนเสริมที่เลือกจากฟีดเมนู โปรดทราบว่า AddOnActivityItem อาจมี AddOn MenuItem ที่ซ้อนกันที่แสดงเป็นsubOptions
ในแต่ละตัวเลือกได้ด้วย
ตัวอย่างต่อไปนี้แมปรายการในเมนูระหว่างฟีดเมนูกับรถเข็น Fulfillment
JSON
ตัวอย่างนี้มีรายการในเมนูแบบง่ายๆ
รายการเมนูในฟีดเมนู
{ "@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" } ] } ] }
รายการในเมนูที่แมปกับรถเข็นดำเนินการตามคำสั่งซื้อ:
{ "@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
ตัวอย่างนี้มีรายการในเมนูที่มี AddOn MenuItems อย่างน้อย 1 รายการ
รายการเมนูในฟีดเมนู
{ "@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" } ] } ] }
รายการในเมนูที่แมปกับรถเข็นดำเนินการตามคำสั่งซื้อ:
{ "@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
ตัวอย่างนี้มีรายการในเมนูที่มีตัวเลือกรายการเมนู, AddOn MenuItems และ AddOn MenuItems ที่ฝังไว้
รายการเมนูในฟีดเมนู
{ "@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" } ] } ] } ] } ] } ] } } ] }
รายการในเมนูที่แมปกับรถเข็นดำเนินการตามคำสั่งซื้อ:
{ "@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" } ] } ] } } ] }
การจัดการข้อผิดพลาด
หากพบปัญหาขณะประมวลผล CheckoutRequestMessage
คุณสามารถตอบกลับด้วย CheckoutResponseMessage
ที่มี FoodErrorExtension
แทนที่จะเป็น CheckoutResponse คุณใช้การตอบกลับนี้เพื่อระบุข้อผิดพลาดอย่างน้อย 1 รายการที่เกิดขึ้นระหว่างการประมวลผลได้
การจัดการข้อผิดพลาดมี 2 วิธีดังนี้
- ข้อผิดพลาดที่กู้คืนได้: ผู้ใช้ไม่จำเป็นต้องแก้ไขรถเข็นเพื่อส่งคำสั่งซื้อ เช่น หากระบุว่าสินค้าใน
Cart
มีการเปลี่ยนแปลงราคา คุณก็สามารถตอบกลับด้วยFoodOrderError
ประเภทข้อผิดพลาดPRICE_CHANGED
พร้อมด้วยcorrectedProposedOrder
และpaymentOptions
Google จะแจ้งให้ผู้ใช้ทราบเกี่ยวกับการเปลี่ยนแปลง แต่อนุญาตให้ผู้ใช้ส่งข้อมูลด้วยcorrectedProposedOrder
นอกจากนี้ ผู้ใช้ยังกลับไปแก้ไขรถเข็นได้ตามต้องการ คุณจะได้รับCheckoutRequestMessage
หรือSubmitOrderRequestMessage
ใหม่ - ข้อผิดพลาดที่กู้คืนไม่ได้: ผู้ใช้จะต้องแก้ไขรถเข็นก่อนส่งคำสั่งซื้อ เช่น หากทราบว่าร้านอาหารปิดแล้ว คุณสามารถตอบกลับด้วย
FoodOrderError
ประเภทข้อผิดพลาดCLOSED
Google จะแจ้งให้ผู้ใช้ทราบและจัดการการโต้ตอบเพื่ออัปเดตร้านอาหารใหม่ คุณจะได้รับCheckoutRequestMessage
ใหม่สำหรับรถเข็นใหม่
โดยทั่วไป ทำให้ไม่สามารถกู้คืนข้อผิดพลาดระดับรถเข็นและข้อผิดพลาดระดับสินค้าได้ ดูรายการประเภทข้อผิดพลาดทั้งหมดและความหมายได้ที่ FoodOrderError
การจัดการการเปลี่ยนแปลงราคา
การเปลี่ยนแปลงราคาระหว่างการชำระเงิน
หากพบปัญหาด้านราคาขณะประมวลผลคำขอชำระเงินของลูกค้า ให้ทำดังนี้
- ตอบกลับ
CheckoutRequestMessage
ด้วยCheckoutResponseMessage
ที่มีFoodErrorExtension
ตามที่อธิบายไว้ในการจัดการข้อผิดพลาด - ในการตอบกลับข้อผิดพลาด ให้ใช้
correctedProposedOrder.cart
เพื่ออัปเดตราคาเป็นค่าที่ถูกต้อง Google ได้รับคำสั่งซื้อที่ถูกต้องและอาจออกCheckoutRequestMessage
ใหม่
หลังจากชำระเงิน Google จะแสดงหน้ายืนยันคำสั่งซื้อต่อผู้ใช้ปลายทาง ไม่ว่าProposedOrder
จะเปลี่ยนไปหรือไม่ก็ตาม
หากข้อเสนอ ProposedOrder ได้รับการแก้ไขแล้ว Google อาจแสดงคำเตือนเพิ่มเติมเพื่อแจ้งให้ผู้ใช้ทราบเกี่ยวกับการเปลี่ยนแปลง หากผู้ใช้ตกลงที่จะสั่งซื้อ
จะไม่มีคำขอชำระเงินอีก ขั้นตอนนี้จะดำเนินการตามลำดับการส่งข้อมูล โดยมี ProposedOrder
ที่แก้ไขแล้ว
แต่ผู้ใช้เปลี่ยนใจและแก้ไขรถเข็นอีกครั้งได้ทุกเมื่อ เมื่อมีการอัปเดตรถเข็นด้วยวิธีนี้ Google จะส่ง CheckoutRequestMessage
ใหม่
การเปลี่ยนแปลงราคาระหว่างส่งคำสั่งซื้อ
หากพบปัญหาเกี่ยวกับราคาขณะประมวลผลการส่งคำสั่งซื้อ (มีการทริกเกอร์ Intent actions.intent.TRANSACTION_DECISION
) อย่าตอบกลับโดยมีข้อผิดพลาดหรืออัปเดตราคาในการตอบกลับ หากราคา จำนวน หรือรายละเอียดอื่นๆ ใน SubmitOrderRequestMessage
ไม่สอดคล้องกับข้อมูลของคุณ ให้ตอบกลับด้วยการตั้งค่า orderState
เป็น REJECTED
เพื่อระบุว่าจะสั่งซื้อตามที่ขอไม่ได้
จากนั้นหากรายละเอียดคำสั่งซื้อและการชำระเงินถูกต้อง ให้ตั้งค่า orderState
เป็น CREATED
หรือ CONFIRMED
นอกจากนี้ ให้ใส่ actionOrderId
เพื่อแสดงรหัสคำสั่งซื้อในระบบของคุณ คุณต้องใช้รหัสนี้เมื่อส่งการอัปเดตครั้งต่อๆ ไป
หากประมวลผลการชำระเงินไม่ได้และได้ส่ง SubmitOrderRequestMessage
ไปแล้ว คุณส่ง AsyncOrderUpdateRequestMessage
พร้อม orderState
ตั้งค่าเป็น REJECTED
เพื่อแจ้งให้ผู้ใช้ทราบว่าคำสั่งซื้อจะไม่สำเร็จ
ราคามีการเปลี่ยนแปลงหลังจากส่งคำสั่งซื้อ
หากคุณพิจารณาว่าราคามีการเปลี่ยนแปลงจากราคาที่ใช้เมื่อลูกค้าส่งคำสั่งซื้อ คุณสามารถออกAsyncOrderUpdateRequestMessage
ตามที่อธิบายไว้ในการใช้การอัปเดตคำสั่งซื้อแบบอะซิงโครนัส ด้วยราคาใหม่
วิธีอัปเดตราคาโดยใช้การอัปเดตคำสั่งซื้อแบบไม่พร้อมกัน
- เปลี่ยนราคาใน
lineItemUpdates[x].price
ค่านี้แสดงถึงค่าใช้จ่ายรวมของสินค้า ซึ่งรวมถึงส่วนเสริมและคูณด้วยจำนวน (ดูข้อมูลเพิ่มเติมได้ที่คำอธิบายช่องprice
ของLineItem
) - ป้อนคำอธิบายในภาษา
lineItemUpdates[x].reason
- ตั้งค่า
lineItemUpdates[x].orderState
เป็นCONFIRMED
คุณสามารถพยายามเรียกเก็บเงินจากเครื่องมือการชำระเงินก่อนหรือหลังจากส่ง AsyncOrderUpdateRequestMessage ตามที่เห็นสมควรแล้ว หากทำธุรกรรมไม่สำเร็จ (ซึ่งอาจเป็นเพราะเดลต้าราคาสูงเกินไป) ให้ส่ง AsyncOrderUpdateRequestMessage พร้อมการตั้งค่าต่อไปนี้ในOrderUpdate
เพื่อแจ้งให้ Google ทราบถึงการดำเนินการที่ไม่สำเร็จ
- ตั้งค่า
orderState
เป็นREJECTED
- อธิบายความล้มเหลวในช่อง
label
การตรวจสอบความถูกต้องของการชำระเงิน
ตามที่ได้กล่าวไว้ในขั้นตอนที่ 4: ใช้จุดชำระเงิน ปลายทางการดำเนินการตามคำสั่งซื้อควรตรวจสอบ CheckoutRequestMessage
ขาเข้าทั้งหมด และตอบกลับด้วย CheckoutResponseMessage
ต่อไปนี้คือตัวอย่างของ CheckoutResponseMessage
เพื่อให้ตรวจสอบได้สําเร็จ
Use Case | วิธีติดตั้งใช้งาน |
---|---|
กรณีการใช้งาน 1: ตรวจสอบสำเร็จ | กลับ CheckoutResponse ซึ่งต้องมี ProposedOrder และ PaymentOptions
ProposedOrder รวมภาษี ค่าธรรมเนียม และราคารวมของรถเข็น |
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 } } } } } ] } } }
การตรวจสอบที่อยู่สำหรับจัดส่ง
ปลายทางการดำเนินการตามคำสั่งซื้อควรตรวจสอบที่อยู่สำหรับจัดส่งซึ่งมีอยู่ใน CheckoutRequestMessage
แต่ละรายการ
หากที่อยู่ที่นำส่งมีปัญหา เช่น อยู่นอกช่วงของบริการนำส่ง CheckoutResponseMessage
ที่ดำเนินการตามคำสั่งซื้อที่นำส่งควรมี FoodOrderError
ที่เป็นประเภทที่เหมาะสม
Use Case | วิธีติดตั้งใช้งาน |
---|---|
กรณีการใช้งาน 1: การตรวจสอบล้มเหลวเนื่องจากที่อยู่สำหรับจัดส่งอยู่นอกช่วงหรือมีปัญหาเกี่ยวกับที่อยู่สำหรับจัดส่ง | แสดงผล FoodErrorExtension ที่มี FoodOrderError ที่เป็นข้อผิดพลาดประเภท 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." } ] } } } ] } } }
การตรวจสอบมูลค่าการสั่งซื้อขั้นต่ำ
ปลายทางการดำเนินการตามคำสั่งซื้อควรตรวจสอบมูลค่าการสั่งซื้อขั้นต่ำของแต่ละ CheckoutRequestMessage
หากไม่ถึงมูลค่าการสั่งซื้อขั้นต่ำ CheckoutResponseMessage
ที่ส่งคืนโดยการดำเนินการตามคำสั่งซื้อควรมี FoodOrderError
ประเภทข้อผิดพลาด
REQUIREMENTS_NOT_MET
Use Case | วิธีติดตั้งใช้งาน |
---|---|
กรณีการใช้งานที่ 1: ตรวจสอบไม่สำเร็จเนื่องจากไม่ถึงมูลค่าการสั่งซื้อขั้นต่ำ | แสดงผล FoodErrorExtension ที่มี FoodOrderError ที่เป็นข้อผิดพลาดประเภท 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." } ] } } } ] } } }
การตรวจสอบกรอบเวลาการสั่งซื้อ
ปลายทางการดำเนินการตามคำสั่งซื้อควรตรวจสอบปัจจัยที่อาจส่งผลต่อกรอบเวลาการสั่งซื้อของ CheckoutRequestMessage
แต่ละรายการ
เช่น หากร้านอาหารปิดทําการหรือไม่รับคําสั่งซื้อแล้วในตอนนี้ CheckoutResponseMessage
ที่ดำเนินการตามคําสั่งซื้อของคุณควรมี FoodOrderError
ประเภทข้อผิดพลาด CLOSED
หรือ NO_CAPACITY
ตามลำดับ
Use Case | วิธีติดตั้งใช้งาน |
---|---|
กรณีการใช้งานที่ 1: ตรวจสอบไม่สำเร็จเนื่องจากร้านอาหารปิดหรือไม่รองรับแล้ว | แสดงผล FoodErrorExtension ที่มี FoodOrderError ที่เป็นข้อผิดพลาดประเภท CLOSED |
กรณีการใช้งานที่ 2: ตรวจสอบไม่สำเร็จเนื่องจากร้านอาหารไม่ว่างและไม่ได้รับคำสั่งซื้อในขณะนี้ | แสดงผล FoodErrorExtension ที่มี FoodOrderError ที่เป็นข้อผิดพลาดประเภท 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." } ] } } } ] } } }
การตรวจสอบสินค้าในรถเข็น
ปลายทางการดำเนินการตามคำสั่งซื้อควรตรวจสอบราคาและความพร้อมจำหน่ายสินค้าของสินค้าในรถเข็นแต่ละรายการที่อยู่ใน CheckoutRequestMessage
หากความพร้อมจำหน่ายสินค้าหรือราคามีการเปลี่ยนแปลง CheckoutResponseMessage
ที่ส่งคืนโดยการดำเนินการตามคำสั่งซื้อควรมี FoodOrderError
ประเภทข้อผิดพลาด AVAILABILITY_CHANGED
หรือ PRICE_CHANGED
ตามลำดับ
Use Case | วิธีติดตั้งใช้งาน |
---|---|
กรณีการใช้งานที่ 1: ตรวจสอบไม่สำเร็จเนื่องจากรายการในเมนูและ/หรือการปรับแต่งบางรายการไม่ถูกต้องหรือหมด | แสดงผล FoodErrorExtension ด้วย correctedProposedOrder , PaymentOptions และ FoodOrderError ของข้อผิดพลาดประเภท
AVAILABILITY_CHANGED ต้องนำรายการที่ไม่ถูกต้องออกจาก CorrectedProposedOrder |
กรณีการใช้งานที่ 2: ตรวจสอบไม่สำเร็จเนื่องจากรายการในเมนูและ/หรือการปรับแต่งบางรายการไม่ถูกต้องหรือหมด รถเข็นที่แก้ไขแล้ว ไม่เป็นไปตามข้อกำหนดมูลค่าการสั่งซื้อขั้นต่ำอีกต่อไป | แสดงผล FoodErrorExtension ที่มี FoodOrderError ของประเภทข้อผิดพลาด AVAILABILITY_CHANGED และ REQUIREMENTS_NOT_MET |
กรณีการใช้งานที่ 3: การตรวจสอบล้มเหลวเนื่องจากรายการในเมนูและ/หรือราคาที่กำหนดเองบางรายการมีการเปลี่ยนแปลง | แสดงผล FoodErrorExtension ด้วย correctedProposedOrder , PaymentOptions และ FoodOrderError ของข้อผิดพลาดประเภท
PRICE_CHANGED คุณต้องอัปเดตราคาที่ล้าสมัยใน CorrectedProposedOrder |
กรณีการใช้งานที่ 4: การตรวจสอบล้มเหลวเนื่องจากรายการในเมนูและ/หรือราคาที่กำหนดเองบางรายการมีการเปลี่ยนแปลง รถเข็นที่แก้ไขแล้วไม่เป็นไปตามข้อกำหนดมูลค่าการสั่งซื้อขั้นต่ำอีกต่อไป | แสดงผล FoodErrorExtension ที่มี FoodOrderError ของประเภทข้อผิดพลาด PRICE_CHANGED และ 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 } } ] } } } ] } } }
ส่งการตรวจสอบคำสั่งซื้อ
ตามที่ได้กล่าวไว้ในขั้นตอนที่ 7: ใช้คำสั่งซื้อการส่ง อุปกรณ์ปลายทางการดำเนินการตามคำสั่งซื้อควรตรวจสอบคำขอขาเข้าทุกรายการ
SubmitOrderRequestMessage
และตอบกลับด้วย
SubmitOrderResponseMessage
ต่อไปนี้คือตัวอย่างของ SubmitOrderResponseMessage
เพื่อให้ตรวจสอบได้สําเร็จ
Use Case | วิธีติดตั้งใช้งาน |
---|---|
กรณีการใช้งาน 1: สร้างคำสั่งซื้อเรียบร้อยแล้ว | SubmitOrderResponseMessage ที่มีสถานะคำสั่งซื้อ CREATED ซึ่งต้องมี actionOrderId , userVisibleId , orderManagementActions และ estimatedFulfillmentTime |
กรณีการใช้งาน 2: คำสั่งซื้อถูกปฏิเสธเนื่องจากมีปัญหาในการชำระเงิน | SubmitOrderResponseMessage ที่มีสถานะคำสั่งซื้อ REJECTED ซึ่งต้องมี actionOrderId , userVisibleId , orderManagementActions และ rejectionInfo ประเภท PAYMENT_DECLINED |
กรณีการใช้งาน 3: คำสั่งซื้อถูกปฏิเสธเนื่องจากผู้ใช้ถูกแจ้งว่าแบน | SubmitOrderResponseMessage ที่มีสถานะคำสั่งซื้อ REJECTED ซึ่งต้องมี actionOrderId , userVisibleId , orderManagementActions และ rejectionInfo ประเภท INELIGIBLE |
กรณีการใช้งาน 4: คำสั่งซื้อถูกปฏิเสธเนื่องจากข้อมูลผู้ใช้ ไม่สมบูรณ์หรือไม่ถูกต้อง | SubmitOrderResponseMessage ที่มีสถานะคำสั่งซื้อ REJECTED ซึ่งต้องมี actionOrderId , userVisibleId , orderManagementActions และ rejectionInfo ประเภท INELIGIBLE |
กรณีการใช้งาน 5: คำสั่งซื้อถูกปฏิเสธโดยไม่ทราบสาเหตุ | SubmitOrderResponseMessage ที่มีสถานะคำสั่งซื้อ REJECTED ซึ่งต้องมี actionOrderId , userVisibleId , orderManagementActions และ rejectionInfo ประเภท 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" } } } ] } } } ] } } }