The checkout process is invoked when a user creates a cart. The contents of the user's cart and details about the order are sent to your Order with Google web service. This information is validated by your web service, and then you can either proceed or make adjustments to their cart as needed.
The checkout handler for your web service must respond to POST requests. When a
customer chooses to check out, Google sends the Order with Google web service a
JSON request body in the form of a CheckoutRequestMessage
, which contains the
details of a customer's Cart
. Your web service then responds back with a
CheckoutResponseMessage
. The following diagram illustrates the process.
Upon receiving a checkout request, your Order with Google web service must do the following:
- Check the cart's validity based on the current item prices, availability, and provider service.
- Calculate the total price (including any discounts, taxes, and delivery fees).
- If successful, respond with an unmodified cart.
- If unsuccessful, respond with an error message and a new proposed order.
Before you begin implementing checkout, we recommend reviewing the Fulfillment overview documentation.
Checkout Request Message
In order to validate the customer's cart, when a customer chooses to check out,
Google sends a request to your web service with a JSON body in the form of a
CheckoutRequestMessage
. The customer order is not submitted until later in the
Order with Google flow.
Data contained in a
CheckoutRequestMessage
includes the following:
- Intent: The
inputs[0].intent
field of every checkout request body contains theactions.foodordering.intent.CHECKOUT
string value. - Cart: The
inputs[0].arguments[0].extension
field of a checkout request contains aCart
object that represents the customer's cart. - Delivery or takeout: The
Cart
object's extension field contains aFoodCartExtension
object that specifies properties for delivery or takeout:- For delivery orders, the
FoodCartExtension
object includes the delivery address. - For pickup or takeout orders, the
FoodCartExtension
object doesn't contain any location information.
- For delivery orders, the
- Sandbox: The
isInSandbox
field of a checkout request contains a boolean value that indicates whether the transaction uses sandbox payments.
Checkout request example
Below is an example of a 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
}
Checkout Response Message
After receiving a request from the Order with Google service, your checkout web
service must process it and respond with a CheckoutResponseMessage
. The
CheckoutResponseMessage
needs to cover either a successful or unsuccessful
request.
Successful request
If a check out request is successful, CheckoutResponseMessage
needs to include
ProposedOrder
and
PaymentOptions
:
ProposedOrder
cart
: Acart
object identical to the cart provided in theCheckoutRequestMessage
. If any of the contents of the cart need to be changed, theCheckoutResponseMessage
should instead include aFoodErrorExtension
with a correctedProposedOrder
.otherItems
: Items added by the provider, such as delivery charges, taxes, and other fees. May also contain gratuity added by the user.totalPrice
: The total price of the order.extension
: AFoodOrderExtension
that defines fulfillment information for the order, such as delivery time.
PaymentOptions
- Setting up payment processing is covered later in Set up Google
Pay.
You can use placeholder JSON in your
CheckoutResponseMessage
until you're ready to implement payment processing. - To add placeholder payment options in your
CheckoutResponseMessage
, refer to the example below, which uses an example payment gateway forPaymentOptions
.
- Setting up payment processing is covered later in Set up Google
Pay.
You can use placeholder JSON in your
Successful response example
{
"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": []
}
}
}
]
}
}
}
]
}
}
}
Unsuccessful request
If a checkout request is unsuccessful, CheckoutResponseMessage
needs to
include FoodErrorExtension
, which contains a list of
FoodOrderError
items that describe any errors that occurred. If there are any recoverable
errors to the order, like a price change of an item in the cart, the
FoodErrorExtension
must include the correctedProposedOrder
.
Unsuccessful response example
{
"expectUserResponse": false,
"finalResponse": {
"richResponse": {
"items": [
{
"structuredResponse": {
"error": {
"@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
"foodOrderErrors": [
{
"error": "CLOSED",
"description": "The restaurant is closed."
}
]
}
}
}
]
}
}
}