Set up Submit order

After the checkout call, the user reviews the updated cart with taxes, delivery fees, discounts, and other charges that you return. The user confirms and submits the order and Google sends your fulfillment endpoint a JSON request that contains the information for the order. Your web service must receive this order, process it, and respond back to Google with the state of the order.

This section describes the order request message format sent by Google, called the SubmitOrderRequestMessage, and the format of the response message you must provide, called the SubmitOrderResponseMessage. For more information about the order fulfillment lifecycle, see the Fulfillment overview.

Order fulfillment implementation

The Ordering End-to-End web service you build to work with Ordering End-to-End must include a URL endpoint for receiving order messages from Google. For order processing, your web service receives a SubmitOrderRequestMessage in JSON format as a POST request from Google. This request contains a customer order, including taxes, fees, and payment information. Upon receiving a submit order request, your web service must do the following:

  • Check transaction eligibility, such as card verification or fraud detection.
  • Create an order in your system.
  • Authorize the payment method and call the charge API of your payment processor when applicable.
  • Respond with the appropriate state of the order: CREATED, CONFIRMED, or REJECTED.

After processing the order, your fulfillment code must provide a response in the form of a SubmitOrderResponseMessage JSON message back to Google.

For more information about the Ordering End-to-End fulfillment web service implementation requirements, see the Fulfillment overview.

Order request message

When a customer chooses to place an order during the Ordering End-to-End flow, Google sends a request to your web service with a JSON message called a SubmitOrderRequestMessage that contains the following data:

  1. Intent: The inputs[0].intent field of every submit order request body contains the actions.intent.TRANSACTION_DECISION string value.
  2. Order: The inputs[0].arguments[0].transactionDecisionValue field of a submit order request contains an Order object that represents the customer's order to be placed, along with payment details.
  3. Sandbox flag: The isInSandbox field of a submit order request indicates whether the transaction uses sandbox payments.

Order request example

The following is an example 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
}
    

Order response message

After receiving a request, your Ordering End-to-End web service processes the request and sends back a SubmitOrderResponseMessage that includes the following data:

  • OrderUpdate: An object containing the state of the order, and any post-order actions available to the user, such as contacting support and viewing order details, which you define in the finalResponse.richResponse.items[0].structuredResponse.orderUpdate field of the response.

Order update field

When your web service sends a SubmitOrderResponseMessage, it contains an OrderUpdate field that includes the following fields:

  • actionOrderId: The unique ID of the order, which is used to uniquely identify the order in your system and refer to it when sending subsequent order updates.
  • orderState: An OrderState object representing the state of the order.
  • orderManagementActions: Post-order actions available to the user, such as contacting customer support and viewing order details.
  • totalPrice: The total price of the order. This is optional. Only send if the total price of the order has changed after the order is submitted.

An order can be in one of the following states:

  • CREATED: Your fulfillment endpoint processed the order successfully, but the provider has not yet confirmed the order.
  • CONFIRMED: Your fulfillment endpoint processed the order successfully, and the provider has confirmed the order.
  • REJECTED: There was a problem and your fulfillment endpoint could not create or confirm the order, which can include problems with payment.

If you set an order to a REJECTED state, specify the reason in the rejectionInfo field of OrderUpdate. Use FoodOrderUpdateExtension.FoodOrderErrors values in conjunction with rejectionInfo of type UNKNOWN and provide a description.

Order response example

The following is an example 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"
              }
            }
          }
        }
      ]
    }
  }
}

Unsuccessful request

If a submit request is unsuccessful, SubmitOrderResponseMessage needs to set the OrderState.state to REJECTED. The response must also include the RejectionInfo, which contains a RejectionType object to describe the error type.

Unsuccessful response example

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"
                    }
                  }
                }
              ]
            }
          }
        }
      ]
    }
  }
}
    

Submit order implementation

The following steps should be taken when implementing the submit order API.

Validation

  1. Perform service, cart and promotion validations as done in Set up Checkout.
  2. Return RejectionInfo with one of the following types if needed:
RejectionInfoType Use case
UNAVAILABLE_SLOT The fulfillment time is no longer valid.
PROMO_USER_INELIGIBLE Use the Email in the Contact object in the request to validate the promotion eligibility for the user. See the example in implement submit order with promotions.
INELIGIBLE
  • User information such as phone number or Email is not valid.
  • Your risk engine detects fraud.
PAYMENT_DECLINED The payment can't be processed. For example, this could be due to insufficient funds.
UNKNOWN For any other validation error.

Set the OrderState.state to REJECTED if there are validation errors encountered. Optionally, you can provide a specific rejection reason using the FoodOrderUpdateExtension.foodOrderErrors. See examples in Submit Order validation.

Process the payment

  1. Compute the totalPrice by adding the cart price, fees, discount, taxes and gratuity. The totalPrice should be the same as the totalPrice returned in the CheckoutResponseMessage plus the change in the gratuity amount if the gratuity can be modified by the user. See Price changes during submit order for more details.
  2. Process the order and payment if you return a response with an order state of CREATED or CONFIRMED.
  3. Ensure that a valid response format is returned by using generated types created from the schema as described in generate client libraries.
  4. Use the GoogleProvidedPaymentInstrument.instrumentToken to process the payment. Return RejectionInfo with type PAYMENT_DECLINED if the payment can't be processed. See Process payments for more details.
  5. Notify the user immediately after the order is processed by Email and or SMS.

Return the response

  1. Set the OrderState.state to CREATED or CONFIRMED if there are no errors.
  2. Set the OrderState.state to REJECTED if there are errors encountered and include the RejectionInfo object with the corresponding RejectionInfoType.
  3. Set the OrderUpdate.orderManagementActions.