Puoi aggiungere assistenza durante l'evasione degli ordini per consentire agli utenti di programmare il ritiro e
ordini di cibo a domicilio in anticipo. Prima di implementare questo supporto in
fulfillment, crea un feed di inventario dei servizi che specifichi le ore di esercizio
per effettuare ordini in anticipo, come descritto nello schema del feed di inventario
(AdvanceServiceDeliveryHoursSpecification
).
Slot per ordine anticipato
Google propone slot per ordini anticipati con incrementi di 15 minuti, per un massimo di 7 giorni
in anticipo, in base ai tempi di evasione degli ordini per un ristorante o un servizio (come definiti
AdvanceServiceDeliveryHoursSpecification
).
Per recuperare gli slot dell'ordine proposto, utilizza i seguenti valori dal
Campo fulfillmentPreference
dell'oggetto FoodCartExtension
al momento del pagamento:
PickupInfo.pickupTimeIso8601
DeliveryInfo.deliveryTimeIso8601
Implementa gli ordini in anticipo al momento del pagamento
Nella tabella riportata di seguito sono elencati i possibili modi in cui puoi implementare il codice risposta al momento del pagamento, quando gli utenti provano a effettuare un ordine.
Scenario | Comportamento di fulfillment |
---|---|
L'ordine anticipato può essere evaso per lo spazio richiesto. | Accetta i P0M ("il prima possibile") oppure
FUTURE_SLOT creando una ProposedOrder con
nella stessa area. Per un esempio di risposta al pagamento che accetta uno spazio, consulta
questo snippet di codice. |
Impossibile evadere l'ordine anticipato per lo spazio richiesto. | Per l'evasione dell'ordine:
Per un esempio di risposta al pagamento che propone aree alternative, consulta questo snippet di codice. |
Slot alternativi per l'evasione degli ordini
Al momento del pagamento, se gli slot dell'ordine proposto da Google non sono adatti, i tuoi
La distribuzione può suggerire alternative utilizzando CheckoutResponseMessage
.
Per specificare spazi per ordini anticipati alternativi, rispondi alla richiesta di pagamento con un
FoodErrorExtension
e imposta i seguenti valori:
- Nel parametro
foodOrderErrors
, specifica il tipo di errore (ad es.UNAVAILABLE_SLOT
,NO_CAPACITY
oCLOSED
). - Nel parametro
correctedProposedOrder
, fornisci un'alternativaP0M
oFUTURE_SLOT
valori tramiteavailableFulfillmentOptions
.
Gli slot alternativi devono durare i prossimi 7 giorni dal momento dell'ordine posizionamento e includere tutte le aree in cui il carrello richiesto dall'utente può sono soddisfatte.
Ad esempio, supponiamo che le offerte speciali per pranzo siano disponibili solo dal lunedì al venerdì dalle 11:00 alle 13:00. L'utente prova quindi ad aggiungere specialità per pranzo al carrello, ma l'area selezionata non è disponibile. In questo caso, l'evasione degli ordini dovrebbe trattieni le specialità per pranzo nel carrello e restituisci solo gli slot dalle 11:00 alle 13:00 per i prossimi 7 giorni
Devi omettere l'oggetto correctedProposedOrder.Cart.fulfillmentPreference
nella tua risposta.
Se non ci sono posti disponibili oppure se il ristorante o il servizio non
per gli ordini anticipati, non devi fornire
correctedProposedOrder
.
Consulta gli esempi riportati di seguito per i messaggi JSON tra il tuo fulfillment e Google durante il flusso di richiesta di pagamento e risposta per un ordine anticipato, quando in un ristorante o in un servizio specifico che sia possibile prenotare.
Esempio: richiesta di pagamento con spazio di consegna
Lo snippet di seguito mostra un esempio di richiesta di pagamento con un ordine anticipato dell'area di pubblicazione.
{
"inputs": [
{
"intent": "actions.foodordering.intent.CHECKOUT",
"arguments": [
{
"extension": {
"@type": "type.googleapis.com/google.actions.v2.orders.Cart",
"merchant": {
"id": "https://www.exampleprovider.com/merchant/id1",
"name": "Cucina Venti"
},
"lineItems": [
{
"name": "Sizzling Prawns Dinner",
"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": "16",
"nanos": 750000000
}
},
}
],
"extension": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
"fulfillmentPreference": {
"fulfillmentInfo": {
"delivery": {
// Deliver at 6:30PM.
"deliveryTimeIso8601": "2017-12-14T18:30:00-07:00"
}
}
},
"location": {
...
}
}
}
}
]
}
]
}
Esempio: accettazione dello spazio da parte di GoogleCheckoutResponse
Lo snippet di seguito mostra un esempio di risposta al pagamento in cui il tuo evasione dell'ordine accetta gli slot dell'ordine anticipato proposti.
{
"expectUserResponse": false,
"finalResponse": {
"richResponse": {
"items": [
{
"structuredResponse": {
"checkoutResponse": {
"proposedOrder": {
"id": "sample_proposed_order_id_1",
"cart": {
"merchant": {
"id": "https://www.exampleprovider.com/merchant/id1",
"name": "Falafel Bite"
},
"lineItems": [
{
"name": "Sizzling Prawns Dinner",
"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": "16",
"nanos": 750000000
}
},
}
],
"extension": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
"fulfillmentPreference": {
"fulfillmentInfo": {
"delivery": {
// Same as the time in the request.
"deliveryTimeIso8601": "2017-12-14T18:30:00-07:00"
}
}
},
"location": {
...
}
}
},
"totalPrice": {
"type": "ESTIMATE",
"amount": {
// Represents $16.75
"currencyCode": "USD",
"units": "16",
"nanos": 750000000
}
},
"extension": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension",
// Send whole proposed order back.
"availableFulfillmentOptions": [
"fulfillmentInfo": {
"delivery": {
// Same as the time in the request.
"deliveryTimeIso8601": "2017-12-14T18:30:00-07:00"
}
}
]
}
},
"paymentOptions": {
...
}
}
}
}
]
}
}
}
Esempio: GoogleCheckResponse con spazi alternativi
Lo snippet di seguito mostra un esempio di risposta al pagamento in cui il tuo evasione dell'ordine
propone spazi per ordini anticipati alternativi. Tieni presente che
L'oggetto correctedProposedOrder.Cart.fulfillmentPreference
deve essere omesso in
la tua risposta.
{
"expectUserResponse": false,
"finalResponse": {
"richResponse": {
"items": [
{
"structuredResponse": {
"error": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
"foodOrderErrors": [
{
"error": "UNAVAILABLE_SLOT", // Cart level error
"description": "The restaurant is closed."
}
],
"correctedProposedOrder": {
// Send whole original cart back,
// without the fulfillmentPreference.
"cart": {
...
},
"otherItems": {
...
},
"totalPrice": {
...
},
"extension": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension",
"availableFulfillmentOptions": [
"fulfillmentInfo": {
"delivery": {
"deliveryTimeIso8601": "2017-12-14T19:00:00-07:00"
}
},
"fulfillmentInfo": {
"delivery": {
"deliveryTimeIso8601": "2017-12-14T19:30:00-07:00"
}
},
"fulfillmentInfo": {
"delivery": {
"deliveryTimeIso8601": "2017-12-14T20:00:00-07:00"
}
}
]
}
},
"paymentOptions": {
...
}
}
}
}
]
}
}
}
Implementa gli ordini in anticipo al momento dell'invio dell'ordine
Al momento dell'invio dell'ordine, se si verifica un problema con gli spazi per gli ordini anticipati,
SubmitOrderResponseMessage
deve includere il motivo (ad esempio
UNAVAILABLE_SLOT
o UNKNOWN
) nell'oggetto RejectionInfo
.
Aggiorna lo stato dell'ordine da CREATED
a CONFIRMED
nel
OrderState
quando l'ordine viene accettato dal fornitore. Includi il parametro
fascia oraria selezionata nell'email di conferma inviata all'utente.
Se l'evasione dell'ordine invia l'ordine al ristorante in un secondo momento, invia a Google una aggiornare utilizzando l'azione di aggiornamento dell'ordine asincrono.
Nell'oggetto OrderUpdate
della risposta dell'ordine per l'evasione dell'ordine oppure
i successivi aggiornamenti asincroni degli ordini,
estimatedFulfillmentTimeIso8601
con il valore impostato come segue:
- Quando lo stato dell'ordine è
CREATED
oCONFIRMED
, imposta il valore su l'orario di consegna o ritiro programmato per l'ordine in anticipo. - Quando il tempo di consegna stimato dal ristorante è più accurato o servizio, imposta il valore sull'orario stimato per la consegna o l'orario di ritiro.
Esempio: SubmitOrderRequest con area di consegna
Lo snippet di seguito mostra un esempio di richiesta di invio di un ordine che indica la spazio per l'ordine anticipato selezionato dall'utente.
{
"inputs": [
{
"intent": "actions.intent.TRANSACTION_DECISION",
"arguments": [
{
"transactionDecisionValue": {
"order": {
"finalOrder": {
"cart": {
"notes": "Guest prefers their food to be hot when it is delivered.",
"merchant": {
"id": "https://www.exampleprovider.com/merchant/id1",
"name": "Cucina Venti"
},
"lineItems": [
{
"name": "Sizzling Prawns Dinner",
"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": "16",
"nanos": 750000000
}
}
}
],
"extension": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
"fulfillmentPreference": {
"fulfillmentInfo": {
"delivery": {
"deliveryTimeIso8601": "2017-12-14T18:30:00-07:00"
}
}
}
"contact": {
...
}
}
},
"totalPrice": {
"type": "ESTIMATE",
"amount": {
"currencyCode": "USD",
"units": "16",
"nanos": 750000000
}
},
"id": "sample_final_order_id",
"extension": {
// Send whole proposed order back.
"availableFulfillmentOptions": [
"fulfillmentInfo": {
"delivery": {
"deliveryTimeIso8601": "2017-12-14T18:30:00-07:00"
}
]
}
},
"googleOrderId": "sample_google_order_id",
"orderDate": "2017-07-17T12:00:00Z",
"paymentInfo": {
...
}
}
}
}
]
}
]
}
Esempio: accettazione dell'ordine su SubmitOrderResponse
Lo snippet di seguito mostra un esempio di risposta di invio di un ordine in cui le tue La distribuzione conferma l'accettazione dell'ordine anticipato dell'utente.
{
"expectUserResponse": false,
"finalResponse": {
"richResponse": {
"items": [
{
"structuredResponse": {
"orderUpdate": {
"actionOrderId": "sample_action_order_id",
"orderState": {
"state": "CREATED",
"label": "Order placed"
},
"receipt": {
"userVisibleOrderId": "userVisibleId1234"
},
"updateTime": "2017-07-17T12:00:00Z",
"orderManagementActions": [
...
],
"infoExtension": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
// Same as the user selected time.
"estimatedFulfillmentTimeIso8601": "2017-12-14T18:30:00-07:00"
}
}
}
}
]
}
}
}
Esempio: SubmitOrderResponse rifiuto dell'ordine a causa dell'indisponibilità dello slot
Lo snippet di seguito mostra un esempio di risposta di invio di un ordine in cui le tue L'evasione degli ordini rifiuta l'ordine anticipato di un utente a causa di uno spazio non disponibile.
{
"expectUserResponse": false,
"finalResponse": {
"richResponse": {
"items": [
{
"structuredResponse": {
"orderUpdate": {
"actionOrderId": "sample_action_order_id",
"orderState": {
"state": "REJECTED",
"label": "Unavailable slot"
},
"rejectionInfo": {
// Note that this UNAVAILABLE_SLOT is different from the enum
// with the same name proposed for FoodOrderError.
"state": "UNAVAILABLE_SLOT",
"label": "Unavailable slot"
},
"updateTime": "2017-07-17T12:00:00Z",
"orderManagementActions": [
...
]
}
}
}
]
}
}
}
Esempi di ordini anticipati
Il tipo AdvanceServiceDeliveryHoursSpecification
può essere utilizzato per specificare
gli orari di consegna o ritiro affinché gli utenti possano pianificare in anticipo l'ordine.
Nota : esistono due finestre temporali separate che è necessario specificare
per il fulfillment del servizio: la finestra di ordine che specifica quando gli utenti possono
e la finestra di evasione in cui è specificato quando viene evaso l'ordine. La
L'oggetto
definisce quando l'utente
possono effettuare l'ordine. I relativi tempi di evasione degli ordini secondari (OpeningHoursSpecification
o ServiceDeliveryHoursSpecification
) definisci quando l'ordine può essere
completato.AdvanceServiceDeliveryHoursSpecification
L'esempio seguente definisce gli orari di un servizio per l'accettazione di ordini anticipati con intervalli di manutenzione di 15 minuti.
{ "hoursAvailable": [ { "@type": "OpeningHoursSpecification", "opens": "T00:00:00", // Ordering available 24 hours "closes": "T23:59:59", "deliveryHours": [ { "@type": "ServiceDeliveryHoursSpecification", "opens": "T09:00:00", // ASAP orders b/w 9am and 8:59:59pm "closes": "T21:00:00", "deliveryLeadTime": { "value": "60", "unitCode": "MIN" } }, { "@type": "AdvanceServiceDeliveryHoursSpecification", "opens": "T10:00:00", // Delivery between 10AM and 7:59:59PM "closes": "T20:00:00", "serviceTimeInterval": "PT15M", // in slots spaced 15 minutes apart (ISO8601) "advanceBookingRequirement": { "minValue": 60, // The slot should be at least 60 mins away "maxValue": 8640, // but not more than 6 days away "unitCode": "MIN" } } ] } ] }
L'esempio seguente mostra come specificare che il servizio è aperto ordini effettuati lo stesso giorno il giorno di Natale ma chiuso per ordini avanzati pianificati per quel giorno. Questo esempio supporta i seguenti scenari:
- Gli utenti possono effettuare un ordine il 25 dicembre con consegna in giornata.
- Gli utenti possono effettuare un ordine in anticipo il 25 dicembre per la consegna pianificata per il 27 dicembre.
- Gli utenti non possono effettuare un ordine anticipato il 22 dicembre per l'invio pianificato il 25 dicembre.
{ "specialOpeningHoursSpecification": { "@type": "AdvanceServiceDeliveryHoursSpecification", "validFrom": "2018-12-25T00:00:00-07:00", "validThrough": "2018-12-26T00:00:00-07:00", "opens": "T00:00:00", // No advance ordering "closes": "T00:00:00" } }
L'esempio seguente mostra come specificare che il servizio è chiuso per ordini in giornata o in anticipo pianificati per il giorno di Natale, ma aperti per per ordini avanzati pianificati per un giorno successivo. Questo esempio supporta i seguenti scenari aggiuntivi:
- Gli utenti non possono effettuare ordini il 25 dicembre con la consegna in giornata.
- Gli utenti possono effettuare un ordine in anticipo il 25 dicembre per la consegna pianificata per il 27 dicembre.
- Gli utenti non possono effettuare un ordine anticipato il 22 dicembre per l'invio pianificato il 25 dicembre.
{ "specialOpeningHoursSpecification": [ { "@type": "ServiceDeliveryHoursSpecification", "validFrom": "2018-12-25T00:00:00-07:00", "validThrough": "2018-12-26T00:00:00-07:00", "opens": "T00:00:00", // No ASAP ordering on Christmas "closes": "T00:00:00" }, { "@type": "AdvanceServiceDeliveryHoursSpecification", "validFrom": "2018-12-25T00:00:00-07:00", "validThrough": "2018-12-26T00:00:00-07:00", "opens": "T00:00:00", // Orders cannot be scheduled for Christmas "closes": "T00:00:00" } ] }
Il seguente servizio di esempio accetta ordini 24 ore su 24, 7 giorni su 7 e consegna a partire da 10:00-14:59:59 nei giorni feriali:
... { "@type": "OpeningHoursSpecification", "opens": "T00:00:00", "closes": "T23:59:59", "deliveryHours": { "@type": "AdvanceServiceDeliveryHoursSpecification", "opens": "T10:00:00", // Delivery starts at 10:00AM "closes": "T15:00:00", // Delivery ends at 3:00PM. Delivery from 10AM-2:59:59PM. "dayOfWeek": [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ], "serviceTimeInterval": "PT15M", // in slots spaced 15 minutes apart "advanceBookingRequirement": { "minValue": 60, // The slot should be at least 60 mins away "maxValue": 8640, // but not more than 6 days away "unitCode": "MIN" } } } ...
Il seguente servizio di esempio accetta ordini ogni giorno dalle 8:00 alle 16:59:59 e i clienti possono optare per la consegna entro un'ora o scegliere una delle slot:
... { "@type": "OpeningHoursSpecification", "opens": "T08:00:00", // Ordering opens at 8:00AM "closes": "T17:00:00", // Ordering closes at 5:00PM, last order at 4:59:59PM "deliveryHours": [ { "@type": "ServiceDeliveryHoursSpecification", "opens": "T08:00:00", "closes": "T17:00:00", "deliveryLeadTime": { "@type": "QuantitativeValue", "value": "60", // If no exact deliveryLeadTime, put a maximum time "unitCode": "MIN" } }, { "@type": "AdvanceServiceDeliveryHoursSpecification", "opens": "T08:00:00", "closes": "T17:00:00", "serviceTimeInterval": "PT15M", // in slots spaced 15 minutes apart "advanceBookingRequirement": { "minValue": 90, // The slot should be at least 90 mins away "maxValue": 8640, // but not more than 6 days away "unitCode": "MIN" } } ] } ...
L'esempio seguente mostra un caso in cui il negozio apre dalle 8:00 alle 16:59:59 su nei giorni feriali, ma dalle 8:00 alle 18:59 nei fine settimana. Gli ordini non vengono accettati 24 ore su 24, 7 giorni su 7.
... { // On weekdays, ordering open from 8AM-4:59:59PM. "@type": "OpeningHoursSpecification", "opens": "T08:00:00", "closes": "T17:00:00", "dayOfWeek": [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ], "deliveryHours": [ { // Fulfillment between 8AM-4:59:59PM on weekdays. "@type": "AdvanceServiceDeliveryHoursSpecification", "opens": "T08:00:00", "closes": "T17:00:00", "dayOfWeek": [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ], "serviceTimeInterval": "PT15M", "advanceBookingRequirement": { "minValue": 60, "maxValue": 8640, "unitCode": "MIN" } }, { // Fulfillment between 8AM-6:59:59PM on weekends (even for orders placed on a // weekday). "@type": "AdvanceServiceDeliveryHoursSpecification", "opens": "T08:00:00", "closes": "T19:00:00", "dayOfWeek": [ "Saturday", "Sunday" ], "serviceTimeInterval": "PT15M", "advanceBookingRequirement": { "minValue": 60, "maxValue": 8640, "unitCode": "MIN" } } ] }, { // On weekends, one can place orders upto 6:59:59PM. "@type": "OpeningHoursSpecification", "opens": "T08:00:00", "closes": "T19:00:00", "dayOfWeek": [ "Saturday", "Sunday" ], "deliveryHours": [ { // But fulfillment on weekdays is only till 4:59:59PM. "@type": "AdvanceServiceDeliveryHoursSpecification", "opens": "T08:00:00", "closes": "T17:00:00", "dayOfWeek": [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ], "serviceTimeInterval": "PT15M", "advanceBookingRequirement": { "minValue": 60, "maxValue": 8640, "unitCode": "MIN" } }, { // Fulfillment on weekends is till 6:59:59PM. "@type": "AdvanceServiceDeliveryHoursSpecification", "opens": "T08:00:00", "closes": "T19:00:00", "dayOfWeek": [ "Saturday", "Sunday" ], "serviceTimeInterval": "PT15M", "advanceBookingRequirement": { "minValue": 60, "maxValue": 8640, "unitCode": "MIN" } } ] } ...