É possível adicionar suporte ao processamento do pedido para que os usuários agendem a retirada e
entrega de pedidos de comida com antecedência. Antes de implementar esse suporte
processamento do pedido, crie um feed de inventário de serviços que especifique o horário de funcionamento para os usuários
fazer pedidos antecipados, conforme descrito no esquema do feed de inventário.
(AdvanceServiceDeliveryHoursSpecification
).
Slots de pedidos avançados
O Google propõe espaços para pedidos antecipados em incrementos de 15 minutos, por até 7 dias
à frente, com base nos tempos de atendimento de um restaurante ou serviço (conforme definido nas
AdvanceServiceDeliveryHoursSpecification
).
Para recuperar os espaços de pedido antecipado propostos, use os seguintes valores do
Campo fulfillmentPreference
do objeto FoodCartExtension
na finalização da compra:
PickupInfo.pickupTimeIso8601
DeliveryInfo.deliveryTimeIso8601
Implemente pedidos antecipados na finalização da compra
A tabela abaixo lista as possíveis maneiras de implementar o fulfillment resposta no momento da finalização da compra quando os usuários tentam fazer pedidos.
Cenário | Comportamento de atendimento do pedido |
---|---|
É possível atender a um pedido antecipado para o horário solicitado. | Aceitar a P0M ("assim que possível") ou
carrinho de FUTURE_SLOT criando um ProposedOrder com o
mesmo slot. Para ver um exemplo de resposta de finalização de compra aceita um horário, consulte
este snippet de código. |
Não é possível cumprir o pedido avançado para o espaço solicitado. | Seu fulfillment deve fazer o seguinte:
Para conferir um exemplo de resposta de finalização de compra propondo slots alternativos, consulte este snippet de código. |
Slots alternativos para processamento do pedido
Na finalização da compra, se as vagas do pedido antecipado proposto pelo Google não forem adequadas, seu
O fulfillment pode sugerir alternativas usando o CheckoutResponseMessage
objeto.
Para especificar espaços alternativos para pedidos antecipados, responda à solicitação de finalização de compra com um
FoodErrorExtension
e defina estes valores:
- No parâmetro
foodOrderErrors
, especifique o tipo de erro (comoUNAVAILABLE_SLOT
,NO_CAPACITY
ouCLOSED
). - No parâmetro
correctedProposedOrder
, forneçaP0M
ouFUTURE_SLOT
poravailableFulfillmentOptions
.
Os horários alternativos devem ser para os próximos sete dias a partir do momento do pedido e incluir todos os espaços em que o carrinho solicitado pelo usuário pode cumpridas.
Por exemplo, digamos que promoções de almoço estejam disponíveis apenas de segunda a sexta-feira das 11h às 13h. O usuário então tenta adicionar especiais de almoço ao carrinho, mas o espaço selecionado não esteja disponível. Nesse caso, o fulfillment precisa manter os descontos especiais no carrinho e devolver apenas os horários das 11h às 13h. nos próximos sete dias
Omita o objeto correctedProposedOrder.Cart.fulfillmentPreference
na sua resposta.
Se não houver horários disponíveis ou se o restaurante ou serviço não tiver
oferecer suporte a pedidos antecipados, não será preciso fornecer um
correctedProposedOrder
:
Confira os exemplos abaixo para as mensagens JSON entre o fulfillment e o Google durante o fluxo de solicitação e resposta de finalização de compra de um pedido antecipado, quando o restaurante ou serviço para fazer encomendas.
Exemplo: CheckoutRequest com slot de entrega
O snippet abaixo mostra um exemplo de solicitação de finalização de compra com um pedido antecipado no slot de entrega.
{
"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": {
...
}
}
}
}
]
}
]
}
Exemplo: CheckoutResponse aceitando o slot
O snippet abaixo mostra um exemplo de resposta de finalização de compra em que o atendimento aceita os slots de pedidos antecipados propostos.
{
"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": {
...
}
}
}
}
]
}
}
}
Exemplo: CheckoutResponse com espaços alternativos
O snippet abaixo mostra um exemplo de resposta de finalização de compra em que o atendimento
propõe espaços alternativos para pedidos antecipados. Observe que o
O objeto correctedProposedOrder.Cart.fulfillmentPreference
precisa ser omitido na
sua resposta.
{
"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": {
...
}
}
}
}
]
}
}
}
Implementar pedidos antecipados ao enviar pedido
No envio do pedido, se houver um problema com os slots de pedidos avançados, seu
SubmitOrderResponseMessage
precisa incluir o motivo (como
UNAVAILABLE_SLOT
ou UNKNOWN
) no objeto RejectionInfo
.
Atualize o estado do pedido de CREATED
para CONFIRMED
no
OrderState
quando o pedido for aceito pelo provedor. Inclua o parâmetro
o horário selecionado no e-mail de confirmação enviado ao usuário.
Se o atendimento do pedido enviar o pedido para o restaurante mais tarde, envie ao Google uma atualizar usando a ação assíncrona de atualização de pedido.
No objeto OrderUpdate
da resposta do pedido de envio ou
atualizações de pedidos assíncronas subsequentes, inclua um
estimatedFulfillmentTimeIso8601
com o valor definido da seguinte maneira:
- Quando o status do pedido for
CREATED
ouCONFIRMED
, defina o valor como o o horário de entrega ou retirada que o usuário agendou para o pedido antecipado. - Quando há um tempo de entrega estimado mais preciso do restaurante ou serviço, defina o valor como o tempo estimado de entrega ou retirada.
Exemplo: SubmitOrderRequest com espaço de entrega
O snippet abaixo mostra um exemplo de solicitação de envio de pedido que indica slot de pedido antecipado selecionado pelo usuário.
{
"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": {
...
}
}
}
}
]
}
]
}
Exemplo: SubmitOrderResponse aceita o pedido
O snippet abaixo mostra um exemplo de resposta de envio de pedido em que o O fulfillment confirma que aceitou o pedido antecipado do usuário.
{
"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"
}
}
}
}
]
}
}
}
Exemplo: SubmitOrderResponse recusa o pedido por indisponibilidade de espaço
O snippet abaixo mostra um exemplo de resposta de envio de pedido em que o O fulfillment recusa o pedido antecipado de um usuário devido a um espaço indisponível.
{
"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": [
...
]
}
}
}
]
}
}
}
Exemplos de pedidos avançados
O tipo AdvanceServiceDeliveryHoursSpecification
pode ser usado para especificar
os horários de entrega ou retirada para que os usuários agendem o pedido com antecedência.
Observação : é preciso especificar duas janelas de tempo separadas.
para o fulfillment do serviço: a janela de pedidos, que especifica quando os usuários podem fazer uma
e a janela de atendimento, que especifica quando o pedido deve ser atendido. A
O objeto
define quando o usuário
fazer o pedido. Os tempos de fulfillment filhos (OpeningHoursSpecification
)
ou ServiceDeliveryHoursSpecification
) definem quando o pedido pode ser
cumpridas.AdvanceServiceDeliveryHoursSpecification
O exemplo a seguir define o horário de funcionamento de um serviço para aceitar pedidos antecipados. com intervalos de serviço de 15 minutos.
{ "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" } } ] } ] }
O exemplo a seguir mostra como especificar que o serviço está aberto para pedidos no mesmo dia no dia de Natal, mas fechado para pedidos avançados programados para naquele dia. Este exemplo é compatível com os seguintes cenários:
- Os usuários podem fazer um pedido em 25 de dezembro para entrega no mesmo dia.
- Os usuários podem fazer um pedido antecipado em 25 de dezembro para entrega programada para 27 de dezembro.
- Os usuários não poderão fazer um pedido antecipado em 22 de dezembro para a entrega programada. em 25 de dezembro.
{ "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" } }
O exemplo a seguir mostra como especificar que o serviço está fechado para pedidos no mesmo dia ou antecipados programados para o Natal, mas abertos para pedidos avançados programados para um dia posterior. Este exemplo suporta os seguintes cenários:
- Os usuários não podem fazer um pedido em 25 de dezembro para entrega no mesmo dia.
- Os usuários podem fazer um pedido antecipado em 25 de dezembro para entrega programada para 27 de dezembro.
- Os usuários não poderão fazer um pedido antecipado em 22 de dezembro para a entrega programada. em 25 de dezembro.
{ "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" } ] }
O exemplo de serviço a seguir aceita pedidos 24 horas por dia, 7 dias por semana, e faz entregas de Das 10h às 14h59min59s em dias úteis:
... { "@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" } } } ...
O serviço de exemplo a seguir aceita pedidos todos os dias, das 8h às 16h59min59s, e os clientes podem optar por uma entrega dentro de uma hora ou escolher uma das slots:
... { "@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" } } ] } ...
O exemplo a seguir mostra um caso em que a loja abre das 8h às 16h59min59s em dias úteis, mas das 8h às 18h59 nos fins de semana. Não aceitamos pedidos 24 horas por dia, 7 dias por semana.
... { // 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" } } ] } ...