Vous pouvez ajouter une assistance dans votre traitement pour permettre aux utilisateurs de planifier un enlèvement et
la livraison de repas
à l'avance. Avant d'implémenter cette prise en charge dans
le traitement, créez un flux d'inventaire de services spécifiant les horaires
pour passer des commandes anticipées, comme décrit dans le schéma du flux d'inventaire
(AdvanceServiceDeliveryHoursSpecification
).
Emplacements pour commandes avancées
Google propose des créneaux de commande à l'avance par tranches de 15 minutes, pour une durée maximale de 7 jours
en avance, en fonction des délais de traitement d'un restaurant ou d'un service (tels que définis dans
AdvanceServiceDeliveryHoursSpecification
).
Pour récupérer les créneaux d'avance proposés, utilisez les valeurs suivantes de la
Champ fulfillmentPreference
de l'objet FoodCartExtension
lors du règlement:
PickupInfo.pickupTimeIso8601
DeliveryInfo.deliveryTimeIso8601
Implémentez les commandes à l'avance lors du paiement
Le tableau ci-dessous répertorie les différentes manières d'implémenter le code de traitement au moment du paiement, lorsque les utilisateurs tentent de passer des commandes.
Scénario | Comportement de traitement |
---|---|
La commande à l'avance peut être honorée pour le créneau demandé. | Acceptez les P0M ("dès que possible") ou
panier FUTURE_SLOT en créant un ProposedOrder avec le
même emplacement. Pour obtenir un exemple de réponse de paiement acceptant un emplacement, consultez
cet extrait de code. |
La commande à l'avance ne peut pas être honorée pour le créneau demandé. | Le fulfillment doit effectuer les opérations suivantes:
<ph type="x-smartling-placeholder">
Pour obtenir un exemple de réponse de paiement proposant d'autres emplacements, consultez cet extrait de code. |
Emplacements alternatifs pour le traitement des commandes
Lors du règlement, si les créneaux de commande à l'avance proposés par Google ne sont pas adaptés, votre
le fulfillment peut suggérer des alternatives à l'aide du CheckoutResponseMessage
.
Pour spécifier d'autres créneaux de commande anticipée, répondez à la demande de paiement avec une
FoodErrorExtension
et définissez les valeurs suivantes:
- Dans le paramètre
foodOrderErrors
, spécifiez le type d'erreur (par exemple,UNAVAILABLE_SLOT
,NO_CAPACITY
ouCLOSED
). - Dans le paramètre
correctedProposedOrder
, indiquez un autreP0M
ou ValeursFUTURE_SLOT
viaavailableFulfillmentOptions
.
Les autres créneaux possibles devraient se situer au cours des sept prochains jours à compter de la date de la commande et inclure tous les emplacements dans lesquels le panier demandé par l'utilisateur peut être satisfaite.
Par exemple, supposons que les plats du jour ne sont disponibles que du lundi au vendredi. entre 11h et 13h. L’utilisateur essaie ensuite d’ajouter des plats du jour à son panier, mais le créneau sélectionné n'est pas disponible. Dans ce cas, votre fulfillment doit Conserver les plats du jour dans le panier et retourner uniquement les créneaux de 11 h à 13 h au cours des 7 prochains jours
Vous devez omettre l'objet correctedProposedOrder.Cart.fulfillmentPreference
dans votre réponse.
S'il n'y a pas de créneaux disponibles, ou si le restaurant ou le service n'en propose pas
de commandes anticipées, vous n'avez pas à fournir de
correctedProposedOrder
Consultez les exemples ci-dessous pour les messages JSON échangés entre votre fulfillment et Google pendant le flux de demande et de réponse lors du règlement pour une commande anticipée, lorsque le un restaurant ou un service peuvent servir des précommandes.
Exemple: Demande de paiement avec créneau de livraison
L'extrait de code ci-dessous illustre un exemple de demande de règlement avec une commande anticipée emplacement de livraison.
{
"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": {
...
}
}
}
}
]
}
]
}
Exemple: La fonction CheckoutResponse accepte le créneau.
L'extrait de code ci-dessous montre un exemple de réponse à un règlement dans laquelle votre traitement accepte les emplacements de commande anticipée proposés.
{
"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": {
...
}
}
}
}
]
}
}
}
Exemple: CheckoutResponse avec des emplacements alternatifs
L'extrait de code ci-dessous montre un exemple de réponse à un règlement dans laquelle votre traitement
propose d'autres créneaux
pour les commandes à l'avance. Notez que
L'objet correctedProposedOrder.Cart.fulfillmentPreference
doit être omis dans
votre réponse.
{
"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": {
...
}
}
}
}
]
}
}
}
Mettre en œuvre les commandes anticipées lors de l'envoi de la commande
Lors de l'envoi de la commande, en cas de problème avec les créneaux de commande anticipée, votre
SubmitOrderResponseMessage
doit inclure le motif (par exemple,
UNAVAILABLE_SLOT
ou UNKNOWN
) dans l'objet RejectionInfo
.
Remplacez l'état de la commande CREATED
par CONFIRMED
dans la
objet OrderState
lorsque la commande est acceptée par le fournisseur. Incluez les
créneau sélectionné dans l'e-mail de confirmation envoyé à l'utilisateur.
Si votre traitement envoie la commande au restaurant ultérieurement, envoyez un à l'aide de l'action de mise à jour de commande asynchrone.
Dans l'objet OrderUpdate
de la réponse à l'envoi de la commande de votre traitement, ou
les mises à jour de commandes asynchrones suivantes, incluez un
estimatedFulfillmentTimeIso8601
avec la valeur définie comme suit:
- Si l'état de la commande est
CREATED
ouCONFIRMED
, définissez la valeur sur l'heure de livraison ou de retrait que l'utilisateur a planifiée pour sa commande anticipée. - Lorsque le délai de livraison estimé du restaurant est plus précis ou service, définissez la valeur sur l'heure de livraison ou de retrait estimée.
Exemple: SubmitOrderRequest avec créneau de livraison
L'extrait de code ci-dessous montre un exemple de demande d'envoi de commande indiquant le à un emplacement de commande avancé que l'utilisateur a sélectionné.
{
"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": {
...
}
}
}
}
]
}
]
}
Exemple: SubmitOrderResponse accepter la commande
L'extrait de code ci-dessous montre un exemple de réponse d'envoi de commande dans laquelle votre fulfillment confirme qu'il a accepté la commande anticipée de l'utilisateur.
{
"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"
}
}
}
}
]
}
}
}
Exemple: SubmitOrderResponse refusant la commande en raison de l'indisponibilité du créneau
L'extrait de code ci-dessous montre un exemple de réponse d'envoi de commande dans laquelle votre le traitement refuse la commande anticipée d'un utilisateur en raison d'un créneau non disponible.
{
"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": [
...
]
}
}
}
]
}
}
}
Exemples de commandes anticipées
Le type AdvanceServiceDeliveryHoursSpecification
peut être utilisé pour spécifier
les heures de livraison ou de retrait
pour que les utilisateurs planifient leur commande à l'avance.
Remarque : Vous devez spécifier deux périodes distinctes.
pour le traitement du service: la période de tri, qui spécifie à quel moment les utilisateurs peuvent placer un
commande, et la période de traitement de la commande. La
L'objet
définit quand l'utilisateur
peuvent passer la commande. Ses délais de traitement enfant (OpeningHoursSpecification
)
ou ServiceDeliveryHoursSpecification
) définissent quand l'ordre peut être
satisfaite.AdvanceServiceDeliveryHoursSpecification
L'exemple suivant définit les horaires d'un service pour l'acceptation des commandes à l'avance, avec des intervalles de service de 15 minutes.
{ "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'exemple suivant montre comment spécifier que le service est ouvert pour commandes le jour même le jour de Noël mais fermée pour les commandes à l'avance programmées pour ce jour-là. Cet exemple est compatible avec les scénarios suivants:
- Les utilisateurs peuvent passer commande le 25 décembre pour une livraison le jour même.
- Les utilisateurs peuvent passer une commande anticipée le 25 décembre pour une livraison prévue pour le 27 décembre.
- Les utilisateurs ne peuvent pas passer de commande anticipée le 22 décembre pour une livraison prévue le 25 décembre.
{ "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'exemple suivant montre comment spécifier que le service est fermé pour commandes le jour même ou les commandes à l'avance planifiées pour le jour de Noël, mais ouvertes pour les commandes avancées planifiées pour un jour ultérieur. Cet exemple est compatible avec scénarios:
- Les utilisateurs ne peuvent pas passer commande le 25 décembre avec une livraison le jour même.
- Les utilisateurs peuvent passer une commande anticipée le 25 décembre pour une livraison prévue pour le 27 décembre.
- Les utilisateurs ne peuvent pas passer de commande anticipée le 22 décembre pour une livraison prévue le 25 décembre.
{ "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" } ] }
L'exemple de service suivant accepte les commandes 24h/24, 7j/7 et les livre depuis De 10h à 14h59:59 en semaine :
... { "@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" } } } ...
L'exemple de service suivant accepte les commandes quotidiennes de 8h à 16h59:59, et les clients peuvent opter pour une livraison dans l'heure qui suit ou choisir l'une des emplacements:
... { "@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'exemple suivant montre un cas où le magasin ouvre de 8h à 16h59:59 le en semaine, mais de 8h à 18h59 le week-end. Les commandes ne sont pas acceptées 24h/24, 7j/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" } } ] } ...