מיפוי פידים של תפריטים ופריטים בעגלת הקניות
כשלקוחות מוסיפים פריטים מפיד התפריט לעגלת הקניות ומבצעים תשלום, 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
של פריט התפריט שנבחר מפיד התפריטים. חשוב לשים לב שבתוך כל אפשרות, AddOnתפריטItem יכול להכיל גם AddOnMenuItem(s) שמיוצג בתורsubOptions
.
בדוגמאות הבאות מפורטות האפשרויות בתפריט בין פיד התפריט לבין עגלת הקניות.
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תפריטItems אחד או יותר.
אפשרויות תפריט בפיד 'תפריט':
{ "@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
דוגמה זו מכילה פריט בתפריט עם אפשרויות של פריטים בתפריט, AddOnmenuItems ו-AddOnMenuItems מקונן
אפשרויות תפריט בפיד 'תפריט':
{ "@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. תוכלו להשתמש בתגובה הזו כדי לזהות שגיאה אחת או יותר שהתרחשו במהלך העיבוד.
יש 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
חדש.
שינויים במחיר במהלך שליחת ההזמנה
אם נתקלתם בבעיה שקשורה למחיר במהלך שליחת ההזמנה (התכונה 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: הטמעת Checkout, נקודת הקצה של מילוי הבקשה צריכה לבצע אימות בכל CheckoutRequestMessage
נכנס, ולהגיב באמצעות CheckoutResponseMessage
.
דוגמה ל-CheckoutResponseMessage
לאימות מוצלח:
תרחיש לדוגמה | איך ליישם |
---|---|
תרחיש לדוגמה 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
מהסוג המתאים.
תרחיש לדוגמה | איך ליישם |
---|---|
תרחיש לדוגמה 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
.
תרחיש לדוגמה | איך ליישם |
---|---|
תרחיש לדוגמה 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
, בהתאמה.
תרחיש לדוגמה | איך ליישם |
---|---|
תרחיש לדוגמה 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
, בהתאמה.
תרחיש לדוגמה | איך ליישם |
---|---|
תרחיש לדוגמה 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
לאימות מוצלח:
תרחיש לדוגמה | איך ליישם |
---|---|
תרחיש לדוגמה 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" } } } ] } } } ] } } }