Configurar la confirmación de la compra

El proceso de confirmación de la compra se invoca cuando un usuario crea un carrito. El contenido de las El carrito del usuario y los detalles del pedido se envían a tu página web de Pedidos de extremo a extremo. servicio. Tu servicio web valida esta información y, luego, continuar o hacer ajustes en el carrito según sea necesario.

El controlador de confirmación de la compra de tu servicio web debe responder a las solicitudes POST. Cuando un elemento el cliente decide finalizar la compra, Google envía al servicio web de pedidos de extremo a extremo Cuerpo de la solicitud JSON en forma de CheckoutRequestMessage, que contiene lo siguiente: detalles del Cart de un cliente. Luego, tu servicio web responde con un CheckoutResponseMessage En el siguiente diagrama, se ilustra el proceso.

CheckoutResponseMessage devuelve el carrito sin modificar del cliente o un
.

Luego de recibir una solicitud de confirmación de la compra, tu servicio web de pedidos de extremo a extremo debe lo siguiente:

  • Verificar la validez del carrito según los precios actuales de los artículos, la disponibilidad y el proveedor del servicio.
  • Calcula el precio total (incluidos los descuentos, los impuestos y el costo de envío) tarifas).
  • Si tienes éxito, responde con un carrito sin modificar.
  • Si no funciona, responde con un mensaje de error y un nuevo pedido propuesto.

Antes de comenzar a implementar la confirmación de la compra, te recomendamos revisar la página de descripción general en la documentación de Google Cloud.

Mensaje de solicitud de confirmación de la compra

Para validar el carrito, cuando un cliente elige pagar, Google envía una solicitud a tu servicio web con un cuerpo JSON en forma de CheckoutRequestMessage El pedido del cliente no se envía hasta más adelante en el Flujo de pedidos de extremo a extremo.

Los datos contenidos en un CheckoutRequestMessage incluye lo siguiente:

  • La intención inputs[0].intent de cada cuerpo de la solicitud de confirmación de la compra contiene el Es el valor de cadena actions.foodordering.intent.CHECKOUT.
  • Carrito: El campo inputs[0].arguments[0].extension de una solicitud de confirmación de la compra contiene un objeto Cart que representa el carrito del cliente.
  • Entrega o exportación: El campo de la extensión del objeto Cart contiene un Un objeto FoodCartExtension que especifica propiedades para entrega o comida para llevar:
    • Para los pedidos con entrega a domicilio, el objeto FoodCartExtension incluye la dirección de entrega de Google.
    • En el caso de los pedidos para retirar o para llevar, el objeto FoodCartExtension no contienen información de ubicación.
  • Zona de pruebas: El campo isInSandbox de una solicitud de confirmación de la compra contiene un valor booleano. valor que indica si la transacción usa pagos de zona de pruebas.

Ejemplo de solicitud de confirmación de la compra

A continuación, se muestra un ejemplo de un CheckoutRequestMessage:

{
    "user": {},
    "conversation": {
        "conversationId": "CTZbZfUlHCybEdcz_5PB3Ttf"
    },
    "inputs": [
        {
            "intent": "actions.foodordering.intent.CHECKOUT",
            "arguments": [
                {
                    "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.Cart",
                        "merchant": {
                            "id": "restaurant/Restaurant/QWERTY",
                            "name": "Tep Tep Chicken Club"
                        },
                        "lineItems": [
                            {
                                "name": "Spicy Fried Chicken",
                                "type": "REGULAR",
                                "id": "299977679",
                                "quantity": 2,
                                "price": {
                                    "type": "ESTIMATE",
                                    "amount": {
                                        "currencyCode": "AUD",
                                        "units": "39",
                                        "nanos": 600000000
                                    }
                                },
                                "offerId": "MenuItemOffer/QWERTY/scheduleId/496/itemId/143",
                                "extension": {
                                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                                }
                            }
                        ],
                        "extension": {
                            "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
                            "fulfillmentPreference": {
                                "fulfillmentInfo": {
                                    "delivery": {
                                        "deliveryTimeIso8601": "P0M"
                                    }
                                }
                            },
                            "location": {
                                "coordinates": {
                                    "latitude": -33.8376441,
                                    "longitude": 151.0868736
                                },
                                "formattedAddress": "Killoola St, 1, Concord West NSW 2138",
                                "zipCode": "2138",
                                "city": "Concord West",
                                "postalAddress": {
                                    "regionCode": "AU",
                                    "postalCode": "2138",
                                    "administrativeArea": "NSW",
                                    "locality": "Concord West",
                                    "addressLines": [
                                        "Killoola St",
                                        "1"
                                    ]
                                }
                            }
                        }
                    }
                }
            ]
        }
    ],
    "directActionOnly": true,
    "isInSandbox": true
}

Mensaje de respuesta de confirmación de la compra

Después de recibir una solicitud del servicio de pedidos de extremo a extremo, el sitio web de confirmación de compra servicio debe procesarla y responder con un CheckoutResponseMessage. El CheckoutResponseMessage debe abordar una solicitud para cada solicitud.

Solicitud correcta

Si la solicitud de pago se realiza correctamente, CheckoutResponseMessage debe incluir lo siguiente: ProposedOrder y PaymentOptions

  • ProposedOrder

    • cart: Es un objeto cart idéntico al carrito proporcionado en el CheckoutRequestMessage Si el contenido del carrito se debe cambió, CheckoutResponseMessage debe incluir un FoodErrorExtension con un ProposedOrder corregido.
    • otherItems: Los artículos que agregó el proveedor, como los cargos de envío impuestos y otras tarifas. También puede contener propinas agregadas por el usuario.
    • totalPrice: Es el precio total del pedido.
    • extension: Es un FoodOrderExtension que define la información de entrega. del pedido, como el tiempo de entrega.
  • PaymentOptions

    • La configuración del procesamiento de pagos se explica más adelante en Cómo configurar Google Pagar Puedes usar el marcador de posición JSON en tu CheckoutResponseMessage hasta que cumplas con las siguientes condiciones: lista para implementar el procesamiento de pagos.
    • Si quieres agregar marcadores de posición de pago a tu CheckoutResponseMessage, sigue estos pasos: consulta el ejemplo a continuación, que usa un ejemplo de puerta de enlace de pagos para PaymentOptions.

Ejemplo de respuesta correcta

{
    "finalResponse": {
        "richResponse": {
            "items": [
                {
                    "structuredResponse": {
                        "checkoutResponse": {
                            "proposedOrder": {
                                "cart": {
                                    "merchant": {
                                        "id": "restaurant/Restaurant/QWERTY",
                                        "name": "Tep Tep Chicken Club"
                                    },
                                    "lineItems": [
                                        {
                                            "name": "Spicy Fried Chicken",
                                            "type": "REGULAR",
                                            "id": "299977679",
                                            "quantity": 2,
                                            "price": {
                                                "type": "ESTIMATE",
                                                "amount": {
                                                    "currencyCode": "AUD",
                                                    "units": "39",
                                                    "nanos": 600000000
                                                }
                                            },
                                            "offerId": "MenuItemOffer/QWERTY/scheduleId/496/itemId/143",
                                            "extension": {
                                                "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                                            }
                                        }
                                    ],
                                    "extension": {
                                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
                                        "fulfillmentPreference": {
                                            "fulfillmentInfo": {
                                                "delivery": {
                                                    "deliveryTimeIso8601": "P0M"
                                                }
                                            }
                                        },
                                        "location": {
                                            "coordinates": {
                                                "latitude": -33.8376441,
                                                "longitude": 151.0868736
                                            },
                                            "formattedAddress": "Killoola St, 1, Concord West NSW 2138",
                                            "zipCode": "2138",
                                            "city": "Concord West",
                                            "postalAddress": {
                                                "regionCode": "AU",
                                                "postalCode": "2138",
                                                "administrativeArea": "NSW",
                                                "locality": "Concord West",
                                                "addressLines": [
                                                    "Killoola St",
                                                    "1"
                                                ]
                                            }
                                        }
                                    }
                                },
                                "totalPrice": {
                                    "type": "ESTIMATE",
                                    "amount": {
                                        "currencyCode": "AUD",
                                        "units": "43",
                                        "nanos": 100000000
                                    }
                                },
                                "extension": {
                                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension",
                                    "availableFulfillmentOptions": [
                                        {
                                            "fulfillmentInfo": {
                                                "delivery": {
                                                    "deliveryTimeIso8601": "P0M"
                                                }
                                            }
                                        }
                                    ]
                                },
                                "otherItems": [
                                    {
                                        "name": "Delivery fee",
                                        "price": {
                                            "type": "ESTIMATE",
                                            "amount": {
                                                "currencyCode": "AUD",
                                                "units": "3",
                                                "nanos": 500000000
                                            }
                                        },
                                        "type": "DELIVERY"
                                    }
                                ]
                            },
                            "paymentOptions": {
                                "googleProvidedOptions": {
                                    "facilitationSpecification": "{\"apiVersion\":2,\"apiVersionMinor\":0,\"merchantInfo\":{\"merchantName\":\"merchantName\"},\"allowedPaymentMethods\":[{\"type\":\"CARD\",\"parameters\":{\"allowedAuthMethods\":[\"PAN_ONLY\"],\"allowedCardNetworks\":[\"VISA\",\"MASTERCARD\"],\"billingAddressRequired\":true,\"cvcRequired\":false},\"tokenizationSpecification\":{\"type\":\"PAYMENT_GATEWAY\",\"parameters\":{\"gatewayMerchantId\":\"YOUR_MERCHANT_ID\",\"gateway\":\"cybersource\"}}}],\"transactionInfo\":{\"currencyCode\":\"AUD\",\"totalPriceStatus\":\"ESTIMATED\",\"totalPrice\":\"43.1\"}} "
                                }
                            },
                            "additionalPaymentOptions": [
                                {
                                    "actionProvidedOptions": {
                                        "paymentType": "ON_FULFILLMENT",
                                        "displayName": "Pay when you get your food.",
                                        "onFulfillmentPaymentData": {
                                            "supportedPaymentOptions": []
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }
}

No se pudo completar la solicitud

Si una solicitud de confirmación de la compra no se realiza correctamente, CheckoutResponseMessage debe hacer lo siguiente: incluir FoodErrorExtension, que contiene una lista de FoodOrderError elementos que describen cualquier error que se haya producido. Si hay problemas de recuperación errores del pedido, como un cambio de precio de un artículo en el carrito, el FoodErrorExtension debe incluir el correctedProposedOrder.

Ejemplo de respuesta no exitosa

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "error": {
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
              "foodOrderErrors": [
                {
                  "error": "CLOSED",
                  "description": "The restaurant is closed."
                }
              ]
            }
          }
        }
      ]
    }
  }
}

Implementación de confirmación de la compra

Se deben seguir estos pasos cuando se implementa la confirmación de la compra.

Valida el servicio

Muestra un FoodOrderError para la primera condición de error de servicio encontradas. Estos errores no se pueden recuperar, por lo que el primer error encontrado debe ser el siguiente: que se devuelven. Consulta Manejo de errores para obtener una descripción de errores recuperables.

  1. Lee la propiedad FulfillmentOptionInfo en la para determinar si el tipo de entrega es para delivery o pickup.
  2. Muestra los siguientes tipos de error si es necesario:

    Tipo de error Caso de uso
    NO VÁLIDO El tipo de entrega no es válido.
    No se ha encontrado. No se encontró el tipo de entrega.
    CERRADA
    • No hay ventanas OperationHours para el pedido.
    • El pedido se realiza cuanto antes y no hay ServiceHours de lo antes posible disponibles para la hora actual.
    • Hay un cierre de emergencia o el servicio isDisabled es verdadero.
    Ten en cuenta que las ventanas especiales tienen prioridad sobre las ventanas normales. Consulta ejemplos en validación de períodos de pedidos y quita entidades de servicio temporalmente.
    UNAVAILABLE_SLOT No se puede completar el tiempo de anticipación del pedido.
    NO_CAPACITY El restaurante está concurrido y no toma pedidos en este momento.
    OUT_OF_SERVICE_AREA El pedido no se puede entregar a la dirección del usuario. Consulta Validación de la dirección de entrega para ver un ejemplo.
    NO_COURIER_AVAILABLE No se puede entregar el pedido porque el personal de entrega es limitado.

Valida y establece el precio del carrito

  1. Busca cada Carrito.lineItems y valida con los datos actuales en en tu sistema o en el del comercio. El MenuItemOffer. Se incluye sku de la entidad del feed. como el LineItem.offerId Crea un FoodOrderError para cada línea de pedido si es necesario. Crea un y, como máximo, un error por cada elemento. Devuelve los siguientes tipos de error si según sea necesario:

    Tipo de error Caso de uso Recuperable
    NO VÁLIDO Los datos del artículo o cualquiera de las opciones no son válidos. No
    No se ha encontrado. No se encontró el elemento ni ninguna de las opciones. No
    PRICE_CHANGED Cambió el precio de un elemento o una combinación de complemento. Este error se puede tratar como recuperable.
    AVAILABILITY_CHANGED El importe solicitado para las líneas de pedido o cualquiera de las opciones no está disponible.
    REQUIREMENTS_NOT_MET No se cumple el mínimo o el máximo del pedido. Esto se puede determinar revisando si el precio del carrito es inferior a la Tarifa.eligibleTransactionVolumeMin o superior a la Tarifa.eligibleTransactionVolumeMax. Consulta el ejemplo de validación del valor mínimo de pedido. No
  2. Muestra la lista validada de elementos de una sola línea con LineItemType REGULAR La suma de todos los precios de las líneas de pedido del carrito es el precio del carrito o SUBTOTAL

Consulta los ejemplos en la validación de artículos del carrito.

Calcula los cargos del servicio

  1. Encuentra la entidad Fee correcta para el servicio según el eligibleRegion, validFrom, validThrough y priority.
  2. Calcula el importe de la tarifa en función de si la entidad se definió con un price. propiedad percentageOfCart o pricePerMeter.
  3. Devolver los cargos del servicio de entrega o comida para llevar como una LineItem con LineItemType, DELIVERY o FEE, respectivamente. Agregar la tarifa a la lista Carrito.otherItems.

Aplica promociones

  1. Busca la entidad Deal según la coincidencia con el Valor Promoción.coupon con el acuerdodealCode.
  2. Valida el acuerdo y muestra un FoodOrderError si es necesario. Estos errores se pueden tratar como recuperables. Muestra los siguientes tipos de error si es necesario:

    Tipo de error Caso de uso
    PROMO_NOT_RECOGNIZED No se reconoció el código del cupón.
    PROMO_EXPIRED Venció la validez del acuerdo.
    PROMO_ORDER_INELIGIBLE El pedido no es apto para el cupón.
    PROMO_NOT_APPLICABLE Cualquier otro motivo.
  3. Calcula el importe del precio del acuerdo en función de Deal.discount o Acuerdo.discountPercentage

  4. Aplica el importe del precio del acuerdo usando el total del carrito o el total de la tarifa según el Acuerdo:dealType.

  5. Devuelve el carrito.promotions con la promoción aplicada.

  6. Devuelve la promoción como una LineItem con LineItemType DISCOUNT. Agrega el descuento al Carrito: Es una lista de otherItems con un precio negativo.

Devuelve la respuesta

  1. Crea el objeto ProposedOrder.cart, el carrito de respuestas es el del mismo modo que el carrito de la solicitud si no se encuentran errores durante la validación.
  2. Muestra la lista ProposedOrder.otherItems, incluida la impuestos, tarifas, propinas y descuentos si se aplican. Consulta la Propina para obtener más detalles sobre cómo configurar el elemento de propina.
  3. Incluye el ProposedOrder.totalPrice agregando el carrito precio, tarifas, descuentos, impuestos y propinas.
  4. Devuelve el FoodOrderExtension.availableFulfillmentOptions con la FulfillmentOption respectiva. Actualiza el valor estimado de retiro o entrega a la hora esperada.
  5. Si hay FoodOrderErrors generados a partir de las verificaciones de validación anteriores, haz lo siguiente:
    • Incluye StructuredResponse.error y la lista de en FoodErrorExtension.foodOrderErrors.
    • Devuelve el objeto ProposedOrder como correctedProposedOrder si se pueden recuperar todos los errores.
    • Devuelve PaymentOptions en paymentOptions. si todos los errores se pueden recuperar.
    • De manera opcional, incluye el additionalPaymentOptions si hay otros las opciones de pago disponibles y todos los errores se pueden corregir.
  6. Si no hay errores de validación, muestra proposedOrder, paymentOptions en el objeto CheckoutResponse. De manera opcional, incluye el additionalPaymentOptions si hay otros las opciones de pago disponibles.