תהליך התשלום בקופה מופעל כשמשתמש יוצר עגלת קניות. תוכן עגלת המשתמש ופרטים על ההזמנה נשלחים לשירות האינטרנט של Ordering מקצה לקצה. המידע הזה מאומת על ידי שירות האינטרנט, ולאחר מכן אפשר להמשיך או לבצע שינויים בעגלת הקניות לפי הצורך.
הגורם המטפל בקופה של שירות האינטרנט חייב להגיב לבקשות POST. כשלקוח בוחר לשלם, Google שולחת לשירות האינטרנט של ההזמנה מקצה לקצה גוף של בקשת JSON בפורמט CheckoutRequestMessage
, שכולל את פרטי Cart
של הלקוח. לאחר מכן, שירות האינטרנט מגיב באמצעות CheckoutResponseMessage
. התרשים הבא ממחיש את התהליך.
כשאתם מקבלים בקשת תשלום, שירות האינטרנט מקצה לקצה של ההזמנה צריך לבצע את הפעולות הבאות:
- כדאי לבדוק את תוקף עגלת הקניות על סמך המחירים הנוכחיים של הפריטים, הזמינות ושירות הספק.
- מחשבים את המחיר הכולל (כולל הנחות, מיסים ודמי משלוח).
- אם הפעולה בוצעה בהצלחה, תוכלו להשיב עם עגלת הקניות שלא שונתה.
- אם לא יסופקו, תוכלו להשיב עם הודעת שגיאה והצעה חדשה להזמנה.
לפני שמתחילים להטמיע את התשלום בקופה, מומלץ לעיין במסמכי התיעוד בנושא סקירה כללית על מילוי הזמנות.
הודעה לגבי בקשת תשלום
כדי לאמת את עגלת הקניות של הלקוח, כשלקוח בוחר לשלם, 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
.
- בהמשך אפשר לקרוא על הגדרת עיבוד התשלומים בקטע הגדרת Google Pay.
תוכלו להשתמש ב-placeholder מסוג JSON ב-
דוגמה לתשובה מוצלחת
{
"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 למצב הראשון של שגיאת השירות שנמצא. אי אפשר לשחזר את השגיאות האלה, ולכן יש להחזיר את השגיאה הראשונה. בקטע טיפול בשגיאות תוכלו למצוא תיאור של השגיאות הניתנות לתיקון.
- קוראים את הנכס FulfillmentOptionInfo בבקשה
כדי לקבוע אם סוג מילוי הבקשה הוא עבור
delivery
אוpickup
. במידת הצורך, מחזירים את סוגי השגיאות הבאים:
סוג השגיאה תרחיש לדוגמה INVALID סוג מילוי הבקשה לא תקין. NOT_FOUND לא נמצא סוג מילוי ההזמנה. סגור - אין חלונות OperationHours להזמנה.
- ההזמנה היא מיידית ואין כרגע זמינות של ServiceHours.
- יש סגירת מקרה חירום או שהשירות
isDisabled
נכון.
UNAVAILABLE_SLOT אי אפשר למלא את ההזמנה מראש. NO_CAPACITY המסעדה עמוסה ולא מקבלת הזמנות כרגע. OUT_OF_SERVICE_AREA לא ניתן לשלוח את ההזמנה לכתובת של המשתמש. כדי לעיין בדוגמאות, ראו אימות כתובת למשלוח. NO_COURIER_AVAILABLE אי אפשר לשלוח את ההזמנה בגלל מגבלת זמן האספקה המוגבלת.
אימות עגלת הקניות ותמחרה
מחפשים כל עגלת קניות
lineItems
ומאמתים אותה עם הנתונים העדכניים במערכת שלכם או במערכת של המוכר. הערך של MenuItemOffer.sku
מישות הפיד נכלל כ-LineItem.offerId
. אם צריך, יוצרים FoodOrderError לכל פריט. אפשר ליצור שגיאה אחת לכל היותר לכל פריט. במידת הצורך, מחזירים את סוגי השגיאות הבאים:סוג השגיאה תרחיש לדוגמה ניתן לשחזור INVALID נתוני הפריט או כל נתוני האפשרויות לא תקינים. לא NOT_FOUND הפריט או אף אחת מהאפשרויות לא נמצאו. לא PRICE_CHANGED המחיר של הפריט או של השילוב של התוסף השתנה. ניתן להתייחס לשגיאה זו כשגיאה ניתנת לשחזור. כן AVAILABILITY_CHANGED הסכום המבוקש עבור הפריטים או כל אחת מהאפשרויות אינו זמין. כן REQUIREMENTS_NOT_MET אין חריגה ממינימום ההזמנה או מהמקסימום להזמנה. כדי לקבוע את הסכום הזה, צריך לבדוק אם מחיר העגלה נמוך מהעמלה. eligibleTransactionVolumeMin
או גבוה מהעמלה.eligibleTransactionVolumeMax
. אפשר לראות את הדוגמה הזו בקטע אימות ערך הזמנה מינימלי.לא מחזירים את הרשימה המאומתת של פריטי lineItems עם הערך LineItemType
REGULAR
. הסכום של כל המחירים של הפריטים מעגלת הקניות הוא מחיר העגלה, אוSUBTOTAL
.
עיינו בדוגמאות לאימות פריטים בעגלת הקניות.
חישוב עמלות השירות
- מחפשים את ישות העמלה הנכונה של השירות לפי
eligibleRegion
,validFrom
,validThrough
ו-priority
. - חישוב סכום העמלה בהתאם לישות שהוגדרה עם נכס
price
,percentageOfCart
אוpricePerMeter
. - אפשר להחזיר את עמלת השירות למשלוח או לאיסוף כ-LineItem עם LineItemType
DELIVERY
אוFEE
בהתאמה. מוסיפים את העמלה לרשימה Cart.otherItems
.
החלת מבצעים
- מחפשים את הישות Deal לפי הערך של promotion.
coupon
עם המבצע.dealCode
. מאמתים את העסקה ומחזירים FoodOrderError במקרה הצורך. ניתן להתייחס לשגיאות האלה כשגיאות שניתן לשחזר. במידת הצורך, מחזירים את סוגי השגיאות הבאים:
סוג השגיאה תרחיש לדוגמה PROMO_NOT_RECOGNIZED קוד השובר לא זוהה. PROMO_EXPIRED התוקף של העסקה פג. PROMO_ORDER_INELIGIBLE ההזמנה אינה זכאית לשובר. PROMO_NOT_APPLICABLE כל סיבה אחרת. מחשבים את סכום מחיר המבצע לפי השדה Deal.
discount
או DealdiscountPercentage
.מחילים את סכום מחיר העסקה על סמך הסכום הכולל של עגלת הקניות או סכום העמלה, בהתאם לעסקה.
dealType
.החזרת עגלת הקניות.
promotions
עם המבצע שהוחל.מחזירים את המבצע כ-LineItem עם LineItemType
DISCOUNT
. מוסיפים את ההנחה לרשימה Cart.otherItems
עם מחיר שלילי.
החזרת התשובה
- יוצרים את ה-ProposedOrder.
cart
, עגלת התגובות תהיה זהה לעגלת הבקשות אם לא אירעו שגיאות במהלך האימות. - מחזירים את הרשימה ProposedOrder
otherItems
שכוללת את המיסים, העמלות, התשר והנחה אם חלים כאלה. לפרטים נוספים על ההגדרה של פריט התשר, ראו Gratuity. - כדי לכלול את ProposedOrder
totalPrice
, צריך להוסיף את מחיר עגלת הקניות, העמלות, ההנחה, המיסים ותשר. - מחזירים את
FoodOrderExtension.
availableFulfillmentOptions
עם ה-FulfillmentOption המתאים. צריך לעדכן את זמן האיסוף או המסירה המשוער לזמן הצפוי. - אם יש FoodOrderErrors שנוצרו מבדיקות האימות הקודמות:
- כוללים את StructuredResponse.
error
ואת רשימת השגיאות ב-FoodErrorExtension.foodOrderErrors
. - אם אפשר לשחזר את כל השגיאות, מחזירים את הערך ProposedOrder בשדה
correctedProposedOrder
. - אם אפשר לשחזר את כל השגיאות, מחזירים את הערך PaymentOptions בשדה
paymentOptions
. - אם יש אפשרויות תשלום אחרות ואפשר לתקן את כל השגיאות, אפשר לכלול את
additionalPaymentOptions
.
- כוללים את StructuredResponse.
- אם אין שגיאות אימות, מחזירים את הערך
proposedOrder
,paymentOptions
באובייקט CheckoutResponse. אם יש אפשרויות תשלום זמינות אחרות, אפשר לכלול אתadditionalPaymentOptions
.