אחרי שיחת התשלום, המשתמש בודק את עגלת הקניות המעודכנת עם המיסים, דמי המשלוח, ההנחות והחיובים האחרים שתחזירו. המשתמש מאשר את ההזמנה ושולח אותה, ו-Google שולחת לנקודת הקצה לטיפול בהזמנות בקשת JSON שמכילה את המידע על ההזמנה. שירות האינטרנט שלכם צריך לקבל את ההזמנה הזו, לעבד אותה ולשלוח תשובה ל-Google עם סטטוס ההזמנה.
בקטע הזה מוסבר על הפורמט של הודעת הבקשה להזמנה שנשלחת על ידי Google, שנקראת SubmitOrderRequestMessage
, ועל הפורמט של הודעת התגובה שאתם צריכים לספק, שנקראת SubmitOrderResponseMessage
.
מידע נוסף על מחזור החיים של מילוי ההזמנות זמין בסקירה הכללית על מילוי ההזמנות.
הטמעת שירותי מילוי הזמנות
שירות האינטרנט של Ordering End-to-End שאתם יוצרים כדי לעבוד עם Ordering End-to-End חייב לכלול נקודת קצה של כתובת URL לקבלת הודעות על הזמנות מ-Google. לצורך עיבוד ההזמנה, שירות האינטרנט שלכם מקבל מ-Google את הערך SubmitOrderRequestMessage
בפורמט JSON כבקשת POST. הבקשה הזו מכילה הזמנה של לקוח, כולל מיסים, עמלות ופרטי תשלום. כשמקבלים בקשה לשליחת הזמנה, שירות האינטרנט צריך לבצע את הפעולות הבאות:
- בדיקת הזכאות לביצוע עסקה, כמו אימות כרטיס או זיהוי הונאות.
- יוצרים הזמנה במערכת.
- מאשרים את אמצעי התשלום ומפעילים את Charge API של ספק שירותי התשלומים, במקרים הרלוונטיים.
- יש להשיב עם סטטוס ההזמנה המתאים:
CREATED
,CONFIRMED
אוREJECTED
.
אחרי עיבוד ההזמנה, קוד המילוי צריך לספק תשובה ל-Google בצורת הודעת JSON מסוג SubmitOrderResponseMessage
.
מידע נוסף על דרישות ההטמעה של שירות האינטרנט של מילוי ההזמנות מקצה לקצה זמין במאמר סקירה כללית על מילוי הזמנות.
הודעת הבקשה להזמנה
כשלקוח בוחר לבצע הזמנה במהלך התהליך מתחילתו ועד סופו, Google שולחת בקשה לשירות האינטרנט שלכם עם הודעת JSON שנקראת SubmitOrderRequestMessage
, שמכילה את הנתונים הבאים:
- כוונה: השדה
inputs[0].intent
בכל גוף בקשה לשליחת הזמנה מכיל את ערך המחרוזתactions.intent.TRANSACTION_DECISION
. - הזמנה: השדה
inputs[0].arguments[0].transactionDecisionValue
בבקשה לשליחת הזמנה מכיל אובייקטOrder
שמייצג את ההזמנה של הלקוח שרוצים להעביר, יחד עם פרטי התשלום. - דגל ארגז חול: השדה
isInSandbox
בבקשה לשליחת הזמנה מציין אם בעסקה נעשה שימוש בתשלומים בארגז חול.
דוגמה לבקשת הזמנה
דוגמה ל-SubmitOrderRequestMessage
:
{ "user": {}, "conversation": { "conversationId": "CTKbKfUlHCyDEdcz_5PBJTtf" }, "inputs": [ { "intent": "actions.intent.TRANSACTION_DECISION", "arguments": [ { "transactionDecisionValue": { "order": { "finalOrder": { "cart": { "merchant": { "id": "restaurant/Restaurant/QWERTY", "name": "Tep Tep Chicken Club" }, "lineItems": [ { "name": "Spicy Fried Chicken", "type": "REGULAR", "id": "299977679", "quantity": 2, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "AUD", "units": "39", "nanos": 600000000 } }, "offerId": "MenuItemOffer/QWERTY/scheduleId/496/itemId/143", "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension", "fulfillmentPreference": { "fulfillmentInfo": { "delivery": { "deliveryTimeIso8601": "P0M" } } }, "location": { "coordinates": { "latitude": -33.8376441, "longitude": 151.0868736 }, "formattedAddress": "Killoola St, 1, Concord West NSW 2138", "zipCode": "2138", "city": "Concord West", "postalAddress": { "regionCode": "AU", "postalCode": "2138", "administrativeArea": "NSW", "locality": "Concord West", "addressLines": [ "Killoola St", "1" ] } }, "contact": { "displayName": "Hab Sy", "email": "hab9878.sy@gmail.com", "phoneNumber": "+61000000000", "firstName": "Hab", "lastName": "Sy" } } }, "otherItems": [ { "name": "Delivery fee", "type": "DELIVERY", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "AUD", "units": "3", "nanos": 500000000 } } }, { "name": "Subtotal", "type": "SUBTOTAL", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "AUD", "units": "39", "nanos": 600000000 } } } ], "totalPrice": { "type": "ESTIMATE", "amount": { "currencyCode": "AUD", "units": "43", "nanos": 100000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension" } }, "googleOrderId": "01412971004192156198", "orderDate": "2020-10-22T09:02:06.173Z", "paymentInfo": { "displayName": "Pay when you get your food", "paymentType": "ON_FULFILLMENT" } } } } ] } ], "directActionOnly": true, "isInSandbox": true }
הודעת תגובה להזמנה
אחרי קבלת בקשה, שירות האינטרנט של תהליך ההזמנה מקצה אותה לטיפול ומחזיר SubmitOrderResponseMessage
שכולל את הנתונים הבאים:
OrderUpdate
: אובייקט שמכיל את סטטוס ההזמנה ואת כל הפעולות שזמינות למשתמש לאחר ההזמנה, כמו יצירת קשר עם התמיכה וצפייה בפרטי ההזמנה. אתם מגדירים את הפעולות האלה בשדהfinalResponse.richResponse.items[0].structuredResponse.orderUpdate
בתגובה.
שדה עדכון ההזמנה
כששירות האינטרנט שולח SubmitOrderResponseMessage
, הוא מכיל את השדה OrderUpdate
שכולל את השדות הבאים:
actionOrderId
: המזהה הייחודי של ההזמנה, שמשמשים לזיהוי ההזמנה באופן ייחודי במערכת ולהפניה אליה כששולחים עדכונים נוספים לגבי ההזמנה.orderState
: אובייקטOrderState
שמייצג את מצב ההזמנה.orderManagementActions
: פעולות שזמינות למשתמש אחרי ביצוע ההזמנה, כמו יצירת קשר עם תמיכת הלקוחות וצפייה בפרטי ההזמנה.totalPrice
: המחיר הכולל של ההזמנה. הפעולה הזאת אופציונלית. שולחים רק אם המחיר הכולל של ההזמנה השתנה אחרי שליחת ההזמנה.
ההזמנה יכולה להיות באחד מהמצבים הבאים:
CREATED
: נקודת הקצה לטיפול בהזמנות עיבדתה את ההזמנה בהצלחה, אבל הספק עדיין לא אישר אותה.CONFIRMED
: ההזמנה טופלה בהצלחה בנקודת הקצה לטיפול בהזמנות, והספק אישר אותה.REJECTED
: הייתה בעיה ונקודת הקצה לטיפול בהזמנות לא הצליחה ליצור או לאשר את ההזמנה. הבעיה יכולה להיות בעיה בתשלום.
אם מגדירים הזמנה למצב REJECTED
, צריך לציין את הסיבה בשדה rejectionInfo
של OrderUpdate
. משתמשים בערכי FoodOrderUpdateExtension.FoodOrderErrors
בשילוב עם rejectionInfo
מסוג UNKNOWN
ומספקים תיאור.
דוגמה לתגובה להזמנה
דוגמה ל-SubmitOrderResponseMessage
:
{ "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "orderUpdate": { "actionOrderId": "1603357328160", "orderState": { "state": "CONFIRMED", "label": "Pending" }, "updateTime": "2020-10-22T02:02:08-07:00", "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Call customer service", "openUrlAction": { "url": "tel:+61234561000" } } }, { "type": "VIEW_DETAILS", "button": { "title": "View order details", "openUrlAction": { "url": "https://partner.com/view/orderstatus" } } } ], "receipt": { "userVisibleOrderId": "BXZ-1603357328" } } } } ] } } }
בקשה שנכשלה
אם שליחת בקשה נכשלת, SubmitOrderResponseMessage
צריך להגדיר את OrderState.state
ל-REJECTED
. התשובה חייבת לכלול גם את RejectionInfo, שמכיל אובייקט RejectionType
שמתאר את סוג השגיאה.
דוגמה לתגובה לא מוצלחת
{ "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" } } } ] } } } ] } } }
שליחת בקשה להטמעת ההזמנה
כך מטמיעים את ה-API לשליחת הזמנות:
אימות
- מבצעים אימותים של שירותים, עגלות קניות וקידומי מכירות, כפי שמתואר בקטע הגדרת תהליך התשלום.
- אם צריך, מחזירים את RejectionInfo עם אחד מהסוגים הבאים:
RejectionInfoType | תרחיש לדוגמה |
---|---|
UNAVAILABLE_SLOT |
זמן האספקה כבר לא תקף. |
PROMO_USER_INELIGIBLE |
כדי לאמת את הזכאות של המשתמש למבצע, משתמשים בכתובת האימייל באובייקט Contact בבקשה. אפשר לעיין בדוגמה בקטע הטמעת שליחת הזמנה עם מבצעים. |
INELIGIBLE |
|
PAYMENT_DECLINED |
לא ניתן לעבד את התשלום. לדוגמה, יכול להיות שהסיבה לכך היא יתרה לא מספיקה בחשבון. |
UNKNOWN |
בכל שגיאת אימות אחרת. |
אם נתקלתם בשגיאות אימות, מגדירים את OrderState.state
לערך REJECTED
. לחלופין, אפשר לציין סיבה ספציפית לדחייה באמצעות התוסף FoodOrderUpdateExtension.foodOrderErrors
. דוגמאות מפורטות במאמר אימות של שליחת הזמנה.
עיבוד התשלום
- מחושבים את
totalPrice
על ידי הוספת המחיר של עגלת הקניות, העמלות, ההנחות, המיסים והטיפ. הערך שלtotalPrice
צריך להיות זהה לערך שלtotalPrice
שהוחזר ב-CheckoutResponseMessage, בתוספת השינוי בסכום התשר אם המשתמש יכול לשנות את התשר. פרטים נוספים זמינים במאמר שינויים במחיר במהלך שליחת ההזמנה. - מעבדים את ההזמנה ואת התשלום אם מחזירים תשובה עם סטטוס ההזמנה
CREATED
אוCONFIRMED
. - כדי לוודא שהתגובה שתוחזר תהיה בפורמט תקין, צריך להשתמש בסוגי נתונים שנוצרו מהסכימה, כפי שמתואר במאמר יצירת ספריות לקוח.
- כדי לעבד את התשלום, משתמשים ב-GoogleProvidedPaymentInstrument.
instrumentToken
. אם לא ניתן לעבד את התשלום, מחזירים את הערך RejectionInfo עם הערךPAYMENT_DECLINED
. פרטים נוספים זמינים במאמר עיבוד תשלומים. - הודעה למשתמש מיד אחרי עיבוד ההזמנה באימייל או ב-SMS.
החזרת התשובה
- אם אין שגיאות, מגדירים את OrderState.
state
לערךCREATED
אוCONFIRMED
. - אם נתקלת בשגיאות, צריך להגדיר את OrderState.
state
לערךREJECTED
ולכלול את האובייקט RejectionInfo עם הערך המתאים של RejectionInfoType. - מגדירים את OrderUpdate.
orderManagementActions
.