Función de pedido por adelantado v1

Puedes agregar compatibilidad en tu entrega para que los usuarios programen el retiro y pedidos de comida a domicilio con anticipación. Antes de implementar esta asistencia de pedidos, crea un feed de inventario de servicios en el que se especifiquen las horas hacer pedidos por adelantado, como se describe en el esquema del feed de inventario (AdvanceServiceDeliveryHoursSpecification).

Ranuras de pedido anticipado

Google propone horarios disponibles para pedidos por adelantado en incrementos de 15 minutos, hasta por 7 días. por adelantado, en función de los tiempos de entrega para un restaurante o servicio (como se define en AdvanceServiceDeliveryHoursSpecification)

Para recuperar los horarios propuestos de orden por adelantado, usa los siguientes valores de Campo fulfillmentPreference del objeto FoodCartExtension durante la confirmación de la compra:

  • PickupInfo.pickupTimeIso8601
  • DeliveryInfo.deliveryTimeIso8601

Implementar pedidos anticipados en la confirmación de la compra

En la siguiente tabla, se enumeran las posibles formas de implementar los filtros de tu entrega en el momento de la confirmación de la compra cuando los usuarios intentan realizar pedidos.

Situación Comportamiento de entrega
Se puede completar el pedido anticipado para el horario disponible solicitado. Acepta las P0M ("lo antes posible") o FUTURE_SLOT mediante la creación de un ProposedOrder con el en la misma ranura. Para ver un ejemplo de respuesta de confirmación de la compra que acepta un horario disponible, consulta este fragmento de código.
No se puede completar el pedido anticipado para el horario solicitado. Tu entrega debe hacer lo siguiente:
  1. Rechazar P0M o FUTURE_SLOT solicitados carrito e indicarás el motivo por el que no se pudo completar el pedido en el objeto FoodErrorExtension.
    • Si el pedido no se puede completar debido a la capacidad, especifica un FoodOrderError de tipo de error NO_CAPACITY.
    • Si el pedido no se puede completar porque el restaurante está cerrado, especifica un FoodOrderError de tipo de error CLOSED
    • Si el pedido no se puede completar debido a alguna otra razón, especifica un FoodOrderError de tipo de error UNAVAILABLE_SLOT
  2. Si es posible, proporciona P0M o FUTURE_SLOT valores en correctedProposedOrder. Estos valores deben ser todas las ranuras de entrega válidas para los próximos 7 días a partir de la hora actual. Incluye el espacio P0M. cuando corresponda.

Para ver un ejemplo de una respuesta de confirmación de la compra en la que se proponen horarios disponibles, consulta este fragmento de código.

Ranuras alternativas para la entrega de pedidos

En la confirmación de la compra, si los horarios disponibles para pedido adelantado que propuso Google no son adecuados, tu de entrega puede sugerir alternativas con CheckoutResponseMessage .

Para especificar horarios disponibles de pedido anticipado alternativos, responde la solicitud de confirmación de la compra con un FoodErrorExtension y establece los siguientes valores:

  1. En el parámetro foodOrderErrors, especifica el tipo de error (como UNAVAILABLE_SLOT, NO_CAPACITY o CLOSED).
  2. En el parámetro correctedProposedOrder, proporciona una P0M alternativa o FUTURE_SLOT a través de availableFulfillmentOptions.

Los horarios disponibles alternativos deben ser los siguientes 7 días desde el momento del pedido ubicación e incluya todos los espacios en los que el carrito solicitado por el usuario cumplir con los requisitos.

Por ejemplo, supongamos que las ofertas especiales para el almuerzo solo están disponibles de lunes a viernes. de 11 a.m. a 1 p.m. Luego, intenta agregar especialidades para el almuerzo a su carrito. el horario seleccionado no está disponible. En este caso, tu entrega debe conservar los especiales de almuerzo en el carrito y devolver solo los horarios disponibles de 11 a.m. a 1 p.m. para los próximos 7 días

Debes omitir el objeto correctedProposedOrder.Cart.fulfillmentPreference. en tu respuesta.

Si no hay horarios disponibles o si el restaurante o el servicio no admitir pedidos por adelantado, entonces no es necesario proporcionar correctedProposedOrder

Consulta los siguientes ejemplos para ver los mensajes JSON entre tu entrega y Google. durante la solicitud de pago y el flujo de respuesta de un pedido por adelantado, cuando restaurante o servicio disponible para tomar pedidos por adelantado.

Ejemplo: CheckoutRequest con espacio de entrega

El siguiente fragmento muestra un ejemplo de una solicitud de confirmación de la compra con un pedido por adelantado el espacio 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": {
                ...
              }
            }
          }
        }
      ]
    }
  ]
}

Ejemplo: CheckoutResponse acepta la ranura

El siguiente fragmento muestra un ejemplo de una respuesta de confirmación de la compra en la que tu entrega acepte los horarios disponibles de pedido anticipado.

{
  "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": {
                ...
              }
            }
          }
        }
      ]
    }
  }
}

Ejemplo: CheckoutResponse con ranuras alternativas

El siguiente fragmento muestra un ejemplo de una respuesta de confirmación de la compra en la que tu entrega propone horarios alternativos de pedidos anticipados. Ten en cuenta que Se debe omitir el objeto correctedProposedOrder.Cart.fulfillmentPreference en tu respuesta.

{
  "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 pedidos por adelantado al momento de enviar el pedido

Cuando envías un pedido, si hay un problema con los horarios disponibles anticipados, tu SubmitOrderResponseMessage debe incluir el motivo (como UNAVAILABLE_SLOT o UNKNOWN) en el objeto RejectionInfo.

Actualiza el estado del pedido de CREATED a CONFIRMED en el OrderState cuando el proveedor acepta el pedido. Incluye el el horario seleccionado en el correo electrónico de confirmación que se enviará al usuario.

Si tu entrega envía el pedido al restaurante más tarde, envíale a Google un con la acción de actualización de pedido asíncrona.

En el objeto OrderUpdate de la respuesta de envío de pedido de tu entrega o actualizaciones posteriores de pedidos asíncronas, incluyen un estimatedFulfillmentTimeIso8601 con el valor configurado de la siguiente manera:

  • Cuando el estado del pedido sea CREATED o CONFIRMED, establece el valor en la hora de entrega o retiro que el usuario programó para su pedido anticipado.
  • Cuando el tiempo de entrega estimado del restaurante es más preciso o servicio, establece el valor en la hora estimada de entrega o de retiro.

Ejemplo: SubmitOrderRequest con el espacio de entrega

El siguiente fragmento muestra un ejemplo de una solicitud de envío de pedido que indica la el espacio de pedido anticipado que seleccionó el usuario.

{
  "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": {
                ...
              }
            }
          }
        }
      ]
    }
  ]
}

Ejemplo: SubmitOrderResponse acepta el pedido

El siguiente fragmento muestra un ejemplo de una respuesta a un pedido de envío en la que tu la entrega confirma que aceptó el pedido anticipado del usuario.

{
  "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"
              }
            }
          }
        }
      ]
    }
  }
}

Ejemplo: SubmitOrderResponse rechaza el pedido porque no hay un horario disponible

El siguiente fragmento muestra un ejemplo de una respuesta a un pedido de envío en la que tu la entrega rechaza el pedido anticipado de un usuario porque no hay un horario 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": [
                ...
              ]
            }
          }
        }
      ]
    }
  }
}

Ejemplos de pedidos anticipados

Se puede usar el tipo AdvanceServiceDeliveryHoursSpecification para especificar las horas de entrega o retiro para que los usuarios programen su pedido con anticipación.

Nota: Hay dos períodos diferentes que debes especificar. para la entrega del servicio: la ventana de pedido, que especifica cuándo los usuarios pueden colocar un pedido, y el período de entrega, que especifica cuándo se completará el pedido. El El objeto OpeningHoursSpecification define cuándo el usuario puede realizar el pedido. Sus tiempos de entrega secundarios (ServiceDeliveryHoursSpecification o AdvanceServiceDeliveryHoursSpecification) definen cuándo se puede se cumpla.

El siguiente ejemplo define el horario de atención de un servicio para aceptar pedidos por adelantado, con intervalos de servicio 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"
          }
        }
      ]
    }
  ]
}

El siguiente ejemplo muestra cómo podrías especificar que el servicio está abierto para pedidos el mismo día en Navidad, pero está cerrado para los pedidos anticipados programados para ese día. En este ejemplo, se admiten las siguientes situaciones:

  • Los usuarios pueden hacer un pedido el 25 de diciembre para la entrega en el mismo día.
  • Los usuarios pueden hacer un pedido anticipado el 25 de diciembre para la entrega programada. para el 27 de diciembre.
  • Los usuarios no pueden hacer un pedido anticipado el 22 de diciembre para la entrega programada el 25 de diciembre.
{
  "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"
  }
}

En el siguiente ejemplo, se muestra cómo podrías especificar que el servicio está cerrado por pedidos el mismo día o por adelantado programados para el día de Navidad, pero abiertos para pedidos anticipados programados para un día posterior. En este ejemplo, se admite lo siguiente diferentes:

  • Los usuarios no pueden realizar un pedido el 25 de diciembre para la entrega en el mismo día.
  • Los usuarios pueden hacer un pedido anticipado el 25 de diciembre para la entrega programada. para el 27 de diciembre.
  • Los usuarios no pueden hacer un pedido anticipado el 22 de diciembre para la entrega programada el 25 de diciembre.
{
  "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"
    }
  ]
}

El siguiente servicio de muestra acepta pedidos las 24 horas del día, los 7 días de la semana, y realiza entregas desde De 10 a.m. a 2:59:59 p.m. los días de semana:

...
{
  "@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"
    }
  }
}
...

El siguiente servicio de muestra acepta pedidos todos los días de 8:00 a.m. a 4:59:59 p.m. y los clientes pueden optar por una entrega dentro de una hora o elegir una de las ranuras:

...
{
  "@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"
      }
    }
  ]
}
...

En el siguiente ejemplo, se muestra un caso en el que la tienda abre de 8 a.m. a 4:59:59 p.m. el entre semana, pero de 8:00 a.m. a 6:59 p.m. los fines de semana. No se aceptan pedidos las 24 horas, todos los días.

...
{
  // 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"
      }
    }
  ]
}
...