אחרי שיחת התשלום, המשתמש יבדוק את עגלת הקניות המעודכנת כדי לציין את המיסים, דמי המשלוח, ההנחות וחיובים נוספים שתחזירו. המשתמש מאשר ושולח את ההזמנה, ו-Google שולחת לנקודת הקצה של מילוי הבקשה בקשת JSON שמכילה את פרטי ההזמנה. שירות האינטרנט שלכם צריך לקבל את ההזמנה הזו, לעבד אותה ולהגיב ל-Google לגבי מצב ההזמנה.
בקטע הזה מתואר הפורמט של ההודעה לבקשת הזמנה שנשלח על ידי Google. הוא נקרא SubmitOrderRequestMessage
, והפורמט של הודעת התשובה שצריך לשלוח. הפורמט הזה נקרא SubmitOrderResponseMessage
.
מידע נוסף על מחזור החיים של אספקת הזמנות זמין בסקירה הכללית על מילוי הזמנות.
הטמעת הזמנות
שירות האינטרנט של Ordering מקצה לקצה, שנוצר כדי לעבוד עם ההזמנה מקצה לקצה, חייב לכלול נקודת קצה (endpoint) של כתובת URL לקבלת הודעות על הזמנות מ-Google. לצורך עיבוד הזמנות, שירות האינטרנט מקבל SubmitOrderRequestMessage
בפורמט JSON כבקשת POST מ-Google. הבקשה הזו כוללת הזמנת לקוח, כולל מיסים, עמלות ופרטי תשלום. כשאתם מקבלים בקשה לשליחת הזמנה, שירות האינטרנט צריך לבצע את הפעולות הבאות:
- לבדוק את הזכאות לביצוע עסקאות, למשל אימות כרטיס או זיהוי הונאות.
- אפשר ליצור הזמנה במערכת.
- מאשרים את אמצעי התשלום וקוראים לממשק ה-API לחיוב של החברה לעיבוד תשלומים, במקרים הרלוונטיים.
- יש לשלוח תשובה עם המצב המתאים של הצו:
CREATED
,CONFIRMED
אוREJECTED
.
לאחר עיבוד ההזמנה, קוד מילוי ההזמנה צריך לשלוח תשובה ל-Google בפורמט של הודעת JSON מסוג SubmitOrderResponseMessage
.
למידע נוסף על הדרישות בנוגע להטמעת שירותי אינטרנט של מילוי הזמנות מקצה לקצה, קראו את הסקירה הכללית על מילוי הזמנות.
הודעה עם בקשת הזמנה
כשלקוח בוחר לבצע הזמנה במהלך תהליך ההזמנה מקצה לקצה, Google שולחת בקשה לשירות האינטרנט שלכם באמצעות הודעת JSON שנקראת SubmitOrderRequestMessage
, שמכילה את הנתונים הבאים:
- Intent: השדה
inputs[0].intent
בכל גוף של בקשת הזמנה שנשלחה מכיל את ערך המחרוזתactions.intent.TRANSACTION_DECISION
. - Order: השדה
inputs[0].arguments[0].transactionDecisionValue
של בקשה לשליחת הזמנה מכיל אובייקטOrder
שמייצג את ההזמנה של הלקוח לביצוע, וגם את פרטי התשלום. - סימון ארגז חול: השדה
isInSandbox
בבקשה לשליחת הזמנה מציין אם העסקה משתמשת בתשלומים דרך ארגז חול.
דוגמה לבקשה להזמנה
זאת דוגמה לSubmitOrderRequestMessage
:
JSON
{ "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 }
הודעת תגובה להזמנה
אחרי שתקבלו בקשה, שירות האינטרנט של Ordering מקצה לקצה מעבד את הבקשה ושולח בחזרה 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
:
JSON
{ "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
שמתאר את סוג השגיאה.
דוגמה לתשובה שלא הצליחה
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" } } } ] } } } ] } } }
שליחת הטמעת ההזמנה
יש לבצע את השלבים הבאים כשמטמיעים את ה-API לשליחת הזמנה.
אימות
- מבצעים אימות של השירות, עגלת הקניות והמבצע כפי שהוגדר בהגדרת התשלום.
- במקרה הצורך, מחזירים את הערך RejectionInfo באחד מהסוגים הבאים:
RejectionInfoType | תרחיש לדוגמה |
---|---|
UNAVAILABLE_SLOT |
מועד האספקה כבר לא בתוקף. |
PROMO_USER_INELIGIBLE |
כדי לאמת את הזכאות של המשתמש למבצע, יש להשתמש באובייקט 'אימייל' באובייקט יצירת קשר בבקשה. אפשר לראות את הדוגמה בקטע הטמעת הזמנה עם מבצעים. |
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
.