Configurar finalização da compra

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.

O CheckoutResponseMessage retorna o carrinho não modificado do cliente ou uma
erro.

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 string actions.foodordering.intent.CHECKOUT.
  • Carrinho: o campo inputs[0].arguments[0].extension de uma solicitação de finalização de compra contém um objeto Cart que representa o carrinho do cliente.
  • Entrega ou retirada: o campo de extensão do objeto Cart contém uma Objeto FoodCartExtension 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.
  • 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 objeto cart idêntico ao carrinho fornecido na CheckoutRequestMessage. Se algum conteúdo do carrinho precisar ser mudou, a CheckoutResponseMessage precisa incluir uma FoodErrorExtension com um ProposedOrder 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: uma FoodOrderExtension 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 para PaymentOptions.

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.

  1. Leia a propriedade FulfillmentOptionInfo no para determinar se o tipo de fulfillment é para delivery ou pickup.
  2. 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.
    As janelas especiais têm precedência sobre as normais. Confira exemplos em validação da janela de pedidos e como remover entidades de serviço temporariamente.
    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

  1. 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
  2. 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 ou SUBTOTAL:

Confira exemplos na seção sobre validação de itens do carrinho.

Calcular as taxas de serviço

  1. Encontre a entidade Taxa correta para o serviço com base no eligibleRegion, validFrom, validThrough e priority.
  2. Calcular o valor da taxa com base no fato de a entidade ter sido definida com price percentageOfCart ou pricePerMeter.
  3. Retorne a taxa de serviço de entrega ou retirada como um LineItem com LineItemType DELIVERY ou FEE, respectivamente. Adicionar a taxa à lista Carrinho.otherItems.

Aplicar promoções

  1. Encontre a entidade Deal com base na correspondência Promoção.coupon com o valor da transação.dealCode.
  2. 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.
  3. Calcule o preço da transação com base em Transação.discount ou Transação.discountPercentage.

  4. Aplique o preço da oferta usando o total do carrinho ou a taxa total, dependendo Transação.dealType.

  5. Retorne o Carrinho.promotions com a promoção aplicada.

  6. 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

  1. 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.
  2. 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.
  3. Inclua ProposedOrder.totalPrice adicionando o carrinho preço, taxas, desconto, impostos e gratificações.
  4. Retorne o FoodOrderExtension.availableFulfillmentOptions com o respectivo FulfillmentOption. Atualizar a estimativa o horário de retirada ou entrega dentro do horário previsto.
  5. 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.
  6. Se não houver erros de validação, retorne o proposedOrder, paymentOptions no objeto CheckoutResponse. Se quiser, inclua additionalPaymentOptions se houver outros opções de pagamento disponíveis.