Após a chamada de finalização de compra, o usuário analisa o carrinho atualizado com impostos, taxas de entrega, descontos e outras cobranças que você retornar. O usuário confirma e envia o pedido, e o Google envia ao endpoint de fulfillment uma solicitação JSON que contém as informações do pedido. Seu serviço da Web precisa receber o pedido, processá-lo e responder ao Google com o estado do pedido.
Esta seção descreve o formato da mensagem de solicitação de pedido enviada pelo Google,
chamado de SubmitOrderRequestMessage
, e o formato da mensagem de resposta
que você precisa fornecer, chamada de
SubmitOrderResponseMessage
.
Para mais informações sobre o ciclo de vida do fulfillment de pedidos, consulte a
Visão geral do fulfillment.
Implementação do atendimento de pedidos
O serviço da Web de finalização de pedidos que você cria para trabalhar com a finalização de pedidos de ponta a ponta precisa
incluir um endpoint de URL para receber mensagens de pedidos do Google. Para o processamento
de pedidos, seu serviço da Web recebe um SubmitOrderRequestMessage
no formato JSON
como uma solicitação POST do Google. Essa solicitação contém um pedido do cliente,
incluindo tributos, taxas e informações de pagamento. Ao receber um pedido de envio de ordem, seu serviço da Web precisa fazer o seguinte:
- Verificar a qualificação da transação, como verificação do cartão ou detecção de fraude.
- Crie um pedido no seu sistema.
- Autorize a forma de pagamento e chame a API de cobrança do processador de pagamentos, quando aplicável.
- Responda com o estado adequado do pedido:
CREATED
,CONFIRMED
ouREJECTED
.
Após o processamento do pedido, o código de fulfillment precisa fornecer uma resposta
na forma de uma mensagem JSON SubmitOrderResponseMessage
ao Google.
Para mais informações sobre os requisitos de implementação do serviço da Web de fulfillment de ponta a ponta de pedidos, consulte a Visão geral do fulfillment.
Mensagem de solicitação de pedido
Quando um cliente escolhe fazer um pedido durante o fluxo de finalização de compra,
o Google envia uma solicitação para seu serviço da Web com uma mensagem JSON chamada
SubmitOrderRequestMessage
, que contém os seguintes dados:
- Intent:o campo
inputs[0].intent
de cada corpo de solicitação de envio de pedidos contém o valor da stringactions.intent.TRANSACTION_DECISION
. - Pedido:o campo
inputs[0].arguments[0].transactionDecisionValue
de uma solicitação de envio de pedido contém um objetoOrder
que representa o pedido do cliente a ser feito, além dos detalhes de pagamento. - Flag de sandbox:o campo
isInSandbox
de um pedido de envio de pedido indica se a transação usa pagamentos de sandbox.
Exemplo de solicitação de pedido
Veja abaixo um exemplo de SubmitOrderRequestMessage
:
{ "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 }
Mensagem de resposta do pedido
Depois de receber uma solicitação, o serviço da Web de ponta a ponta de pedidos processa a
solicitação e envia de volta uma SubmitOrderResponseMessage
que inclui os
seguintes dados:
OrderUpdate
: um objeto que contém o estado do pedido e todas as ações pós-pedido disponíveis para o usuário, como entrar em contato com o suporte e visualizar os detalhes do pedido, que você define no campofinalResponse.richResponse.items[0].structuredResponse.orderUpdate
da resposta.
Campo de atualização do pedido
Quando o serviço da Web envia um SubmitOrderResponseMessage
, ele contém um campo OrderUpdate
que inclui os seguintes campos:
actionOrderId
: o ID exclusivo do pedido, que é usado para identificar exclusivamente o pedido no sistema e se referir a ele ao enviar atualizações posteriores do pedido.orderState
: um objetoOrderState
que representa o estado do pedido.orderManagementActions
: ações pós-pedido disponíveis para o usuário, como entrar em contato com o suporte ao cliente e conferir os detalhes do pedido.totalPrice
: o preço total do pedido. Isso é opcional. Envie apenas se o preço total do pedido tiver mudado após o envio.
Um pedido pode estar em um dos seguintes estados:
CREATED
: seu endpoint de fulfillment processou o pedido, mas o provedor ainda não confirmou o pedido.CONFIRMED
: seu endpoint de atendimento processou o pedido, e o provedor confirmou o pedido.REJECTED
: ocorreu um problema e o endpoint de fulfillment não conseguiu criar ou confirmar o pedido, o que pode incluir problemas de pagamento.
Se você definir um pedido para um estado REJECTED
, especifique o motivo no
campo rejectionInfo
de OrderUpdate
. Use
valores FoodOrderUpdateExtension.FoodOrderErrors
com
rejectionInfo
do tipo UNKNOWN
e forneça uma descrição.
Exemplo de resposta de pedido
Veja abaixo um exemplo de SubmitOrderResponseMessage
:
{ "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" } } } } ] } } }
Pedido não realizado
Se uma solicitação de envio falhar, o SubmitOrderResponseMessage
precisa definir
o OrderState.state
como REJECTED
. A resposta também precisa
incluir o RejectionInfo, que contém um objeto RejectionType
para descrever o tipo de erro.
Exemplo de resposta com falha
{ "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" } } } ] } } } ] } } }
Implementação do envio de pedidos
Siga as etapas abaixo ao implementar a API de envio de pedidos.
Validação
- Realize as validações de serviço, carrinho e promoção como em Configurar o final de compra.
- Retorne RejectionInfo com um dos seguintes tipos, se necessário:
RejectionInfoType | Caso de uso |
---|---|
UNAVAILABLE_SLOT |
O tempo de entrega não é mais válido. |
PROMO_USER_INELIGIBLE |
Use o e-mail no objeto Contact na solicitação para validar a qualificação do usuário para a promoção. Consulte o exemplo em implementar o envio de pedidos com promoções. |
INELIGIBLE |
|
PAYMENT_DECLINED |
Não foi possível processar o pagamento. Por exemplo, isso pode ser devido a saldo insuficiente. |
UNKNOWN |
Para qualquer outro erro de validação. |
Defina OrderState.state
como REJECTED
se houver erros de validação. Como alternativa, é possível fornecer um motivo específico de rejeição
usando a FoodOrderUpdateExtension.foodOrderErrors
. Confira exemplos em
Enviar validação de pedido.
Processar o pagamento
- Calcule o
totalPrice
adicionando o preço do carrinho, as taxas, o desconto, os tributos e a gorjeta. OtotalPrice
precisa ser igual aototalPrice
retornado na CheckoutResponseMessage, mais a alteração no valor da gorjeta, se ela puder ser modificada pelo usuário. Consulte Mudanças de preço durante o envio de pedidos para mais detalhes. - Processe o pedido e o pagamento se você retornar uma resposta com um estado de pedido
de
CREATED
ouCONFIRMED
. - Para garantir que um formato de resposta válido seja retornado, use tipos gerados criados a partir do esquema, conforme descrito em gerar bibliotecas de cliente.
- Use o
GoogleProvidedPaymentInstrument.
instrumentToken
para processar o pagamento. Retorne RejectionInfo com o tipoPAYMENT_DECLINED
se o pagamento não puder ser processado. Consulte Processar pagamentos para mais detalhes. - Notifique o usuário imediatamente após o processamento do pedido por e-mail ou SMS.
Retornar a resposta
- Defina OrderState.
state
comoCREATED
ouCONFIRMED
se não houver erros. - Defina OrderState.
state
comoREJECTED
se houver erros e inclua o objeto RejectionInfo com o RejectionInfoType correspondente. - Defina a OrderUpdate.
orderManagementActions
.