הגדרת Google Checkout

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

הגורם המטפל בקופה של שירות האינטרנט חייב להגיב לבקשות POST. כשלקוח בוחר לשלם, Google שולחת לשירות האינטרנט של ההזמנה מקצה לקצה גוף של בקשת JSON בפורמט CheckoutRequestMessage, שכולל את פרטי Cart של הלקוח. לאחר מכן, שירות האינטרנט מגיב באמצעות CheckoutResponseMessage. התרשים הבא ממחיש את התהליך.

התגובה CheckoutMessage מחזירה את עגלת הקניות של הלקוח שלא שונתה, או שגיאה.

כשאתם מקבלים בקשת תשלום, שירות האינטרנט מקצה לקצה של ההזמנה צריך לבצע את הפעולות הבאות:

  • כדאי לבדוק את תוקף עגלת הקניות על סמך המחירים הנוכחיים של הפריטים, הזמינות ושירות הספק.
  • מחשבים את המחיר הכולל (כולל הנחות, מיסים ודמי משלוח).
  • אם הפעולה בוצעה בהצלחה, תוכלו להשיב עם עגלת הקניות שלא שונתה.
  • אם לא יסופקו, תוכלו להשיב עם הודעת שגיאה והצעה חדשה להזמנה.

לפני שמתחילים להטמיע את התשלום בקופה, מומלץ לעיין במסמכי התיעוד בנושא סקירה כללית על מילוי הזמנות.

הודעה לגבי בקשת תשלום

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

הנתונים ב-CheckoutRequestMessage כוללים את הפרטים הבאים:

  • Intent: השדה inputs[0].intent בכל גוף של בקשת תשלום מכיל את ערך המחרוזת actions.foodordering.intent.CHECKOUT.
  • עגלת קניות: השדה inputs[0].arguments[0].extension בבקשת תשלום מכיל אובייקט Cart שמייצג את עגלת הקניות של הלקוח.
  • מסירה או ייצוא נתונים: שדה התוסף של האובייקט Cart מכיל אובייקט FoodCartExtension שמציין את המאפיינים להעברה או לאיסוף:
    • בהזמנות למשלוח, האובייקט FoodCartExtension כולל את הכתובת למשלוח.
    • בהזמנות באיסוף עצמי או באיסוף עצמי, האובייקט FoodCartExtension לא מכיל פרטי מיקום.
  • Sandbox: השדה isInSandbox של בקשת התשלום מכיל ערך בוליאני שמציין אם בטרנזקציה נעשה שימוש בתשלומים דרך Sandbox.

דוגמה לבקשת תשלום

דוגמה ל-CheckoutRequestMessage:

{
    "user": {},
    "conversation": {
        "conversationId": "CTZbZfUlHCybEdcz_5PB3Ttf"
    },
    "inputs": [
        {
            "intent": "actions.foodordering.intent.CHECKOUT",
            "arguments": [
                {
                    "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.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"
                                    ]
                                }
                            }
                        }
                    }
                }
            ]
        }
    ],
    "directActionOnly": true,
    "isInSandbox": true
}

הודעת תגובה לקופה

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

הבקשה מולאה

אם בקשת התשלום הצליחה, CheckoutResponseMessage צריך לכלול את ProposedOrder ואת PaymentOptions:

  • ProposedOrder

    • cart: אובייקט cart שזהה לעגלת הקניות שסופקה ב-CheckoutRequestMessage. אם צריך לשנות חלק מתוכן העגלה, השדה CheckoutResponseMessage צריך לכלול במקום זאת FoodErrorExtension עם ProposedOrder מתוקן.
    • otherItems: פריטים שהספק הוסיף, כמו דמי משלוח, מיסים ועמלות אחרות. עשוי להכיל גם דמי שירות שנוספו על ידי המשתמש.
    • totalPrice: המחיר הכולל של ההזמנה.
    • extension: FoodOrderExtension שמגדירים את פרטי האספקה של ההזמנה, כמו זמן האספקה.
  • PaymentOptions

    • בהמשך אפשר לקרוא על הגדרת עיבוד התשלומים בקטע הגדרת Google Pay. תוכלו להשתמש ב-placeholder מסוג JSON ב-CheckoutResponseMessage עד שתהיו מוכנים להטמיע את עיבוד התשלומים.
    • כדי להוסיף אפשרויות תשלום placeholder ב-CheckoutResponseMessage, אפשר להיעזר בדוגמה שבהמשך, שמשתמשת בשער תשלומים לדוגמה PaymentOptions.

דוגמה לתשובה מוצלחת

{
    "finalResponse": {
        "richResponse": {
            "items": [
                {
                    "structuredResponse": {
                        "checkoutResponse": {
                            "proposedOrder": {
                                "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"
                                                ]
                                            }
                                        }
                                    }
                                },
                                "totalPrice": {
                                    "type": "ESTIMATE",
                                    "amount": {
                                        "currencyCode": "AUD",
                                        "units": "43",
                                        "nanos": 100000000
                                    }
                                },
                                "extension": {
                                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension",
                                    "availableFulfillmentOptions": [
                                        {
                                            "fulfillmentInfo": {
                                                "delivery": {
                                                    "deliveryTimeIso8601": "P0M"
                                                }
                                            }
                                        }
                                    ]
                                },
                                "otherItems": [
                                    {
                                        "name": "Delivery fee",
                                        "price": {
                                            "type": "ESTIMATE",
                                            "amount": {
                                                "currencyCode": "AUD",
                                                "units": "3",
                                                "nanos": 500000000
                                            }
                                        },
                                        "type": "DELIVERY"
                                    }
                                ]
                            },
                            "paymentOptions": {
                                "googleProvidedOptions": {
                                    "facilitationSpecification": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"merchantName\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\"],\"allowedCardNetworks\":[\"VISA\",\"MASTERCARD\"],\"billingAddressRequired\":true,\"cvcRequired\":false},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gatewayMerchantId\":\"YOUR_MERCHANT_ID\",\"gateway\":\"cybersource\"}}}],\"transactionInfo\":{\"currencyCode\":\"AUD\",\"totalPriceStatus\":\"ESTIMATED\",\"totalPrice\":\"43.1\"}} "
                                }
                            },
                            "additionalPaymentOptions": [
                                {
                                    "actionProvidedOptions": {
                                        "paymentType": "ON_FULFILLMENT",
                                        "displayName": "Pay when you get your food.",
                                        "onFulfillmentPaymentData": {
                                            "supportedPaymentOptions": []
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }
}

הבקשה לא מולאה

אם בקשת תשלום נכשלה, CheckoutResponseMessage צריך לכלול את הפריט FoodErrorExtension, שכולל רשימה של פריטים ב-FoodOrderError שמתארים את השגיאות שהתרחשו. אם יש שגיאות בהזמנה, כמו שינוי מחיר של פריט בעגלת הקניות, השדה FoodErrorExtension צריך לכלול את correctedProposedOrder.

דוגמה לתשובה שלא הצליחה

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "error": {
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
              "foodOrderErrors": [
                {
                  "error": "CLOSED",
                  "description": "The restaurant is closed."
                }
              ]
            }
          }
        }
      ]
    }
  }
}

יישום Google Checkout

צריך לבצע את הפעולות הבאות במהלך ההטמעה של התשלום בקופה.

אימות השירות

מחזירים FoodOrderError למצב הראשון של שגיאת השירות שנמצא. אי אפשר לשחזר את השגיאות האלה, ולכן יש להחזיר את השגיאה הראשונה. בקטע טיפול בשגיאות תוכלו למצוא תיאור של השגיאות הניתנות לתיקון.

  1. קוראים את הנכס FulfillmentOptionInfo בבקשה כדי לקבוע אם סוג מילוי הבקשה הוא עבור delivery או pickup.
  2. במידת הצורך, מחזירים את סוגי השגיאות הבאים:

    סוג השגיאה תרחיש לדוגמה
    INVALID סוג מילוי הבקשה לא תקין.
    NOT_FOUND לא נמצא סוג מילוי ההזמנה.
    סגור
    • אין חלונות OperationHours להזמנה.
    • ההזמנה היא מיידית ואין כרגע זמינות של ServiceHours.
    • יש סגירת מקרה חירום או שהשירות isDisabled נכון.
    חשוב לדעת שחלונות מיוחדים מקבלים עדיפות על פני חלונות רגילים. בקישורים הבאים תוכלו למצוא דוגמאות לאימות חלון ההזמנה ולהסרת ישויות שירות באופן זמני.
    UNAVAILABLE_SLOT אי אפשר למלא את ההזמנה מראש.
    NO_CAPACITY המסעדה עמוסה ולא מקבלת הזמנות כרגע.
    OUT_OF_SERVICE_AREA לא ניתן לשלוח את ההזמנה לכתובת של המשתמש. כדי לעיין בדוגמאות, ראו אימות כתובת למשלוח.
    NO_COURIER_AVAILABLE אי אפשר לשלוח את ההזמנה בגלל מגבלת זמן האספקה המוגבלת.

אימות עגלת הקניות ותמחרה

  1. מחפשים כל עגלת קניות lineItems ומאמתים אותה עם הנתונים העדכניים במערכת שלכם או במערכת של המוכר. הערך של MenuItemOffer.sku מישות הפיד נכלל כ-LineItem.offerId. אם צריך, יוצרים FoodOrderError לכל פריט. אפשר ליצור שגיאה אחת לכל היותר לכל פריט. במידת הצורך, מחזירים את סוגי השגיאות הבאים:

    סוג השגיאה תרחיש לדוגמה ניתן לשחזור
    INVALID נתוני הפריט או כל נתוני האפשרויות לא תקינים. לא
    NOT_FOUND הפריט או אף אחת מהאפשרויות לא נמצאו. לא
    PRICE_CHANGED המחיר של הפריט או של השילוב של התוסף השתנה. ניתן להתייחס לשגיאה זו כשגיאה ניתנת לשחזור. כן
    AVAILABILITY_CHANGED הסכום המבוקש עבור הפריטים או כל אחת מהאפשרויות אינו זמין. כן
    REQUIREMENTS_NOT_MET אין חריגה ממינימום ההזמנה או מהמקסימום להזמנה. כדי לקבוע את הסכום הזה, צריך לבדוק אם מחיר העגלה נמוך מהעמלה.eligibleTransactionVolumeMin או גבוה מהעמלה.eligibleTransactionVolumeMax. אפשר לראות את הדוגמה הזו בקטע אימות ערך הזמנה מינימלי. לא
  2. מחזירים את הרשימה המאומתת של פריטי lineItems עם הערך LineItemType REGULAR. הסכום של כל המחירים של הפריטים מעגלת הקניות הוא מחיר העגלה, או SUBTOTAL.

עיינו בדוגמאות לאימות פריטים בעגלת הקניות.

חישוב עמלות השירות

  1. מחפשים את ישות העמלה הנכונה של השירות לפי eligibleRegion, validFrom, validThrough ו-priority.
  2. חישוב סכום העמלה בהתאם לישות שהוגדרה עם נכס price, percentageOfCart או pricePerMeter.
  3. אפשר להחזיר את עמלת השירות למשלוח או לאיסוף כ-LineItem עם LineItemType DELIVERY או FEE בהתאמה. מוסיפים את העמלה לרשימה Cart.otherItems.

החלת מבצעים

  1. מחפשים את הישות Deal לפי הערך של promotion.coupon עם המבצע.dealCode.
  2. מאמתים את העסקה ומחזירים FoodOrderError במקרה הצורך. ניתן להתייחס לשגיאות האלה כשגיאות שניתן לשחזר. במידת הצורך, מחזירים את סוגי השגיאות הבאים:

    סוג השגיאה תרחיש לדוגמה
    PROMO_NOT_RECOGNIZED קוד השובר לא זוהה.
    PROMO_EXPIRED התוקף של העסקה פג.
    PROMO_ORDER_INELIGIBLE ההזמנה אינה זכאית לשובר.
    PROMO_NOT_APPLICABLE כל סיבה אחרת.
  3. מחשבים את סכום מחיר המבצע לפי השדה Deal.discount או DealdiscountPercentage.

  4. מחילים את סכום מחיר העסקה על סמך הסכום הכולל של עגלת הקניות או סכום העמלה, בהתאם לעסקה.dealType.

  5. החזרת עגלת הקניות.promotions עם המבצע שהוחל.

  6. מחזירים את המבצע כ-LineItem עם LineItemType DISCOUNT. מוסיפים את ההנחה לרשימה Cart.otherItems עם מחיר שלילי.

החזרת התשובה

  1. יוצרים את ה-ProposedOrder.cart, עגלת התגובות תהיה זהה לעגלת הבקשות אם לא אירעו שגיאות במהלך האימות.
  2. מחזירים את הרשימה ProposedOrderotherItems שכוללת את המיסים, העמלות, התשר והנחה אם חלים כאלה. לפרטים נוספים על ההגדרה של פריט התשר, ראו Gratuity.
  3. כדי לכלול את ProposedOrdertotalPrice, צריך להוסיף את מחיר עגלת הקניות, העמלות, ההנחה, המיסים ותשר.
  4. מחזירים את FoodOrderExtension.availableFulfillmentOptions עם ה-FulfillmentOption המתאים. צריך לעדכן את זמן האיסוף או המסירה המשוער לזמן הצפוי.
  5. אם יש FoodOrderErrors שנוצרו מבדיקות האימות הקודמות:
    • כוללים את StructuredResponse.error ואת רשימת השגיאות ב-FoodErrorExtension.foodOrderErrors.
    • אם אפשר לשחזר את כל השגיאות, מחזירים את הערך ProposedOrder בשדה correctedProposedOrder.
    • אם אפשר לשחזר את כל השגיאות, מחזירים את הערך PaymentOptions בשדה paymentOptions.
    • אם יש אפשרויות תשלום אחרות ואפשר לתקן את כל השגיאות, אפשר לכלול את additionalPaymentOptions.
  6. אם אין שגיאות אימות, מחזירים את הערך proposedOrder, paymentOptions באובייקט CheckoutResponse. אם יש אפשרויות תשלום זמינות אחרות, אפשר לכלול את additionalPaymentOptions.