הגדרת האפשרות 'שליחת הזמנה'

אחרי שיחת התשלום, המשתמש יבדוק את עגלת הקניות המעודכנת כדי לציין את המיסים, דמי המשלוח, ההנחות וחיובים נוספים שתחזירו. המשתמש מאשר ושולח את ההזמנה, ו-Google שולחת לנקודת הקצה של מילוי הבקשה בקשת JSON שמכילה את פרטי ההזמנה. שירות האינטרנט שלכם צריך לקבל את ההזמנה הזו, לעבד אותה ולהגיב ל-Google לגבי מצב ההזמנה.

בקטע הזה מתואר הפורמט של ההודעה לבקשת הזמנה שנשלח על ידי Google. הוא נקרא SubmitOrderRequestMessage, והפורמט של הודעת התשובה שצריך לשלוח. הפורמט הזה נקרא SubmitOrderResponseMessage. מידע נוסף על מחזור החיים של אספקת הזמנות זמין בסקירה הכללית על מילוי הזמנות.

הטמעת הזמנות

שירות האינטרנט של Ordering מקצה לקצה, שנוצר כדי לעבוד עם ההזמנה מקצה לקצה, חייב לכלול נקודת קצה (endpoint) של כתובת URL לקבלת הודעות על הזמנות מ-Google. לצורך עיבוד הזמנות, שירות האינטרנט מקבל SubmitOrderRequestMessage בפורמט JSON כבקשת POST מ-Google. הבקשה הזו כוללת הזמנת לקוח, כולל מיסים, עמלות ופרטי תשלום. כשאתם מקבלים בקשה לשליחת הזמנה, שירות האינטרנט צריך לבצע את הפעולות הבאות:

  • לבדוק את הזכאות לביצוע עסקאות, למשל אימות כרטיס או זיהוי הונאות.
  • אפשר ליצור הזמנה במערכת.
  • מאשרים את אמצעי התשלום וקוראים לממשק ה-API לחיוב של החברה לעיבוד תשלומים, במקרים הרלוונטיים.
  • יש לשלוח תשובה עם המצב המתאים של הצו: CREATED, CONFIRMED או REJECTED.

לאחר עיבוד ההזמנה, קוד מילוי ההזמנה צריך לשלוח תשובה ל-Google בפורמט של הודעת JSON מסוג SubmitOrderResponseMessage.

למידע נוסף על הדרישות בנוגע להטמעת שירותי אינטרנט של מילוי הזמנות מקצה לקצה, קראו את הסקירה הכללית על מילוי הזמנות.

הודעה עם בקשת הזמנה

כשלקוח בוחר לבצע הזמנה במהלך תהליך ההזמנה מקצה לקצה, Google שולחת בקשה לשירות האינטרנט שלכם באמצעות הודעת JSON שנקראת SubmitOrderRequestMessage, שמכילה את הנתונים הבאים:

  1. Intent: השדה inputs[0].intent בכל גוף של בקשת הזמנה שנשלחה מכיל את ערך המחרוזת actions.intent.TRANSACTION_DECISION.
  2. Order: השדה inputs[0].arguments[0].transactionDecisionValue של בקשה לשליחת הזמנה מכיל אובייקט Order שמייצג את ההזמנה של הלקוח לביצוע, וגם את פרטי התשלום.
  3. סימון ארגז חול: השדה 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 לשליחת הזמנה.

אימות

  1. מבצעים אימות של השירות, עגלת הקניות והמבצע כפי שהוגדר בהגדרת התשלום.
  2. במקרה הצורך, מחזירים את הערך RejectionInfo באחד מהסוגים הבאים:
RejectionInfoType תרחיש לדוגמה
UNAVAILABLE_SLOT מועד האספקה כבר לא בתוקף.
PROMO_USER_INELIGIBLE כדי לאמת את הזכאות של המשתמש למבצע, יש להשתמש באובייקט 'אימייל' באובייקט יצירת קשר בבקשה. אפשר לראות את הדוגמה בקטע הטמעת הזמנה עם מבצעים.
INELIGIBLE
  • פרטי המשתמש, כמו מספר טלפון או כתובת אימייל, לא תקינים.
  • מנוע הסיכונים שלכם מזהה הונאה.
PAYMENT_DECLINED לא ניתן לעבד את התשלום. לדוגמה, הסיבה לכך יכולה להיות שאין מספיק כסף בחשבון.
UNKNOWN כל שגיאת אימות אחרת.

מגדירים את OrderState.state לערך REJECTED אם מתרחשות שגיאות אימות. תוכלו גם לציין סיבה ספציפית לדחייה באמצעות FoodOrderUpdateExtension.foodOrderErrors ראו דוגמאות בקטע שליחת אישור הזמנה.

עיבוד התשלום

  1. כדי לחשב את totalPrice, מוסיפים את מחיר עגלת הקניות, העמלות, ההנחה, המיסים ותידרות. הערך totalPrice צריך להיות זהה לערך totalPrice שמוחזר ב-CheckoutResponseMessage, בתוספת השינוי בסכום התמורה אם המשתמש יכול לשנות אותו. לפרטים נוספים, ראו שינויים במחיר במהלך שליחת ההזמנה.
  2. מעבדים את ההזמנה ואת התשלום אם מחזירים תשובה עם סטטוס הזמנה CREATED או CONFIRMED.
  3. כדי להבטיח שיוחזר פורמט תגובה חוקי, צריך להשתמש בסוגים שנוצרו באמצעות הסכימה, כפי שמתואר בקטע יצירת ספריות לקוח.
  4. משתמשים ב-GoogleProvidedPaymentInstrument.instrumentToken כדי לעבד את התשלום. אם אי אפשר לעבד את התשלום, עליכם להחזיר את הערך RejectionInfo עם הסוג PAYMENT_DECLINED. לפרטים נוספים קראו את המאמר עיבוד תשלומים.
  5. מיידעים את המשתמש מיד לאחר עיבוד ההזמנה באימייל או ב-SMS.

החזרת התשובה

  1. אם אין שגיאות, מגדירים את OrderState.state ל-CREATED או ל-CONFIRMED.
  2. אם אירעו שגיאות, מגדירים את הערך OrderState.state REJECTED. אם אירעו שגיאות, כוללים את האובייקט RejectionInfo עם הערך המקביל מסוג RejectionInfoType.
  3. מגדירים את OrderUpdate.orderManagementActions.