Después de la llamada de confirmación de la compra, el usuario revisa el carrito actualizado con los impuestos, las tarifas de entrega, los descuentos y otros cargos que devuelves. El usuario confirma y envía el pedido, y Google envía a tu extremo de entrega una solicitud JSON que contiene la información del pedido. Tu servicio web debe recibir este pedido, procesarlo y responder a Google con el estado del pedido.
En esta sección, se describe el formato del mensaje de solicitud de pedido que envía Google,
llamado SubmitOrderRequestMessage
, y el formato del mensaje de respuesta
que debes proporcionar, llamado
SubmitOrderResponseMessage
.
Para obtener más información sobre el ciclo de vida de la entrega de pedidos, consulta la descripción general de la entrega.
Implementación de la preparación de pedidos
El servicio web de pedidos de extremo a extremo que compilas para trabajar con este servicio debe incluir un extremo de URL para recibir mensajes de pedidos de Google. Para el procesamiento de pedidos, tu servicio web recibe un SubmitOrderRequestMessage
en formato JSON como una solicitud POST de Google. Esta solicitud contiene un pedido de un cliente, incluidos los impuestos, las tarifas y la información de pago. Cuando recibas una solicitud para enviar un pedido, tu servicio web debe hacer lo siguiente:
- Verifica la elegibilidad de la transacción, como la verificación de la tarjeta o la detección de fraudes.
- Crea un pedido en tu sistema.
- Autoriza la forma de pago y llama a la API de cargos de tu procesador de pagos cuando corresponda.
- Responde con el estado correcto del pedido:
CREATED
,CONFIRMED
oREJECTED
.
Después de procesar el pedido, tu código de entrega debe proporcionar una respuesta a Google en forma de un mensaje JSON SubmitOrderResponseMessage
.
Para obtener más información sobre los requisitos de implementación del servicio web de entrega de extremo a extremo de pedidos, consulta la descripción general de la entrega.
Mensaje de solicitud de pedido
Cuando un cliente elige realizar un pedido durante el flujo de pedidos de extremo a extremo, Google envía una solicitud a tu servicio web con un mensaje JSON llamado SubmitOrderRequestMessage
que contiene los siguientes datos:
- Intent: El campo
inputs[0].intent
de cada cuerpo de solicitud de envío de pedido contiene el valor de cadenaactions.intent.TRANSACTION_DECISION
. - Pedido: El campo
inputs[0].arguments[0].transactionDecisionValue
de una solicitud para enviar un pedido contiene un objetoOrder
que representa el pedido que realizará el cliente, junto con los detalles del pago. - Marca de zona de pruebas: El campo
isInSandbox
de una solicitud de envío de pedido indica si la transacción usa pagos de zona de pruebas.
Ejemplo de solicitud de pedido
A continuación, se muestra un ejemplo de SubmitOrderRequestMessage
:
JSON
{ "user": {}, "conversation": { "conversationId": "CTKbKfUlHCyDEdcz_5PBJTtf" }, "inputs": [ { "intent": "actions.intent.TRANSACTION_DECISION", "arguments": [ { "transactionDecisionValue": { "order": { "finalOrder": { "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" ] } }, "contact": { "displayName": "Hab Sy", "email": "hab9878.sy@gmail.com", "phoneNumber": "+61000000000", "firstName": "Hab", "lastName": "Sy" } } }, "otherItems": [ { "name": "Delivery fee", "type": "DELIVERY", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "AUD", "units": "3", "nanos": 500000000 } } }, { "name": "Subtotal", "type": "SUBTOTAL", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "AUD", "units": "39", "nanos": 600000000 } } } ], "totalPrice": { "type": "ESTIMATE", "amount": { "currencyCode": "AUD", "units": "43", "nanos": 100000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension" } }, "googleOrderId": "01412971004192156198", "orderDate": "2020-10-22T09:02:06.173Z", "paymentInfo": { "displayName": "Pay when you get your food", "paymentType": "ON_FULFILLMENT" } } } } ] } ], "directActionOnly": true, "isInSandbox": true }
Mensaje de respuesta del pedido
Después de recibir una solicitud, tu servicio web de extremo a extremo de pedidos la
procesa y devuelve un SubmitOrderResponseMessage
que incluye los
siguientes datos:
OrderUpdate
: Es un objeto que contiene el estado del pedido y cualquier acción posterior al pedido disponible para el usuario, como comunicarse con el equipo de asistencia y ver los detalles del pedido, que defines en el campofinalResponse.richResponse.items[0].structuredResponse.orderUpdate
de la respuesta.
Campo de actualización de pedidos
Cuando tu servicio web envía un SubmitOrderResponseMessage
, contiene un campo OrderUpdate
que incluye los siguientes campos:
actionOrderId
: Es el ID único del pedido, que se usa para identificarlo de forma inequívoca en tu sistema y consultarlo cuando envíes actualizaciones posteriores del pedido.orderState
: Es un objetoOrderState
que representa el estado del pedido.orderManagementActions
: Son las acciones posteriores al pedido disponibles para el usuario, como comunicarse con el equipo de asistencia al cliente y ver los detalles del pedido.totalPrice
: Es el precio total del pedido. Esto es opcional. Envíalo solo si el precio total del pedido cambió después de que se envió.
Un pedido puede estar en uno de los siguientes estados:
CREATED
: Tu extremo de entrega procesó el pedido correctamente, pero el proveedor aún no lo confirmó.CONFIRMED
: Tu extremo de entrega procesó el pedido correctamente y el proveedor lo confirmó.REJECTED
: Hubo un problema y tu extremo de entrega no pudo crear ni confirmar el pedido, lo que puede incluir problemas con el pago.
Si estableces un pedido en un estado REJECTED
, especifica el motivo en el campo rejectionInfo
de OrderUpdate
. Usa valores FoodOrderUpdateExtension.FoodOrderErrors
junto con rejectionInfo
de tipo UNKNOWN
y proporciona una descripción.
Ejemplo de respuesta de pedido
A continuación, se muestra un ejemplo de SubmitOrderResponseMessage
:
JSON
{ "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "orderUpdate": { "actionOrderId": "1603357328160", "orderState": { "state": "CONFIRMED", "label": "Pending" }, "updateTime": "2020-10-22T02:02:08-07:00", "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Call customer service", "openUrlAction": { "url": "tel:+61234561000" } } }, { "type": "VIEW_DETAILS", "button": { "title": "View order details", "openUrlAction": { "url": "https://partner.com/view/orderstatus" } } } ], "receipt": { "userVisibleOrderId": "BXZ-1603357328" } } } } ] } } }
Solicitud no exitosa
Si una solicitud de envío no se realiza correctamente, SubmitOrderResponseMessage
debe establecer OrderState.state
en REJECTED
. La respuesta también debe incluir RejectionInfo, que contiene un objeto RejectionType
para describir el tipo de error.
Ejemplo de una respuesta incorrecta
JSON
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "REJECTED", "label": "Order rejected" }, "updateTime": "2017-05-10T02:30:00.000Z", "rejectionInfo": { "type": "PAYMENT_DECLINED", "reason": "Insufficient funds" }, "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:person@example.com" } } }, { "type": "CALL", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+16505554679" } } }, { "type": "VIEW_DETAILS", "button": { "title": "View order", "openUrlAction": { "url": "https://orderview.partner.com?orderid=sample_action_order_id" } } } ] } } } ] } } }
Envía la implementación del pedido
Cuando implementes la API de SubmitOrder, debes seguir los siguientes pasos.
Validación
- Realiza las validaciones del servicio, el carrito y la promoción como se hace en Configurar la confirmación de la compra.
- Devuelve RejectionInfo con uno de los siguientes tipos si es necesario:
RejectionInfoType | Caso de uso |
---|---|
UNAVAILABLE_SLOT |
El tiempo de entrega ya no es válido. |
PROMO_USER_INELIGIBLE |
Usa el correo electrónico en el objeto Contact de la solicitud para validar la elegibilidad del usuario para la promoción. Consulta el ejemplo en Cómo implementar el envío de pedidos con promociones. |
INELIGIBLE |
|
PAYMENT_DECLINED |
No se puede procesar el pago. Por ejemplo, esto puede deberse a que no hay fondos suficientes. |
UNKNOWN |
Para cualquier otro error de validación. |
Establece OrderState.state
en REJECTED
si se producen errores de validación. De manera opcional, puedes proporcionar un motivo de rechazo específico con FoodOrderUpdateExtension.foodOrderErrors
. Consulta ejemplos en Enviar validación de pedidos.
Procesa el pago
- Para calcular
totalPrice
, agrega el precio del carrito, las tarifas, el descuento, los impuestos y la propina. EltotalPrice
debe ser el mismo que eltotalPrice
que se muestra en CheckoutResponseMessage más el cambio en el importe de la propina si el usuario puede modificarla. Consulta Cambios de precio durante el envío del pedido para obtener más detalles. - Procesa el pedido y el pago si devuelves una respuesta con un estado de pedido de
CREATED
oCONFIRMED
. - Asegúrate de que se muestre un formato de respuesta válido con los tipos generados que se crearon a partir del esquema, como se describe en Cómo generar bibliotecas cliente.
- Usa GoogleProvidedPaymentInstrument.
instrumentToken
para procesar el pago. Muestra RejectionInfo con el tipoPAYMENT_DECLINED
si no se puede procesar el pago. Consulta Cómo procesar pagos para obtener más detalles. - Notifica al usuario inmediatamente después de que se procese el pedido por correo electrónico o SMS.
Devuelve la respuesta
- Establece OrderState.
state
enCREATED
oCONFIRMED
si no hay errores. - Establece OrderState.
state
enREJECTED
si se producen errores y, luego, incluye el objeto RejectionInfo con el RejectionInfoType correspondiente. - Establece OrderUpdate.
orderManagementActions
.