Menü feed'lerini ve sipariş tamamlama sepeti öğelerini eşleme
Müşteriler menü feed'inizdeki öğeleri alışveriş sepetlerine ekleyip ödeme yaptığında Google, bu öğelerin fiyatını ve stok durumunu doğrulamak için öğeleri sipariş tamamlama uç noktanıza gönderir. Fiyatlandırma ve stok durumu doğrulandıktan sonra müşteri sipariş verebilir. Bu bölümde, menü feed'i öğelerinin sipariş tamamlama sepeti öğeleriyle nasıl eşleneceği gösterilmektedir.
Bu bölümdeki örnekler, Menü feed'inin ve Alışveriş sepeti şemasının basitleştirilmiş sürümleridir. Yalnızca menü feed'i ile alışveriş sepeti nesnesi arasındaki eşlemeyi göstermekle alakalı alanlar gösterilir. Şemaların tamamı için Menu
ve Cart
adresine bakın.
Menu
feed'inde alışveriş sepetine eklenen öğeler, hem ödeme hem de sipariş gönderme için Cart
nesnesinde gönderilir.
- Basit bir
MenuItem
,lineItems
dizisindeLineItem
olarak temsil edilir.offerId
, seçili menü öğesinin Menü feed'indekioffer.id
'i temsil eder. - Zorunlu bir
MenuItemOption
içerenMenuItem
,lineItems
dizisindeLineItem
olarak temsil edilir.offerId
, seçili menü öğesi seçeneğinin Menü feed'indekioffer.id
değeridir. LineItem
öğesininAddOnMenuItem
değeri,FoodItemExtension
öğesininoptions
dizisindeFoodItemOption
olarak temsil edilir. Her seçeneğin, Menü feed'indeki seçili eklenti menü öğesininoffer.id
'sine karşılık gelen birofferId
'si vardır. Bir AddOnMenuItem öğesinin, her seçenek içindesubOptions
olarak temsil edilen iç içe yerleştirilmiş AddOnMenuItem öğeleri de olabileceğini unutmayın.
Aşağıdaki örneklerde, menü öğeleri menü feed'i ile sipariş sepeti arasında eşlenmektedir.
Bu örnekte basit menü öğelerinin listesi yer almaktadır.
Menü feed'indeki menü öğeleri:
{ "@type": "Menu", "@id": "menu_id", "hasMenuItem": [ { "@type": "MenuItem", "@id": "menuitem_id_1", "offers": [ { "@type": "Offer", "@id": "menuitem_offer_id_1", "price": "p_1", "priceCurrency": "USD" } ] }, { "@type": "MenuItem", "@id": "menuitem_id_2", "offers": [ { "@type": "Offer", "@id": "menuitem_offer_id_2", "price": "p_2", "priceCurrency": "USD" } ] } ] }
Teslimat sepeti ile eşlenen menü öğeleri:
{ "@type": "Cart", "lineItems": [ { "offerId": "menuitem_offer_id_1", "price": { "amount": { "currencyCode": "USD", "units": "dollar(q_1*p_1)", "nanos": "cent(q_1*p_1)" } }, "quantity": "q_1" }, { "offerId": "menuitem_offer_id_2", "price": { "amount": { "currencyCode": "USD", "units": "dollar(q_2*p_2)", "nanos": "cent(q_2*p_2)" } }, "quantity": "q_2" } ] }
Bu örnekte, bir veya daha fazla AddOnMenuItem içeren bir menü öğesi yer alır.
Menü feed'indeki menü öğeleri:
{ "@type": "Menu", "@id": "menu_id", "hasMenuItem": [ { "@type": "MenuItem", "@id": "menuitem_id_1", "offers": [ { "@type": "Offer", "@id": "menuitem_offer_id_1", "price": "p_1", "priceCurrency": "USD" } ], "menuAddOn": [ { "@type": "MenuAddOnSection", "@id": "menuaddon_section_id_1", "hasMenuItem": [ { "@type": "AddOnMenuItem", "@id": "menuitem_addon_id_1", "offers": [ { "@type": "Offer", "@id": "menuitem_addon_offer_id_1", "price": "addon_p_1", "priceCurrency": "USD" } ] }, { "@type": "AddOnMenuItem", "@id": "menuitem_addon_id_2", "offers": [ { "@type": "Offer", "@id": "menuitem_addon_offer_id_2", "price": "addon_p_2", "priceCurrency": "USD" } ] } ] } ] }, { "@type": "MenuItem", "@id": "menuitem_id_2", "offers": [ { "@type": "Offer", "@id": "menuitem_offer_id_2", "price": "p_2", "priceCurrency": "USD" } ] } ] }
Teslimat sepeti ile eşlenen menü öğeleri:
{ "@type": "Cart", "lineItems": [ { "offerId": "menuitem_offer_id_1", "price": { "amount": { "currencyCode": "USD", "units": "dollar(q_1*(p_1 + addon_q_1*addon_p_1 + addon_q_2*addon_p_2))", "nanos": "cent(q_1*(p_1 + addon_q_1*addon_p_1 + addon_q_2*addon_p_2))" } }, "quantity": "q_1", "extension": { "@type": "FoodItemExtension", "options": [ { "offerId": "menuitem_addon_offer_id_1", "price": { "currencyCode": "USD", "units": "dollar(addon_q_1*addon_p_1)", "nanos": "cent(addon_q_1*addon_p_1)" }, "quantity": "addon_q_1" }, { "offerId": "menuitem_addon_offer_id_2", "price": { "currencyCode": "USD", "units": "dollar(addon_q_2*addon_p_2)", "nanos": "cent(addon_q_2*addon_p_2)" }, "quantity": "addon_q_2" } ] } }, { "offerId": "menuitem_offer_id_2", "price": { "amount": { "currencyCode": "USD", "units": "dollar(q_2*p_2)", "nanos": "cent(q_2*p_2)" } }, "quantity": "q_2" } ] }
Bu örnekte, menü öğesi seçenekleri, AddOnMenuItems ve iç içe yerleştirilmiş AddOnMenuItems içeren bir menü öğesi yer almaktadır.
Menü feed'indeki menü öğeleri:
{ "@type": "MenuItem", "@id": "menuitem_id_1", "hasMenuItemOptions": [ { "@type": "MenuItemOption", "value": { "@type": "PropertyValue", "name": "OPTION", "value": "Large", "offers": [ { "@type": "Offer", "@id": "menuitem_option_offer_id_1", "price": "p_1", "priceCurrency": "USD" } ], "menuAddOn": [ { "@type": "AddOnMenuSection", "@id": "menuitem_option_addon_section_id_1", "hasMenuItem": [ { "@type": "AddOnMenuItem", "@id": "menuitem_option_addon_id_1", "offers": [ { "@type": "Offer", "@id": "menuitem_option_addon_offer_id_1", "price": "addon_p_1", "priceCurrency": "USD" } ] }, { "@type": "AddOnMenuItem", "@id": "menuitem_option_addon_id_2", "offers": [ { "@type": "Offer", "@id": "menuitem_option_addon_offer_id_2", "price": "addon_p_2", "priceCurrency": "USD" } ], "menuAddOn": [ { "@type": "AddOnMenuSection", "@id": "menuitem_option_subaddon_section_id_1", "hasMenuItem": [ { "@type": "AddOnMenuItem", "@id": "menuitem_option_subaddon_id_1", "offers": [ { "@type": "Offer", "@id": "menuitem_option_subaddon_offer_id_1", "price": "subaddon_p_1", "priceCurrency": "USD" } ] } ] } ] } ] } ] } } ] }
Teslimat sepeti ile eşlenen menü öğeleri:
{ "@type": "Cart", "lineItems": [ { "offerId": "menuitem_option_offer_id_1", "price": { "amount": { "currencyCode": "USD", "units": "dollar(q_1*(p_1 + addon_q_1*addon_p_1 + addon_q_2*(addon_p_2 + subaddon_q_1*subaddon_p_1)))", "nanos": "cent(q_1*(p_1 + addon_q_1*addon_p_1 + addon_q_2*(addon_p_2 + subaddon_q_1*subaddon_p_1)))" } }, "quantity": "q_1", "extension": { "@type": "FoodItemExtension", "options": [ { "offerId": "menuitem_option_addon_offer_id_1", "price": { "currencyCode": "USD", "units": "dollar(addon_q_1*addon_p_1)", "nanos": "cent(addon_q_1*addon_p_1)" }, "quantity": "addon_q_1" }, { "offerId": "menuitem_option_addon_offer_id_2", "price": { "currencyCode": "USD", "units": "dollar(addon_q_2*(addon_p_2 + subaddon_q_1*subaddon_p_1))", "nanos": "cent(addon_q_2*(addon_p_2 + subaddon_q_1*subaddon_p_1))" }, "quantity": "addon_q_2", "subOptions": [ { "offerId": "menuitem_option_subaddon_offer_id_1", "price": { "currencyCode": "USD", "units": "dollar(subaddon_q_1*subaddon_p_1)", "nanos": "cent(subaddon_q_1*subaddon_p_1)" }, "quantity": "subaddon_q_1" } ] } ] } } ] }
Hataları işleme
CheckoutRequestMessage
işlenirken sorun yaşarsanız CheckoutResponse yerine FoodErrorExtension
içeren bir CheckoutResponseMessage
ile yanıt verebilirsiniz. İşleme sırasında oluşan bir veya daha fazla hatayı tespit etmek için bu yanıtı kullanabilirsiniz.
Hataları gidermenin iki yolu vardır:
- Düzeltilebilir hatalar: Kullanıcının siparişi göndermek için alışveriş sepetini düzenlemesi gerekmez. Örneğin,
Cart
öğesindeki bir öğenin fiyatında değişiklik olduğunu belirlersenizcorrectedProposedOrder
vepaymentOptions
ile birliktePRICE_CHANGED
hata türüne sahip birFoodOrderError
ile yanıt verebilirsiniz. Google, kullanıcıyı değişiklik hakkında bilgilendirir ancak kullanıcınıncorrectedProposedOrder
ile göndermesine izin verir. Kullanıcı dilerse geri dönüp alışveriş sepetini düzenleyebilir. Yeni birCheckoutRequestMessage
veyaSubmitOrderRequestMessage
alırsınız. - Telafi edilemeyen hatalar: Kullanıcının siparişi göndermeden önce alışveriş sepetini düzenlemesi gerekir. Örneğin, restoranın kapalı olduğunu belirlerseniz
CLOSED
hata türüne sahip birFoodOrderError
ile yanıt verebilirsiniz. Google, kullanıcıyı bilgilendirir ve yeni bir restorana güncelleme yapmak için etkileşimi yönetir. Yeni bir alışveriş sepeti için yeni birCheckoutRequestMessage
alırsınız.
Genel olarak, alışveriş sepeti düzeyindeki hataları kurtarılamaz, öğe düzeyindeki hataları ise kurtarılabilir hale getirin. Hata türlerinin ve anlamlarının tam listesi için FoodOrderError
bölümüne bakın.
Fiyat değişikliklerini yönetme
Ödeme sırasında fiyat değişikliği
Bir müşterinin ödeme isteğini işleme alırken fiyat sorunuyla karşılaşırsanız aşağıdakileri yapın:
CheckoutRequestMessage
mesajını, Hataları ele alma bölümünde açıklandığı gibiFoodErrorExtension
içeren birCheckoutResponseMessage
ile yanıtlayın.- Hata yanıtında, fiyatı doğru değere güncellemek için
correctedProposedOrder.cart
öğesini kullanın. Google, düzeltilen siparişi alır ve yeni birCheckoutRequestMessage
yayınlayabilir.
Google, ödeme yapıldıktan sonra ProposedOrder
değiştirilmiş olup olmadığına bakılmaksızın son kullanıcıya bir sipariş onay sayfası gösterir.
ProposedOrder düzeltildiyse Google, kullanıcıyı değişikliklerden haberdar etmek için ek uyarılar gösterebilir. Kullanıcı sipariş vermeyi kabul ederse başka ödeme isteği gönderilmez. Akış, düzeltilen ProposedOrder
ile sipariş göndermeye devam eder.
Ancak kullanıcı dilediğinde fikrini değiştirip sepetini tekrar düzenleyebilir. Alışveriş sepeti bu şekilde güncellendiğinde Google yeni bir CheckoutRequestMessage
gönderir.
Sipariş gönderme sırasında fiyat değişiklikleri
Sipariş gönderme işlemini gerçekleştirirken fiyat sorunuyla karşılaşırsanız (actions.intent.TRANSACTION_DECISION
intent'i tetiklendiyse) yanıtınızda hata mesajı göndermeyin veya fiyatı güncellemeyin. SubmitOrderRequestMessage
içindeki fiyatlar, miktarlar veya diğer ayrıntılar verilerinizle eşleşmiyorsa siparişin istenen şekilde verilemediğini belirtmek için orderState
değerini REJECTED
olarak ayarlayarak yanıt verin.
Ardından, sipariş ve ödeme ayrıntıları geçerliyse orderState
değerini CREATED
veya CONFIRMED
olarak ayarlayın. Ayrıca, siparişin kimliğini sisteminizde temsil etmek için bir actionOrderId
ekleyin. Sonraki güncellemeler gönderilirken bu kimlik kullanılmalıdır.
Ödemeyi işleyemiyorsanız ve SubmitOrderRequestMessage
gönderdiyseniz kullanıcıya siparişin gerçekleşmeyeceğini bildirmek için orderState
değerini REJECTED
olarak ayarlayarak bir AsyncOrderUpdateRequestMessage
gönderebilirsiniz.
Sipariş gönderildikten sonra fiyat değişikliği
Bir müşterinin siparişini gönderirken kullanılan fiyattan farklı bir fiyat olduğunu belirlerseniz Asenkron Sipariş Güncellemelerini Uygulama bölümünde açıklandığı gibi yeni fiyatla bir AsyncOrderUpdateRequestMessage
gönderebilirsiniz.
Asynkron sipariş güncellemelerini kullanarak fiyatları güncellemek için:
lineItemUpdates[x].price
'te fiyatı değiştirin. Bu değer, eklentiler dahil olmak üzere öğenin toplam maliyetini ve miktarla çarpımını yansıtır. (Daha fazla bilgi içinLineItem
öğesininprice
alanının açıklamasına bakın.)lineItemUpdates[x].reason
alanına bir açıklama girin.lineItemUpdates[x].orderState
değeriniCONFIRMED
olarak ayarlayın.
İsterseniz AsyncOrderUpdateRequestMessage'ı göndermeden önce veya sonra ödeme aracından ödeme almayı deneyebilirsiniz. İşlem başarısız olursa (muhtemelen fiyat farkı çok yüksek olduğu için) Google'ı hatadan haberdar etmek üzere OrderUpdate
alanında aşağıdaki ayarlarla bir AsyncOrderUpdateRequestMessage gönderin:
orderState
değeriniREJECTED
olarak ayarlayın.label
alanında hatayı açıklayın.
Ödeme doğrulaması
4. Adım: Ödemeyi uygulayın bölümünde belirtildiği gibi, sipariş tamamlama uç noktanız gelen her CheckoutRequestMessage
üzerinde doğrulama gerçekleştirmeli ve CheckoutResponseMessage
ile yanıt vermelidir.
Başarılı bir doğrulama için CheckoutResponseMessage
örneğini aşağıda görebilirsiniz:
Kullanım alanı | Nasıl uygulanır? |
---|---|
Kullanım alanı 1: Doğrulama başarılı | Dönüş CheckoutResponse . ProposedOrder ve PaymentOptions olmalıdır.
ProposedOrder , vergileri, ücretleri ve alışveriş sepetinin toplam fiyatını içerir. |
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "checkoutResponse": { "proposedOrder": { "id": "sample_proposed_order_id_1", "otherItems": [ { "name":"New customer discount", "price": { "type":"ESTIMATE", "amount": { "currencyCode":"USD", "units":"-5", "nanos": -500000000 } }, "type": "DISCOUNT" }, { "name": "Delivery fee", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "3", "nanos": 500000000 } }, "type": "DELIVERY" }, { "name": "Tax", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "1", "nanos": 500000000 } }, "type": "TAX" } ], "cart": { "merchant": { "id": "https://www.exampleprovider.com/merchant/id1", "name": "Falafel Bite" }, "lineItems": [ { "name": "Pita Chips", "type": "REGULAR", "id": "sample_item_offer_id_1", "offerId": "https://www.exampleprovider.com/menu/item/offer/id1", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "2", "nanos": 750000000 } }, "subLines": [ { "note": "Notes for this item." } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension", "options": [ { "id": "sample_addon_offer_id_1", "offerId": "https://www.exampleprovider.com/menu/item/addon/offer/id1", "name": "Honey Mustard", "price": { "currencyCode": "USD" }, "quantity": 1 }, { "id": "sample_addon_offer_id_2", "offerId": "https://www.exampleprovider.com/menu/item/addon/offer/id2", "name": "BBQ Sauce", "price": { "currencyCode": "USD", "nanos": 500000000 }, "quantity": 1 } ] } }, { "name": "Chicken Shwarma Wrap", "type": "REGULAR", "id": "sample_item_offer_id_2", "offerId": "https://www.exampleprovider.com/menu/item/offer/id2", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "8" } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } }, { "name": "Greek Salad", "type": "REGULAR", "id": "sample_item_offer_id_3", "offerId": "https://www.exampleprovider.com/menu/item/offer/id3", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "9", "nanos": 990000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } }, { "name": "Prawns Biryani", "type": "REGULAR", "id": "sample_item_offer_id_4", "offerId": "https://www.exampleprovider.com/menu/item/offer/id4", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "15", "nanos": 990000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension", "fulfillmentPreference": { "fulfillmentInfo": { "delivery": { "deliveryTimeIso8601": "P90M" } } }, "location": { "coordinates": { "latitude": 37.788783, "longitude": -122.41384 }, "formattedAddress": "1350 CHARLESTON ROAD, MOUNTAIN VIEW, CA, United States", "zipCode": "94043", "city": "Mountain View", "postalAddress": { "regionCode": "US", "postalCode": "94043", "administrativeArea": "CA", "locality": "Mountain View", "addressLines": [ "1350 Charleston Road" ] }, "notes": "Gate code is #111" } } }, "totalPrice": { "type": "ESTIMATE", "amount": { // Represents $36.73 "currencyCode": "USD", "units": "36", "nanos": 730000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension", "availableFulfillmentOptions": [ { "fulfillmentInfo": { "delivery": { "deliveryTimeIso8601": "P90M" } }, "expiresAt": "2017-07-17T12:30:00Z" } ] } }, "paymentOptions": { "googleProvidedOptions": { "tokenizationParameters": { "tokenizationType": "PAYMENT_GATEWAY", "parameters": { "gateway": "stripe", "stripe:publishableKey": "pk_live_stripe_client_key", "stripe:version": "2017-04-06" } }, "supportedCardNetworks": [ "AMEX", "DISCOVER", "MASTERCARD", "JCB", "VISA" ], "prepaidCardDisallowed": true } } } } } ] } } }
Teslimat adresi doğrulaması
Siparişin sonlandırılması uç noktanız, her CheckoutRequestMessage
içinde bulunan teslimat adresini doğrulamalıdır.
Teslimat adresiyle ilgili bir sorun varsa (ör. teslimat hizmetinin kapsamı dışındaysa) sipariş karşılama ekibiniz tarafından döndürülen CheckoutResponseMessage
, uygun türde bir FoodOrderError
içermelidir.
Kullanım alanı | Nasıl uygulanır? |
---|---|
Kullanım alanı 1: Teslimat adresi aralık dışında olduğundan veya teslimat adresiyle ilgili bir sorun olduğundan doğrulama başarısız oldu | OUT_OF_SERVICE_AREA hata türünde FoodOrderError ile FoodErrorExtension döndürülür. |
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "OUT_OF_SERVICE_AREA", "description": "Sorry, the restaurant cannot deliver to your address." } ] } } } ] } } }
Minimum sipariş değeri doğrulaması
Siparişin karşılanması için kullanılan uç noktanız, her CheckoutRequestMessage
için minimum sipariş değerini doğrulamalıdır.
Minimum sipariş değeri karşılanmıyorsa sipariş karşılama hizmetiniz tarafından döndürülen CheckoutResponseMessage
, REQUIREMENTS_NOT_MET
hata türüne sahip bir FoodOrderError
içermelidir.
Kullanım alanı | Nasıl uygulanır? |
---|---|
Kullanım alanı 1: Minimum sipariş değeri karşılanmadığı için doğrulama başarısız oldu | REQUIREMENTS_NOT_MET hata türünde FoodOrderError ile FoodErrorExtension döndürülür. |
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "REQUIREMENTS_NOT_MET", "description": "The cart subtotal must be over $20." } ] } } } ] } } }
Sipariş aralığı doğrulaması
Siparişin son tarihini etkileyebilecek tüm faktörler, sipariş tamamlama uç noktanız tarafından doğrulanmalıdır.CheckoutRequestMessage
Örneğin, restoran kapalıysa veya şu anda sipariş almıyorsa sipariş karşılama hizmetiniz tarafından döndürülen CheckoutResponseMessage
, sırasıyla CLOSED
veya NO_CAPACITY
hata türüne sahip bir FoodOrderError
içermelidir.
Kullanım alanı | Nasıl uygulanır? |
---|---|
Kullanım alanı 1: Restoran kapalı olduğu veya artık desteklenmediği için doğrulama başarısız oldu | CLOSED hata türüne sahip FoodOrderError ile FoodErrorExtension döndürülür. |
2. kullanım alanı: Restoran meşgul olduğu ve şu anda sipariş almadığı için doğrulama başarısız oldu | NO_CAPACITY hata türüne sahip FoodOrderError ile FoodErrorExtension döndürülür. |
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "CLOSED", "description": "The restaurant is closed." } ] } } } ] } } }
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "NO_CAPACITY", "description": "Sorry, the restaurant is busy at the moment." } ] } } } ] } } }
Alışveriş sepeti öğelerinin doğrulanması
Siparişin karşılanması için kullanılan uç noktanız, CheckoutRequestMessage
içinde bulunan her alışveriş sepeti öğesinin fiyatını ve stok durumunu doğrulamalıdır.
Stok durumu veya fiyatlandırma değiştiyse sipariş karşılama hizmetiniz tarafından döndürülen CheckoutResponseMessage
, sırasıyla AVAILABILITY_CHANGED
veya PRICE_CHANGED
hata türüne sahip bir FoodOrderError
içermelidir.
Kullanım alanı | Nasıl uygulanır? |
---|---|
Kullanım alanı 1: Bazı menü öğeleri ve/veya özelleştirmeleri geçerli olmadığı veya stokta olmadığı için doğrulama başarısız oldu | AVAILABILITY_CHANGED hata türüne sahip correctedProposedOrder , PaymentOptions ve FoodOrderError ile FoodErrorExtension döndürme Geçersiz öğeler CorrectedProposedOrder 'ten kaldırılmalıdır. |
2. kullanım alanı: Bazı menü öğeleri ve/veya bunların özelleştirmeleri geçerli olmadığı veya stokta olmadığı için doğrulama başarısız oldu. Düzeltilen alışveriş sepeti artık minimum sipariş değeri şartını karşılamıyor. | AVAILABILITY_CHANGED ve REQUIREMENTS_NOT_MET hata türlerinden FoodOrderError ile FoodErrorExtension döndürme |
3. kullanım alanı: Bazı menü öğelerinin ve/veya özelleştirme fiyatlarının değişmesi nedeniyle doğrulama başarısız oldu | PRICE_CHANGED hata türüne sahip correctedProposedOrder , PaymentOptions ve FoodOrderError ile FoodErrorExtension döndürme Güncel olmayan fiyatlar CorrectedProposedOrder 'te güncellenmelidir. |
Kullanım alanı 4: Bazı menü öğeleri ve/veya özelleştirme fiyatları değiştiği için doğrulama başarısız oldu. Düzeltilen alışveriş sepeti artık minimum sipariş değeri şartını karşılamıyor | PRICE_CHANGED ve REQUIREMENTS_NOT_MET hata türlerinden FoodOrderError ile FoodErrorExtension döndürme |
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "AVAILABILITY_CHANGED", "id": "sample_item_offer_id_1", "description": "The item is no longer available." }, { "error": "AVAILABILITY_CHANGED", "id": "sample_item_offer_id_2", "description": "The item is no longer available." } ], "correctedProposedOrder": { "id": "sample_corrected_proposed_order_id_1", "otherItems": [ { "name":"New customer discount", "price": { "type":"ESTIMATE", "amount": { "currencyCode":"USD", "units":"-5", "nanos": -500000000 } }, "type": "DISCOUNT" }, { "name": "Delivery fee", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "3", "nanos": 500000000 } }, "type": "DELIVERY" }, { "name": "Tax", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "1", "nanos": 500000000 } }, "type": "TAX" } ], "cart": { "merchant": { "id": "https://www.exampleprovider.com/merchant/id1", "name": "Falafel Bite" }, "lineItems": [ { "name": "Greek Salad", "type": "REGULAR", "id": "sample_item_offer_id_3", "offerId": "https://www.exampleprovider.com/menu/item/offer/id3", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "9", "nanos": 990000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } }, { "name": "Prawns Biryani", "type": "REGULAR", "id": "sample_item_offer_id_4", "offerId": "https://www.exampleprovider.com/menu/item/offer/id4", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "15", "nanos": 990000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension", "fulfillmentPreference": { "fulfillmentInfo": { "delivery": { "deliveryTimeIso8601": "P90M" } } }, "location": { "coordinates": { "latitude": 37.788783, "longitude": -122.41384 }, "formattedAddress": "1350 CHARLESTON ROAD, MOUNTAIN VIEW, CA, United States", "zipCode": "94043", "city": "Mountain View", "postalAddress": { "regionCode": "US", "postalCode": "94043", "administrativeArea": "CA", "locality": "Mountain View", "addressLines": [ "1350 Charleston Road" ] }, "notes": "Gate code is #111" } } }, "totalPrice": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "36", "nanos": 730000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension", "availableFulfillmentOptions": [ { "fulfillmentInfo": { "delivery": { "deliveryTimeIso8601": "P90M" } }, "expiresAt": "2017-07-17T12:30:00Z" } ] } }, "paymentOptions": { "googleProvidedOptions": { "tokenizationParameters": { "tokenizationType": "PAYMENT_GATEWAY", "parameters": { "gateway": "stripe", "stripe:publishableKey": "pk_live_stripe_client_key", "stripe:version": "2017-04-06" } }, "supportedCardNetworks": [ "AMEX", "DISCOVER", "MASTERCARD", "JCB", "VISA" ], "prepaidCardDisallowed": true } } } } } ] } } }
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "REQUIREMENTS_NOT_MET", "description": "The cart subtotal must be over $20." }, { "error": "AVAILABILITY_CHANGED", "id": "cart_lineitem_id" "description": "cart_lineitem_id is no longer available." } ] } } } ] } } }
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "PRICE_CHANGED", "id": "sample_item_offer_id_1", "description": "The price has changed.", "updatedPrice": { "currencyCode": "USD", "units": "2", "nanos": 750000000 } }, { "error": "PRICE_CHANGED", "id": "sample_item_offer_id_2", "description": "The price has changed.", "updatedPrice": { "currencyCode": "USD", "units": "8" } } ], "correctedProposedOrder": { "id": "sample_corrected_proposed_order_id_1", "otherItems": [ { "name":"New customer discount", "price": { "type":"ESTIMATE", "amount": { "currencyCode":"USD", "units":"-5", "nanos": -500000000 } }, "type": "DISCOUNT" }, { "name": "Delivery fee", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "3", "nanos": 500000000 } }, "type": "DELIVERY" }, { "name": "Tax", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "1", "nanos": 500000000 } }, "type": "TAX" } ], "cart": { "merchant": { "id": "https://www.exampleprovider.com/merchant/id1", "name": "Falafel Bite" }, "lineItems": [ { "name": "Pita Chips", "type": "REGULAR", "id": "sample_item_offer_id_1", "offerId": "https://www.exampleprovider.com/menu/item/offer/id1", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "2", "nanos": 750000000 } }, "subLines": [ { "note": "Notes for this item." } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension", "options": [ { "id": "sample_addon_offer_id_1", "offerId": "https://www.exampleprovider.com/menu/item/addon/offer/id1", "name": "Honey Mustard", "price": { "currencyCode": "USD" }, "quantity": 1 }, { "id": "sample_addon_offer_id_2", "offerId": "https://www.exampleprovider.com/menu/item/addon/offer/id2", "name": "BBQ Sauce", "price": { "currencyCode": "USD", "nanos": 500000000 }, "quantity": 1 } ] } }, { "name": "Chicken Shwarma Wrap", "type": "REGULAR", "id": "sample_item_offer_id_2", "offerId": "https://www.exampleprovider.com/menu/item/offer/id2", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "8" } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } }, { "name": "Greek Salad", "type": "REGULAR", "id": "sample_item_offer_id_3", "offerId": "https://www.exampleprovider.com/menu/item/offer/id3", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "9", "nanos": 990000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } }, { "name": "Prawns Biryani", "type": "REGULAR", "id": "sample_item_offer_id_4", "offerId": "https://www.exampleprovider.com/menu/item/offer/id4", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "15", "nanos": 990000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension", "fulfillmentPreference": { "fulfillmentInfo": { "delivery": { "deliveryTimeIso8601": "P90M" } } }, "location": { "coordinates": { "latitude": 37.788783, "longitude": -122.41384 }, "formattedAddress": "1350 CHARLESTON ROAD, MOUNTAIN VIEW, CA, United States", "zipCode": "94043", "city": "Mountain View", "postalAddress": { "regionCode": "US", "postalCode": "94043", "administrativeArea": "CA", "locality": "Mountain View", "addressLines": [ "1350 Charleston Road" ] }, "notes": "Gate code is #111" } } }, "totalPrice": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "36", "nanos": 730000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension", "availableFulfillmentOptions": [ { "fulfillmentInfo": { "delivery": { "deliveryTimeIso8601": "P90M" } }, "expiresAt": "2017-07-17T12:30:00Z" } ] } }, "paymentOptions": { "googleProvidedOptions": { "tokenizationParameters": { "tokenizationType": "PAYMENT_GATEWAY", "parameters": { "gateway": "stripe", "stripe:publishableKey": "pk_live_stripe_client_key", "stripe:version": "2017-04-06" } }, "supportedCardNetworks": [ "AMEX", "DISCOVER", "MASTERCARD", "JCB", "VISA" ], "prepaidCardDisallowed": true } } } } } ] } } }
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension", "foodOrderErrors": [ { "error": "REQUIREMENTS_NOT_MET", "description": "The cart subtotal must be over $20." }, { "error": "PRICE_CHANGED", "id": "cart_lineitem_id" "description": "cart_lineitem_id price has been updated." "updatedPrice": { "currencyCode": "USD", "units": "2", "nanos": 750000000 } } ] } } } ] } } }
Sipariş doğrulamasını gönderme
7. Adım: Sipariş Gönder'i uygulayın bölümünde belirtildiği gibi, sipariş tamamlama uç noktanız gelen her SubmitOrderRequestMessage
üzerinde doğrulama gerçekleştirmeli ve SubmitOrderResponseMessage
ile yanıt vermelidir.
Başarılı bir doğrulama için SubmitOrderResponseMessage
örneğini aşağıda görebilirsiniz:
Kullanım alanı | Nasıl uygulanır? |
---|---|
Kullanım alanı 1: Sipariş başarıyla oluşturulur | CREATED sipariş durumu olan bir SubmitOrderResponseMessage . actionOrderId ,
userVisibleId , orderManagementActions ve
estimatedFulfillmentTime olmalıdır. |
2. kullanım alanı: Ödeme sorunları nedeniyle sipariş reddedilir | REJECTED sipariş durumu olan bir SubmitOrderResponseMessage . PAYMENT_DECLINED türünde actionOrderId ,
userVisibleId , orderManagementActions ve
rejectionInfo olmalıdır. |
Kullanım alanı 3: Kullanıcının yasaklanmış olarak işaretlenmesi nedeniyle sipariş reddedilir | REJECTED sipariş durumu olan bir SubmitOrderResponseMessage . INELIGIBLE türünde actionOrderId ,
userVisibleId , orderManagementActions ve
rejectionInfo olmalıdır. |
Kullanım alanı 4: Kullanıcı bilgileri eksik veya geçersiz olduğundan sipariş reddediliyor | REJECTED sipariş durumu olan bir SubmitOrderResponseMessage . INELIGIBLE türünde actionOrderId ,
userVisibleId , orderManagementActions ve
rejectionInfo olmalıdır. |
Kullanım alanı 5: Sipariş bilinmeyen bir nedenle reddedilir | REJECTED sipariş durumu olan bir SubmitOrderResponseMessage . UNKNOWN türünde actionOrderId ,
userVisibleId , orderManagementActions ve
rejectionInfo olmalıdır. |
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "CREATED", "label": "Order received" }, "updateTime": "2017-05-10T02:30:00.000Z", "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" } } } ] } } } ] } } }
{ "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" } } } ] } } } ] } } }
{ "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": "INELIGIBLE", "reason": "Sorry, we are not able to take orders from this user" }, "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" } } } ] } } } ] } } }
{ "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": "INELIGIBLE", "reason": "Sorry, the phone number must not be blank" }, "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" } } } ] } } } ] } } }
{ "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": "UNKNOWN", "reason": "Sorry, there is something wrong with this order." }, "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" } } } ] } } } ] } } }