O processo de finalização de compra é invocado quando um usuário cria um carrinho. O conteúdo do carrinho do usuário e detalhes sobre o pedido são enviados para a página do seu pedido na Web serviço. Essas informações são validadas pelo seu serviço da Web e você pode prossiga ou faça ajustes no carrinho conforme necessário.
O gerenciador de finalização de compra do seu serviço da Web precisa responder a solicitações POST. Quando um
o cliente decide finalizar a compra, o Google envia o serviço da Web de pedido de ponta a ponta uma
Corpo da solicitação JSON na forma de um CheckoutRequestMessage
, que contém o
detalhes do Cart
de um cliente. Seu serviço da Web responde com uma
CheckoutResponseMessage
: No diagrama a seguir, ilustramos o processo.
Ao receber uma solicitação de finalização de compra, o serviço da Web de pedido de ponta a ponta precisa fazer o seguinte: o seguinte:
- Verifique a validade do carrinho com base nos preços, disponibilidade dos itens atuais do Google Cloud.
- Calcule o preço total (incluindo descontos, tributos e entrega) tarifas).
- Se der certo, responda com um carrinho sem modificações.
- Se não tiver êxito, responda com uma mensagem de erro e um novo pedido proposto.
Antes de começar a implementar a finalização da compra, recomendamos que você consulte a seção Fulfillment visão geral na documentação do Google Cloud.
Mensagem de solicitação de finalização da compra
Para validar o carrinho do cliente, quando ele decide finalizar a compra,
O Google envia uma solicitação ao seu serviço da Web com um corpo JSON na forma de um
CheckoutRequestMessage
: O pedido do cliente não é enviado até mais tarde no
Fluxo de pedidos de ponta a ponta.
Os dados contidos em um
CheckoutRequestMessage
inclui o seguinte:
- Intenção: a
inputs[0].intent
do corpo de cada solicitação de checkout contém o Valor da stringactions.foodordering.intent.CHECKOUT
. - Carrinho: o campo
inputs[0].arguments[0].extension
de uma solicitação de finalização de compra contém um objetoCart
que representa o carrinho do cliente. - Entrega ou retirada: o campo de extensão do objeto
Cart
contém uma ObjetoFoodCartExtension
que especifica propriedades para entrega ou retirada de dados:- Para pedidos de entrega, o objeto
FoodCartExtension
inclui o endereço de entrega. - Para pedidos para retirada ou retirada, o objeto
FoodCartExtension
não todas as informações de localização.
- Para pedidos de entrega, o objeto
- Sandbox: o campo
isInSandbox
de uma solicitação de finalização de compra contém um booleano O valor que indica se a transação usa pagamentos de sandbox.
Exemplo de solicitação de finalização de compra
Confira abaixo um exemplo de 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
}
Mensagem de resposta à finalização da compra
Depois de receber uma solicitação do serviço de pedidos de ponta a ponta, a página de finalização da compra na Web
serviço precisa processá-la e responder com um CheckoutResponseMessage
. A
CheckoutResponseMessage
precisa abranger um problema de sucesso ou
solicitação.
Solicitação bem-sucedida
Se uma solicitação de finalização de compra for bem-sucedida, CheckoutResponseMessage
precisará incluir
ProposedOrder
e
PaymentOptions
:
ProposedOrder
cart
: um objetocart
idêntico ao carrinho fornecido naCheckoutRequestMessage
. Se algum conteúdo do carrinho precisar ser mudou, aCheckoutResponseMessage
precisa incluir umaFoodErrorExtension
com umProposedOrder
corrigido.otherItems
: itens adicionados pelo fornecedor, como taxas de entrega. tributos e outras taxas. Também pode conter gratificações adicionadas pelo usuário.totalPrice
: o preço total do pedido.extension
: umaFoodOrderExtension
que define as informações de fulfillment do pedido, como o tempo de entrega.
PaymentOptions
- A configuração do processamento de pagamentos é abordada mais adiante em Configurar o Google
Pay.
Você pode usar o JSON de marcador de posição no
CheckoutResponseMessage
até pronto para implementar o processamento de pagamentos. - Para adicionar opções de pagamento como marcador de posição no seu
CheckoutResponseMessage
, consulte o exemplo abaixo, que usa uma exemplo de gateway de pagamento paraPaymentOptions
.
- A configuração do processamento de pagamentos é abordada mais adiante em Configurar o Google
Pay.
Você pode usar o JSON de marcador de posição no
Exemplo de resposta bem-sucedida
{
"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": []
}
}
}
]
}
}
}
]
}
}
}
Falha na solicitação
Se o pedido de finalização da compra não for concluído, CheckoutResponseMessage
vai precisar
inclua FoodErrorExtension
, que contém uma lista de
FoodOrderError
itens que descrevem os erros ocorridos. Se houver dados recuperáveis
erros no pedido, como uma alteração no preço de um item no carrinho, o
FoodErrorExtension
precisa incluir o correctedProposedOrder
.
Exemplo de resposta sem êxito
{
"expectUserResponse": false,
"finalResponse": {
"richResponse": {
"items": [
{
"structuredResponse": {
"error": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
"foodOrderErrors": [
{
"error": "CLOSED",
"description": "The restaurant is closed."
}
]
}
}
}
]
}
}
}
Implementação da finalização da compra
Siga estas etapas ao implementar a finalização da compra.
Validar o serviço
Retorne um FoodOrderError para a primeira condição de erro de serviço encontradas. Esses erros não são recuperáveis, portanto, o primeiro erro encontrado deve ser retornados. Consulte Tratamento de erros para ver uma descrição dos erros recuperáveis.
- Leia a propriedade FulfillmentOptionInfo no
para determinar se o tipo de fulfillment é para
delivery
oupickup
. Retorne os seguintes tipos de erro, se necessário:
Tipo de erro Caso de uso INVÁLIDA O tipo de atendimento do pedido é inválido. NOT_FOUND O tipo de fulfillment não foi encontrado. CLOSED - Não há janelas OperationHours para o pedido.
- O pedido é "Assim que possível", e não há ServiceHours disponível para o horário atual.
- Há uma interdição de emergência ou o serviço
isDisabled
é verdadeiro.
UNAVAILABLE_SLOT Não foi possível atender ao pedido com antecedência. NO_CAPACITY O restaurante está ocupado e não aceita pedidos no momento. OUT_OF_SERVICE_AREA O pedido não pode ser entregue no endereço do usuário. Consulte Validação do endereço de entrega para ver um exemplo. NO_COURIER_AVAILABLE Não é possível entregar o pedido por causa de um número limitado de funcionários.
Validar e definir o preço do carrinho
Procure cada Carrinho.
lineItems
e valide com os dados atuais seu sistema ou no sistema do comerciante. A MenuItemOffer.sku
da entidade do feed é incluído como LineItem.offerId
. Crie um FoodOrderError para cada item de linha, se necessário. Crie um máximo de um erro para cada item. Retorne os seguintes tipos de erro se necessário:Tipo de erro Caso de uso Recuperável INVÁLIDA Os dados do item ou os dados das opções são inválidos. Não NOT_FOUND O item ou qualquer uma das opções não foi encontrado. Não PRICE_CHANGED O preço de um item ou combinação de complementos mudou. Esse erro pode ser tratado como recuperável. Sim AVAILABILITY_CHANGED O valor solicitado para os itens de linha ou qualquer uma das opções não está disponível. Sim REQUIREMENTS_NOT_MET O pedido mínimo ou máximo não foi atingido. Para isso, verifique se o preço do carrinho está abaixo da Taxa, eligibleTransactionVolumeMin
ou acima da Taxa.eligibleTransactionVolumeMax
. Confira o exemplo na validação do valor mínimo do pedido.Não Retorne a lista validada de lineItems com LineItemType
REGULAR
A soma de todos os preços dos itens de linha do carrinho é o preço do carrinho ouSUBTOTAL
:
Confira exemplos na seção sobre validação de itens do carrinho.
Calcular as taxas de serviço
- Encontre a entidade Taxa correta para o serviço com base no
eligibleRegion
,validFrom
,validThrough
epriority
. - Calcular o valor da taxa com base no fato de a entidade ter sido definida com
price
percentageOfCart
oupricePerMeter
. - Retorne a taxa de serviço de entrega ou retirada como um LineItem com
LineItemType
DELIVERY
ouFEE
, respectivamente. Adicionar a taxa à lista Carrinho.otherItems
.
Aplicar promoções
- Encontre a entidade Deal com base na correspondência
Promoção.
coupon
com o valor da transação.dealCode
. Valide a oferta e retorne um FoodOrderError, se necessário. Esses erros podem ser tratados como recuperáveis. Retorne os seguintes tipos de erro se necessário:
Tipo de erro Caso de uso PROMO_NOT_RECOGNIZED O código do cupom não foi reconhecido. PROMO_EXPIRED A validade do negócio expirou. PROMO_ORDER_INELIGIBLE O pedido não está qualificado para receber o cupom. PROMO_NOT_APPLICABLE Qualquer outro motivo. Calcule o preço da transação com base em Transação.
discount
ou Transação.discountPercentage
.Aplique o preço da oferta usando o total do carrinho ou a taxa total, dependendo Transação.
dealType
.Retorne o Carrinho.
promotions
com a promoção aplicada.Retorne a promoção como um LineItem com LineItemType
DISCOUNT
. Adicione o desconto ao valor Carrinho.otherItems
lista com um preço negativo.
Retornar a resposta
- Crie o ProposedOrder.
cart
, o carrinho de respostas é o igual ao do carrinho de solicitações se nenhum erro for encontrado durante a validação. - Retorne a lista ProposedOrder.
otherItems
, incluindo o tributos, taxas, gratificações e desconto, se aplicáveis. Consulte Gratuidade para mais detalhes sobre como configurar o item de gorjeta. - Inclua ProposedOrder.
totalPrice
adicionando o carrinho preço, taxas, desconto, impostos e gratificações. - Retorne o
FoodOrderExtension.
availableFulfillmentOptions
com o respectivo FulfillmentOption. Atualizar a estimativa o horário de retirada ou entrega dentro do horário previsto. - Se houver FoodOrderErrors gerados nas verificações de validação anteriores:
- Inclua StructuredResponse.
error
e a lista de em FoodErrorExtension.foodOrderErrors
. - Retorne o ProposedOrder na
correctedProposedOrder
se todos os erros forem recuperáveis. - Retorne PaymentOptions no
paymentOptions
. se todos os erros forem recuperáveis. - Se quiser, inclua
additionalPaymentOptions
se houver outros as opções de pagamento disponíveis e todos os erros podem ser recuperados.
- Inclua StructuredResponse.
- Se não houver erros de validação, retorne o
proposedOrder
,paymentOptions
no objeto CheckoutResponse. Se quiser, incluaadditionalPaymentOptions
se houver outros opções de pagamento disponíveis.