Triển khai các thao tác thực hiện nâng cao

Liên kết nguồn cấp dữ liệu thực đơn và các mục trong giỏ hàng để thực hiện đơn hàng

Khi khách hàng thêm các mặt hàng từ nguồn cấp dữ liệu Thực đơn của bạn vào giỏ hàng và thanh toán, Google gửi các mặt hàng đó đến điểm cuối thực hiện đơn hàng của bạn để xác minh giá và tình trạng còn hàng. Sau khi giá và tình trạng còn hàng được xác thực, khách hàng có thể đặt hàng. Phần này minh hoạ cách liên kết các mục trong nguồn cấp dữ liệu thực đơn với các mặt hàng trong giỏ hàng thực hiện đơn hàng.

Các mẫu trong mục này là phiên bản đơn giản của Nguồn cấp dữ liệu thực đơn và Giỏ hàng giản đồ. Chỉ những trường có liên quan để minh hoạ mối liên kết giữa Nguồn cấp dữ liệu thực đơn và thì đối tượng Giỏ hàng sẽ xuất hiện. Để xem giản đồ đầy đủ, hãy xem MenuCart.

Những mặt hàng trong nguồn cấp dữ liệu Menu được thêm vào giỏ hàng sẽ được gửi trong Cart cho cả thanh toán và gửi đơn đặt hàng.

  • Một MenuItem đơn giản được biểu thị dưới dạng LineItem trong lineItems mảng với offerIdoffer.id của mục trong trình đơn đã chọn trong Trình đơn nguồn cấp dữ liệu.
  • MenuItemMenuItemOption bắt buộc được biểu thị dưới dạng LineItem trong mảng lineItems với offerId được chọn tuỳ chọn mục trong trình đơn offer.id từ nguồn cấp dữ liệu Thực đơn.
  • AddOnMenuItem của LineItem được biểu thị dưới dạng FoodItemOption trong mảng options của FoodItemExtension. Mỗi tuỳ chọn có một offerId tương ứng với trình đơn tiện ích bổ sung đã chọn offer.id của mục từ nguồn cấp dữ liệu Thực đơn. Lưu ý rằng AddOnMenuItem cũng có thể có (các) AddOnMenuItem lồng ghép được biểu thị dưới dạng subOptions bên trong mỗi .

Ví dụ sau đây liên kết các mục trong trình đơn giữa nguồn cấp dữ liệu thực đơn và phương thức thực hiện đơn hàng giỏ hàng.

JSON

Ví dụ này chứa một danh sách các mục trong trình đơn đơn giản.

Các món trong thực đơn trong một nguồn cấp dữ liệu thực đơn:

{
  "@type": "Menu",
  "@id": "menu_id",
  "hasMenuItem": [
    {
      "@type": "MenuItem",
      "@id": "menuitem_id_1",
      "offers": [
        {
          "@type": "Offer",
          "@id": "menuitem_offer_id_1",
          "price": "p_1",
          "priceCurrency": "USD"
        }
      ]
    },
    {
      "@type": "MenuItem",
      "@id": "menuitem_id_2",
      "offers": [
        {
          "@type": "Offer",
          "@id": "menuitem_offer_id_2",
          "price": "p_2",
          "priceCurrency": "USD"
        }
      ]
    }
  ]
}

Các mặt hàng trong trình đơn được liên kết với giỏ hàng thực hiện đơn hàng:

{
  "@type": "Cart",
  "lineItems": [
    {
      "offerId": "menuitem_offer_id_1",
      "price": {
        "amount": {
          "currencyCode": "USD",
          "units": "dollar(q_1*p_1)",
          "nanos": "cent(q_1*p_1)"
        }
      },
      "quantity": "q_1"
    },
    {
      "offerId": "menuitem_offer_id_2",
      "price": {
        "amount": {
          "currencyCode": "USD",
          "units": "dollar(q_2*p_2)",
          "nanos": "cent(q_2*p_2)"
        }
      },
      "quantity": "q_2"
    }
  ]
}

JSON

Ví dụ này chứa một mục trong trình đơn có một hoặc nhiều AddOnMenuItems.

Các món trong thực đơn trong một nguồn cấp dữ liệu thực đơn:

{
  "@type": "Menu",
  "@id": "menu_id",
  "hasMenuItem": [
    {
      "@type": "MenuItem",
      "@id": "menuitem_id_1",
      "offers": [
        {
          "@type": "Offer",
          "@id": "menuitem_offer_id_1",
          "price": "p_1",
          "priceCurrency": "USD"
        }
      ],
      "menuAddOn": [
        {
          "@type": "MenuAddOnSection",
          "@id": "menuaddon_section_id_1",
          "hasMenuItem": [
            {
              "@type": "AddOnMenuItem",
              "@id": "menuitem_addon_id_1",
              "offers": [
                {
                  "@type": "Offer",
                  "@id": "menuitem_addon_offer_id_1",
                  "price": "addon_p_1",
                  "priceCurrency": "USD"
                }
              ]
            },
            {
              "@type": "AddOnMenuItem",
              "@id": "menuitem_addon_id_2",
              "offers": [
                {
                  "@type": "Offer",
                  "@id": "menuitem_addon_offer_id_2",
                  "price": "addon_p_2",
                  "priceCurrency": "USD"
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "@type": "MenuItem",
      "@id": "menuitem_id_2",
      "offers": [
        {
          "@type": "Offer",
          "@id": "menuitem_offer_id_2",
          "price": "p_2",
          "priceCurrency": "USD"
        }
      ]
    }
  ]
}

Các mặt hàng trong trình đơn được liên kết với giỏ hàng thực hiện đơn hàng:

{
  "@type": "Cart",
  "lineItems": [
    {
      "offerId": "menuitem_offer_id_1",
      "price": {
        "amount": {
          "currencyCode": "USD",
          "units": "dollar(q_1*(p_1 + addon_q_1*addon_p_1 + addon_q_2*addon_p_2))",
          "nanos": "cent(q_1*(p_1 + addon_q_1*addon_p_1 + addon_q_2*addon_p_2))"
        }
      },
      "quantity": "q_1",
      "extension": {
        "@type": "FoodItemExtension",
        "options": [
          {
            "offerId": "menuitem_addon_offer_id_1",
            "price": {
                "currencyCode": "USD",
                "units": "dollar(addon_q_1*addon_p_1)",
                "nanos": "cent(addon_q_1*addon_p_1)"
            },
            "quantity": "addon_q_1"
          },
          {
            "offerId": "menuitem_addon_offer_id_2",
            "price": {
                "currencyCode": "USD",
                "units": "dollar(addon_q_2*addon_p_2)",
                "nanos": "cent(addon_q_2*addon_p_2)"
            },
            "quantity": "addon_q_2"
          }
        ]
      }
    },
    {
      "offerId": "menuitem_offer_id_2",
      "price": {
        "amount": {
          "currencyCode": "USD",
          "units": "dollar(q_2*p_2)",
          "nanos": "cent(q_2*p_2)"
        }
      },
      "quantity": "q_2"
    }
  ]
}

JSON

Ví dụ này chứa một mục trong trình đơn có các lựa chọn cho mục trong trình đơn, AddOnMenuItems, và AddOnMenuItems được lồng

Các món trong thực đơn trong một nguồn cấp dữ liệu thực đơn:

{
  "@type": "MenuItem",
  "@id": "menuitem_id_1",
  "hasMenuItemOptions": [
    {
      "@type": "MenuItemOption",
      "value": {
        "@type": "PropertyValue",
        "name": "OPTION",
        "value": "Large",
        "offers": [
          {
            "@type": "Offer",
            "@id": "menuitem_option_offer_id_1",
            "price": "p_1",
            "priceCurrency": "USD"
          }
        ],
        "menuAddOn": [
          {
            "@type": "AddOnMenuSection",
            "@id": "menuitem_option_addon_section_id_1",
            "hasMenuItem": [
              {
                "@type": "AddOnMenuItem",
                "@id": "menuitem_option_addon_id_1",
                "offers": [
                  {
                    "@type": "Offer",
                    "@id": "menuitem_option_addon_offer_id_1",
                    "price": "addon_p_1",
                    "priceCurrency": "USD"
                  }
                ]
              },
              {
                "@type": "AddOnMenuItem",
                "@id": "menuitem_option_addon_id_2",
                "offers": [
                  {
                    "@type": "Offer",
                    "@id": "menuitem_option_addon_offer_id_2",
                    "price": "addon_p_2",
                    "priceCurrency": "USD"
                  }
                ],
                "menuAddOn": [
                  {
                    "@type": "AddOnMenuSection",
                    "@id": "menuitem_option_subaddon_section_id_1",
                    "hasMenuItem": [
                      {
                        "@type": "AddOnMenuItem",
                        "@id": "menuitem_option_subaddon_id_1",
                        "offers": [
                          {
                            "@type": "Offer",
                            "@id": "menuitem_option_subaddon_offer_id_1",
                            "price": "subaddon_p_1",
                            "priceCurrency": "USD"
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    }
  ]
}

Các mặt hàng trong trình đơn được liên kết với giỏ hàng thực hiện đơn hàng:

{
  "@type": "Cart",
  "lineItems": [
    {
      "offerId": "menuitem_option_offer_id_1",
      "price": {
        "amount": {
          "currencyCode": "USD",
          "units": "dollar(q_1*(p_1 + addon_q_1*addon_p_1 + addon_q_2*(addon_p_2 + subaddon_q_1*subaddon_p_1)))",
          "nanos": "cent(q_1*(p_1 + addon_q_1*addon_p_1 + addon_q_2*(addon_p_2 + subaddon_q_1*subaddon_p_1)))"
        }
      },
      "quantity": "q_1",
      "extension": {
        "@type": "FoodItemExtension",
        "options": [
          {
            "offerId": "menuitem_option_addon_offer_id_1",
            "price": {
              "currencyCode": "USD",
              "units": "dollar(addon_q_1*addon_p_1)",
              "nanos": "cent(addon_q_1*addon_p_1)"
            },
            "quantity": "addon_q_1"
          },
          {
            "offerId": "menuitem_option_addon_offer_id_2",
            "price": {
              "currencyCode": "USD",
              "units": "dollar(addon_q_2*(addon_p_2 + subaddon_q_1*subaddon_p_1))",
              "nanos": "cent(addon_q_2*(addon_p_2 + subaddon_q_1*subaddon_p_1))"
            },
            "quantity": "addon_q_2",
            "subOptions": [
              {
                "offerId": "menuitem_option_subaddon_offer_id_1",
                "price": {
                  "currencyCode": "USD",
                  "units": "dollar(subaddon_q_1*subaddon_p_1)",
                  "nanos": "cent(subaddon_q_1*subaddon_p_1)"
                },
                "quantity": "subaddon_q_1"
              }
            ]
          }
        ]
      }
    }
  ]
}

Xử lý lỗi

Nếu gặp sự cố khi xử lý CheckoutRequestMessage, bạn có thể phản hồi bằng CheckoutResponseMessage chứa FoodErrorExtension thay vì CheckoutResponse. Bạn có thể dùng để xác định một hoặc nhiều lỗi xảy ra trong quá trình xử lý.

Có 2 cách để xử lý lỗi:

  • Lỗi có thể khôi phục: Người dùng không bắt buộc phải chỉnh sửa giỏ hàng của họ để gửi đơn đặt hàng. Ví dụ: nếu bạn xác định rằng một mục trong Cart có khi giá thay đổi, bạn có thể phản hồi bằng loại lỗi FoodOrderError PRICE_CHANGED, cùng với correctedProposedOrderpaymentOptions. Google thông báo cho người dùng về thay đổi nhưng cho phép người dùng gửi kèm theo correctedProposedOrder. Người dùng cũng có thể quay lại và chỉnh sửa giỏ hàng nếu mong muốn. Bạn sẽ nhận được CheckoutRequestMessage mới hoặc SubmitOrderRequestMessage.
  • Lỗi không thể khôi phục: Người dùng phải chỉnh sửa giỏ hàng trước gửi đơn đặt hàng. Ví dụ: nếu bạn xác định rằng nhà hàng này đã đóng, bạn có thể phản hồi bằng FoodOrderError thuộc loại lỗi CLOSED. Google thông báo cho người dùng và quản lý quá trình tương tác để cập nhật lên nhà hàng của bạn. Bạn sẽ nhận được một CheckoutRequestMessage mới để có giỏ hàng.

Nhìn chung, lỗi ở cấp giỏ hàng là không thể khôi phục và lỗi ở cấp mặt hàng có thể khôi phục được. Để biết danh sách đầy đủ các loại lỗi và ý nghĩa của chúng, hãy xem FoodOrderError.

Xử lý các thay đổi về giá

Thay đổi giá trong quy trình thanh toán

Nếu bạn gặp vấn đề về giá trong khi xử lý giao dịch thanh toán của khách hàng yêu cầu, hãy làm như sau:

  1. Phản hồi CheckoutRequestMessage bằng CheckoutResponseMessage chứa FoodErrorExtension, như mô tả trong phần Xử lý lỗi.
  2. Trong phản hồi lỗi, hãy sử dụng correctedProposedOrder.cart để cập nhật giá thành giá trị chính xác. Google nhận được đơn đặt hàng đã sửa và có thể phát hành một đơn đặt hàng mới CheckoutRequestMessage.

Sau khi thanh toán, Google sẽ hiển thị trang xác nhận đơn đặt hàng cho người dùng cuối, bất kể ProposedOrder có bị thay đổi hay không.

Nếu suggesteddOrder đã được sửa, Google có thể hiển thị các cảnh báo bổ sung cho thông báo cho người dùng về các thay đổi. Nếu người dùng đồng ý đặt hàng, sẽ không có thêm yêu cầu thanh toán nào nữa. Quy trình sẽ tiếp tục gửi đơn đặt hàng, với ProposedOrder đã sửa.

Tuy nhiên, người dùng luôn có thể đổi ý và chỉnh sửa lại giỏ hàng. Thời gian bản cập nhật giỏ hàng theo cách này thì Google sẽ gửi một CheckoutRequestMessage mới.

Giá thay đổi trong quá trình gửi đơn đặt hàng

Nếu bạn gặp vấn đề về giá trong quá trình xử lý việc gửi đơn đặt hàng (ý định actions.intent.TRANSACTION_DECISION đã được kích hoạt), đừng phản hồi có lỗi hoặc cập nhật giá trong phản hồi của bạn. Nếu giá, số lượng, hoặc các thông tin chi tiết khác trong SubmitOrderRequestMessage không tương ứng với dữ liệu của bạn, hãy phản hồi bằng orderState được đặt thành REJECTED để cho biết rằng Không thể đặt hàng theo yêu cầu.

Sau đó, nếu đơn đặt hàng và thông tin thanh toán là hợp lệ, hãy đặt orderState thành CREATED hoặc CONFIRMED. Ngoài ra, hãy thêm actionOrderId để thể hiện mã đơn hàng trong hệ thống của bạn. Bạn phải sử dụng mã này khi gửi các bản cập nhật tiếp theo.

Nếu bạn không thể xử lý khoản thanh toán và đã gửi SubmitOrderRequestMessage, bạn có thể gửi AsyncOrderUpdateRequestMessage với orderState được đặt thành REJECTED để cho phép người dùng biết rằng đơn đặt hàng sẽ không thành công.

Giá thay đổi sau khi gửi đơn đặt hàng

Nếu bạn xác định rằng một mức giá đã thay đổi so với giá được áp dụng khi khách hàng sử dụng đã gửi đơn đặt hàng, bạn có thể tạo AsyncOrderUpdateRequestMessage, như được mô tả trong phần Triển khai bản cập nhật thứ tự không đồng bộ, với mức giá mới.

Cách cập nhật giá bằng tính năng cập nhật đơn đặt hàng không đồng bộ:

  1. Thay đổi giá bằng lineItemUpdates[x].price. Chiến dịch này giá trị phản ánh tổng chi phí của mặt hàng, bao gồm các dịch vụ bổ sung và nhân theo số lượng. (Để biết thêm thông tin, hãy xem phần mô tả của trường price của LineItem.)
  2. Nhập nội dung giải thích bằng lineItemUpdates[x].reason.
  3. Đặt lineItemUpdates[x].orderState đến CONFIRMED.

Bạn có thể thử tính phí vào phương thức thanh toán trước hoặc sau khi gửi AsyncOrderUpdateRequestMessage, tuỳ theo quyết định của bạn. Nếu giao dịch không thành công (có thể do delta giá quá cao), hãy gửi AsyncOrderUpdateRequestMessage với các cài đặt sau trong phần OrderUpdate để thông báo cho Google về lỗi:

  • Đặt orderState thành REJECTED.
  • Mô tả lỗi trong trường label.

Xác thực quy trình thanh toán

Như đã thảo luận trong Bước 4: Triển khai thanh toán, điểm cuối phương thức thực hiện sẽ thực hiện xác thực trên mọi thiết bị đến CheckoutRequestMessage rồi trả lời bằng CheckoutResponseMessage.

Dưới đây là ví dụ về CheckoutResponseMessage để thành công xác thực:

Trường hợp sử dụng Cách triển khai
Trường hợp sử dụng 1: Xác thực thành công Trả lại CheckoutResponse. Phải có ProposedOrderPaymentOptions. ProposedOrder bao gồm thuế, phí và tổng giá của giỏ hàng.

JSON

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "checkoutResponse": {
              "proposedOrder": {
                "id": "sample_proposed_order_id_1",
                "otherItems": [
                  {
                    "name":"New customer discount",
                    "price": {
                      "type":"ESTIMATE",
                      "amount": {
                        "currencyCode":"USD",
                        "units":"-5",
                        "nanos": -500000000
                      }
                    },
                    "type": "DISCOUNT"
                  },
                  {
                    "name": "Delivery fee",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD",
                        "units": "3",
                        "nanos": 500000000
                      }
                    },
                    "type": "DELIVERY"
                  },
                  {
                    "name": "Tax",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD",
                        "units": "1",
                        "nanos": 500000000
                      }
                    },
                    "type": "TAX"
                  }
                ],
                "cart": {
                  "merchant": {
                    "id": "https://www.exampleprovider.com/merchant/id1",
                    "name": "Falafel Bite"
                  },
                  "lineItems": [
                    {
                      "name": "Pita Chips",
                      "type": "REGULAR",
                      "id": "sample_item_offer_id_1",
                      "offerId": "https://www.exampleprovider.com/menu/item/offer/id1",
                      "quantity": 1,
                      "price": {
                        "type": "ESTIMATE",
                        "amount": {
                          "currencyCode": "USD",
                          "units": "2",
                          "nanos": 750000000
                        }
                      },
                      "subLines": [
                        {
                          "note": "Notes for this item."
                        }
                      ],
                      "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension",
                        "options": [
                          {
                            "id": "sample_addon_offer_id_1",
                            "offerId": "https://www.exampleprovider.com/menu/item/addon/offer/id1",
                            "name": "Honey Mustard",
                            "price": {
                              "currencyCode": "USD"
                            },
                            "quantity": 1
                          },
                          {
                            "id": "sample_addon_offer_id_2",
                            "offerId": "https://www.exampleprovider.com/menu/item/addon/offer/id2",
                            "name": "BBQ Sauce",
                            "price": {
                              "currencyCode": "USD",
                              "nanos": 500000000
                            },
                            "quantity": 1
                          }
                        ]
                      }
                    },
                    {
                      "name": "Chicken Shwarma Wrap",
                      "type": "REGULAR",
                      "id": "sample_item_offer_id_2",
                      "offerId": "https://www.exampleprovider.com/menu/item/offer/id2",
                      "quantity": 1,
                      "price": {
                        "type": "ESTIMATE",
                        "amount": {
                          "currencyCode": "USD",
                          "units": "8"
                        }
                      },
                      "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                      }
                    },
                    {
                      "name": "Greek Salad",
                      "type": "REGULAR",
                      "id": "sample_item_offer_id_3",
                      "offerId": "https://www.exampleprovider.com/menu/item/offer/id3",
                      "quantity": 1,
                      "price": {
                        "type": "ESTIMATE",
                        "amount": {
                          "currencyCode": "USD",
                          "units": "9",
                          "nanos": 990000000
                        }
                      },
                      "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                      }
                    },
                    {
                      "name": "Prawns Biryani",
                      "type": "REGULAR",
                      "id": "sample_item_offer_id_4",
                      "offerId": "https://www.exampleprovider.com/menu/item/offer/id4",
                      "quantity": 1,
                      "price": {
                        "type": "ESTIMATE",
                        "amount": {
                          "currencyCode": "USD",
                          "units": "15",
                          "nanos": 990000000
                        }
                      },
                      "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                      }
                    }
                  ],
                  "extension": {
                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
                    "fulfillmentPreference": {
                      "fulfillmentInfo": {
                        "delivery": {
                          "deliveryTimeIso8601": "P90M"
                        }
                      }
                    },
                    "location": {
                      "coordinates": {
                        "latitude": 37.788783,
                        "longitude": -122.41384
                      },
                      "formattedAddress": "1350 CHARLESTON ROAD, MOUNTAIN VIEW, CA, United States",
                      "zipCode": "94043",
                      "city": "Mountain View",
                      "postalAddress": {
                        "regionCode": "US",
                        "postalCode": "94043",
                        "administrativeArea": "CA",
                        "locality": "Mountain View",
                        "addressLines": [
                          "1350 Charleston Road"
                        ]
                      },
                      "notes": "Gate code is #111"
                     }
                   }
                },
                "totalPrice": {
                  "type": "ESTIMATE",
                  "amount": {
                    // Represents $36.73
                    "currencyCode": "USD",
                    "units": "36",
                    "nanos": 730000000
                  }
                },
                "extension": {
                  "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension",
                  "availableFulfillmentOptions": [
                    {
                      "fulfillmentInfo": {
                        "delivery": {
                          "deliveryTimeIso8601": "P90M"
                        }
                      },
                      "expiresAt": "2017-07-17T12:30:00Z"
                    }
                  ]
                }
              },
              "paymentOptions": {
                "googleProvidedOptions": {
                  "tokenizationParameters": {
                    "tokenizationType": "PAYMENT_GATEWAY",
                    "parameters": {
                      "gateway": "stripe",
                      "stripe:publishableKey": "pk_live_stripe_client_key",
                      "stripe:version": "2017-04-06"
                    }
                  },
                  "supportedCardNetworks": [
                    "AMEX",
                    "DISCOVER",
                    "MASTERCARD",
                    "JCB",
                    "VISA"
                  ],
                  "prepaidCardDisallowed": true
                }
              }
            }
          }
        }
      ]
    }
  }
}

Xác thực địa chỉ giao hàng

Điểm cuối thực hiện đơn hàng phải xác thực địa chỉ giao hàng có trong mỗi CheckoutRequestMessage.

Nếu có vấn đề về địa chỉ giao hàng, chẳng hạn như địa chỉ nằm ngoài phạm vi dịch vụ giao hàng, CheckoutResponseMessage do phương thức thực hiện phải chứa FoodOrderError thuộc kiểu phù hợp.

Trường hợp sử dụng Cách triển khai
Trường hợp sử dụng 1: Xác thực không thành công vì không có địa chỉ giao hàng hoặc có vấn đề với địa chỉ giao hàng Trả lại FoodErrorExtension bằng FoodOrderError về loại lỗi OUT_OF_SERVICE_AREA.

JSON

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "error": {
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
              "foodOrderErrors": [
                {
                  "error": "OUT_OF_SERVICE_AREA",
                  "description": "Sorry, the restaurant cannot deliver to your address."
                }
              ]
            }
          }
        }
      ]
    }
  }
}

Xác thực giá trị đơn đặt hàng tối thiểu

Điểm cuối thực hiện đơn hàng phải xác thực giá trị đặt hàng tối thiểu của mỗi CheckoutRequestMessage.

Nếu bạn không đáp ứng được giá trị đặt hàng tối thiểu, CheckoutResponseMessage mà phương thức thực hiện của bạn trả về phải chứa FoodOrderError loại lỗi REQUIREMENTS_NOT_MET.

Trường hợp sử dụng Cách triển khai
Trường hợp sử dụng 1: Xác thực không thành công do giá trị đặt hàng tối thiểu không được đáp ứng Trả lại FoodErrorExtension bằng FoodOrderError về loại lỗi REQUIREMENTS_NOT_MET.

JSON

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "error": {
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
              "foodOrderErrors": [
                {
                  "error": "REQUIREMENTS_NOT_MET",
                  "description": "The cart subtotal must be over $20."
                }
              ]
            }
          }
        }
      ]
    }
  }
}

Xác thực khoảng thời gian đặt hàng

Điểm cuối thực hiện đơn hàng của bạn phải xác thực mọi yếu tố có thể ảnh hưởng đến cửa sổ sắp xếp của từng CheckoutRequestMessage.

Ví dụ: nếu nhà hàng đóng cửa hoặc không còn nhận đơn đặt hàng tại thời điểm, CheckoutResponseMessage mà phương thức thực hiện của bạn trả về sẽ chứa một FoodOrderError thuộc loại lỗi CLOSED hoặc NO_CAPACITY, .

Trường hợp sử dụng Cách triển khai
Trường hợp sử dụng 1: Không xác thực được vì nhà hàng đóng cửa hoặc không còn được hỗ trợ nữa Trả lại FoodErrorExtension bằng FoodOrderError về loại lỗi CLOSED.
Trường hợp sử dụng 2: Xác thực không thành công vì nhà hàng đang bận và hiện không nhận đơn đặt hàng Trả lại FoodErrorExtension bằng FoodOrderError về loại lỗi NO_CAPACITY.

JSON

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "error": {
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
              "foodOrderErrors": [
                {
                  "error": "CLOSED",
                  "description": "The restaurant is closed."
                }
              ]
            }
          }
        }
      ]
    }
  }
}

JSON

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "error": {
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
              "foodOrderErrors": [
                {
                  "error": "NO_CAPACITY",
                  "description": "Sorry, the restaurant is busy at the moment."
                }
              ]
            }
          }
        }
      ]
    }
  }
}

Xác thực mặt hàng trong giỏ hàng

Điểm cuối thực hiện đơn hàng phải xác thực giá và tình trạng còn hàng của từng mặt hàng trong giỏ hàng nằm trong CheckoutRequestMessage.

Nếu tình trạng còn hàng hoặc giá đã thay đổi, CheckoutResponseMessage mà phương thức thực hiện của bạn trả về phải chứa FoodOrderError loại lỗi AVAILABILITY_CHANGED hoặc PRICE_CHANGED.

Trường hợp sử dụng Cách triển khai
Trường hợp sử dụng 1: Xác thực không thành công vì một số mục trong trình đơn và/hoặc các thông tin tuỳ chỉnh không hợp lệ hoặc đã hết hàng Trả lại FoodErrorExtension bằng correctedProposedOrder, PaymentOptionsFoodOrderError thuộc loại lỗi AVAILABILITY_CHANGED. Phải xoá các mục không hợp lệ khỏi CorrectedProposedOrder.
Trường hợp sử dụng 2: Xác thực không thành công do một số mục trong trình đơn và/hoặc các thông tin tuỳ chỉnh không hợp lệ hoặc đã hết hàng. Giỏ hàng đã chỉnh sửa không còn đáp ứng yêu cầu về giá trị đơn đặt hàng tối thiểu. Trả lại FoodErrorExtension bằng FoodOrderError loại lỗi AVAILABILITY_CHANGEDREQUIREMENTS_NOT_MET.
Trường hợp sử dụng 3: Xác thực không thành công do một số mục trong trình đơn và/hoặc giá tuỳ chỉnh đã thay đổi Trả lại FoodErrorExtension bằng correctedProposedOrder, PaymentOptionsFoodOrderError thuộc loại lỗi PRICE_CHANGED. Bạn phải cập nhật giá đã lỗi thời sau CorrectedProposedOrder.
Trường hợp sử dụng 4: Xác thực không thành công do một số mục trong trình đơn và/hoặc giá tuỳ chỉnh đã thay đổi. Giỏ hàng được chỉnh sửa không còn đáp ứng yêu cầu về giá trị đơn đặt hàng tối thiểu Trả lại FoodErrorExtension bằng FoodOrderError loại lỗi PRICE_CHANGEDREQUIREMENTS_NOT_MET.

JSON

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "error": {
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
              "foodOrderErrors": [
                {
                  "error": "AVAILABILITY_CHANGED",
                  "id": "sample_item_offer_id_1",
                  "description": "The item is no longer available."
                },
                {
                  "error": "AVAILABILITY_CHANGED",
                  "id": "sample_item_offer_id_2",
                  "description": "The item is no longer available."
                }
              ],
              "correctedProposedOrder": {
                "id": "sample_corrected_proposed_order_id_1",
                "otherItems": [
                  {
                    "name":"New customer discount",
                    "price": {
                      "type":"ESTIMATE",
                      "amount": {
                        "currencyCode":"USD",
                        "units":"-5",
                        "nanos": -500000000
                      }
                    },
                    "type": "DISCOUNT"
                  },
                  {
                    "name": "Delivery fee",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD",
                        "units": "3",
                        "nanos": 500000000
                      }
                    },
                    "type": "DELIVERY"
                  },
                  {
                    "name": "Tax",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD",
                        "units": "1",
                        "nanos": 500000000
                      }
                    },
                    "type": "TAX"
                  }
                ],
                "cart": {
                  "merchant": {
                    "id": "https://www.exampleprovider.com/merchant/id1",
                    "name": "Falafel Bite"
                  },
                  "lineItems": [
                    {
                      "name": "Greek Salad",
                      "type": "REGULAR",
                      "id": "sample_item_offer_id_3",
                      "offerId": "https://www.exampleprovider.com/menu/item/offer/id3",
                      "quantity": 1,
                      "price": {
                        "type": "ESTIMATE",
                        "amount": {
                          "currencyCode": "USD",
                          "units": "9",
                          "nanos": 990000000
                        }
                      },
                      "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                      }
                    },
                    {
                      "name": "Prawns Biryani",
                      "type": "REGULAR",
                      "id": "sample_item_offer_id_4",
                      "offerId": "https://www.exampleprovider.com/menu/item/offer/id4",
                      "quantity": 1,
                      "price": {
                        "type": "ESTIMATE",
                        "amount": {
                          "currencyCode": "USD",
                          "units": "15",
                          "nanos": 990000000
                        }
                      },
                      "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                      }
                    }
                  ],
                  "extension": {
                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
                    "fulfillmentPreference": {
                      "fulfillmentInfo": {
                        "delivery": {
                          "deliveryTimeIso8601": "P90M"
                        }
                      }
                    },
                    "location": {
                      "coordinates": {
                        "latitude": 37.788783,
                        "longitude": -122.41384
                      },
                      "formattedAddress": "1350 CHARLESTON ROAD, MOUNTAIN VIEW, CA, United States",
                      "zipCode": "94043",
                      "city": "Mountain View",
                      "postalAddress": {
                        "regionCode": "US",
                        "postalCode": "94043",
                        "administrativeArea": "CA",
                        "locality": "Mountain View",
                        "addressLines": [
                          "1350 Charleston Road"
                        ]
                      },
                      "notes": "Gate code is #111"
                     }
                   }
                },
                "totalPrice": {
                  "type": "ESTIMATE",
                  "amount": {
                    "currencyCode": "USD",
                    "units": "36",
                    "nanos": 730000000
                  }
                },
                "extension": {
                  "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension",
                  "availableFulfillmentOptions": [
                    {
                      "fulfillmentInfo": {
                        "delivery": {
                          "deliveryTimeIso8601": "P90M"
                        }
                      },
                      "expiresAt": "2017-07-17T12:30:00Z"
                    }
                  ]
                }
              },
              "paymentOptions": {
                "googleProvidedOptions": {
                  "tokenizationParameters": {
                    "tokenizationType": "PAYMENT_GATEWAY",
                    "parameters": {
                      "gateway": "stripe",
                      "stripe:publishableKey": "pk_live_stripe_client_key",
                      "stripe:version": "2017-04-06"
                    }
                  },
                  "supportedCardNetworks": [
                    "AMEX",
                    "DISCOVER",
                    "MASTERCARD",
                    "JCB",
                    "VISA"
                  ],
                  "prepaidCardDisallowed": true
                }
              }
            }
          }
        }
      ]
    }
  }
}

JSON

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "error": {
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
              "foodOrderErrors": [
                {
                  "error": "REQUIREMENTS_NOT_MET",
                  "description": "The cart subtotal must be over $20."
                },
                {
                  "error": "AVAILABILITY_CHANGED",
                  "id": "cart_lineitem_id"
                  "description": "cart_lineitem_id is no longer available."
                }
              ]
            }
          }
        }
      ]
    }
  }
}

JSON

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "error": {
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
              "foodOrderErrors": [
                {
                  "error": "PRICE_CHANGED",
                  "id": "sample_item_offer_id_1",
                  "description": "The price has changed.",
                  "updatedPrice": {
                    "currencyCode": "USD",
                    "units": "2",
                    "nanos": 750000000
                  }
                },
                {
                  "error": "PRICE_CHANGED",
                  "id": "sample_item_offer_id_2",
                  "description": "The price has changed.",
                  "updatedPrice": {
                    "currencyCode": "USD",
                    "units": "8"
                  }
                }
              ],
              "correctedProposedOrder": {
                "id": "sample_corrected_proposed_order_id_1",
                "otherItems": [
                  {
                    "name":"New customer discount",
                    "price": {
                      "type":"ESTIMATE",
                      "amount": {
                        "currencyCode":"USD",
                        "units":"-5",
                        "nanos": -500000000
                      }
                    },
                    "type": "DISCOUNT"
                  },
                  {
                    "name": "Delivery fee",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD",
                        "units": "3",
                        "nanos": 500000000
                      }
                    },
                    "type": "DELIVERY"
                  },
                  {
                    "name": "Tax",
                    "price": {
                      "type": "ESTIMATE",
                      "amount": {
                        "currencyCode": "USD",
                        "units": "1",
                        "nanos": 500000000
                      }
                    },
                    "type": "TAX"
                  }
                ],
                "cart": {
                  "merchant": {
                    "id": "https://www.exampleprovider.com/merchant/id1",
                    "name": "Falafel Bite"
                  },
                  "lineItems": [
                    {
                      "name": "Pita Chips",
                      "type": "REGULAR",
                      "id": "sample_item_offer_id_1",
                      "offerId": "https://www.exampleprovider.com/menu/item/offer/id1",
                      "quantity": 1,
                      "price": {
                        "type": "ESTIMATE",
                        "amount": {
                          "currencyCode": "USD",
                          "units": "2",
                          "nanos": 750000000
                        }
                      },
                      "subLines": [
                        {
                          "note": "Notes for this item."
                        }
                      ],
                      "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension",
                        "options": [
                          {
                            "id": "sample_addon_offer_id_1",
                            "offerId": "https://www.exampleprovider.com/menu/item/addon/offer/id1",
                            "name": "Honey Mustard",
                            "price": {
                              "currencyCode": "USD"
                            },
                            "quantity": 1
                          },
                          {
                            "id": "sample_addon_offer_id_2",
                            "offerId": "https://www.exampleprovider.com/menu/item/addon/offer/id2",
                            "name": "BBQ Sauce",
                            "price": {
                              "currencyCode": "USD",
                              "nanos": 500000000
                            },
                            "quantity": 1
                          }
                        ]
                      }
                    },
                    {
                      "name": "Chicken Shwarma Wrap",
                      "type": "REGULAR",
                      "id": "sample_item_offer_id_2",
                      "offerId": "https://www.exampleprovider.com/menu/item/offer/id2",
                      "quantity": 1,
                      "price": {
                        "type": "ESTIMATE",
                        "amount": {
                          "currencyCode": "USD",
                          "units": "8"
                        }
                      },
                      "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                      }
                    },
                    {
                      "name": "Greek Salad",
                      "type": "REGULAR",
                      "id": "sample_item_offer_id_3",
                      "offerId": "https://www.exampleprovider.com/menu/item/offer/id3",
                      "quantity": 1,
                      "price": {
                        "type": "ESTIMATE",
                        "amount": {
                          "currencyCode": "USD",
                          "units": "9",
                          "nanos": 990000000
                        }
                      },
                      "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                      }
                    },
                    {
                      "name": "Prawns Biryani",
                      "type": "REGULAR",
                      "id": "sample_item_offer_id_4",
                      "offerId": "https://www.exampleprovider.com/menu/item/offer/id4",
                      "quantity": 1,
                      "price": {
                        "type": "ESTIMATE",
                        "amount": {
                          "currencyCode": "USD",
                          "units": "15",
                          "nanos": 990000000
                        }
                      },
                      "extension": {
                        "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension"
                      }
                    }
                  ],
                  "extension": {
                    "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension",
                    "fulfillmentPreference": {
                      "fulfillmentInfo": {
                        "delivery": {
                          "deliveryTimeIso8601": "P90M"
                        }
                      }
                    },
                    "location": {
                      "coordinates": {
                        "latitude": 37.788783,
                        "longitude": -122.41384
                      },
                      "formattedAddress": "1350 CHARLESTON ROAD, MOUNTAIN VIEW, CA, United States",
                      "zipCode": "94043",
                      "city": "Mountain View",
                      "postalAddress": {
                        "regionCode": "US",
                        "postalCode": "94043",
                        "administrativeArea": "CA",
                        "locality": "Mountain View",
                        "addressLines": [
                          "1350 Charleston Road"
                        ]
                      },
                      "notes": "Gate code is #111"
                     }
                   }
                },
                "totalPrice": {
                  "type": "ESTIMATE",
                  "amount": {
                    "currencyCode": "USD",
                    "units": "36",
                    "nanos": 730000000
                  }
                },
                "extension": {
                  "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension",
                  "availableFulfillmentOptions": [
                    {
                      "fulfillmentInfo": {
                        "delivery": {
                          "deliveryTimeIso8601": "P90M"
                        }
                      },
                      "expiresAt": "2017-07-17T12:30:00Z"
                    }
                  ]
                }
              },
              "paymentOptions": {
                "googleProvidedOptions": {
                  "tokenizationParameters": {
                    "tokenizationType": "PAYMENT_GATEWAY",
                    "parameters": {
                      "gateway": "stripe",
                      "stripe:publishableKey": "pk_live_stripe_client_key",
                      "stripe:version": "2017-04-06"
                    }
                  },
                  "supportedCardNetworks": [
                    "AMEX",
                    "DISCOVER",
                    "MASTERCARD",
                    "JCB",
                    "VISA"
                  ],
                  "prepaidCardDisallowed": true
                }
              }
            }
          }
        }
      ]
    }
  }
}

JSON

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "error": {
              "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension",
              "foodOrderErrors": [
                {
                  "error": "REQUIREMENTS_NOT_MET",
                  "description": "The cart subtotal must be over $20."
                },
                {
                  "error": "PRICE_CHANGED",
                  "id": "cart_lineitem_id"
                  "description": "cart_lineitem_id price has been updated."
                  "updatedPrice": {
                    "currencyCode": "USD",
                    "units": "2",
                    "nanos": 750000000
                  }
                }
              ]
            }
          }
        }
      ]
    }
  }
}

Gửi xác thực đơn đặt hàng

Như đã thảo luận trong Bước 7: Triển khai tính năng Gửi đơn đặt hàng, điểm cuối phương thức thực hiện sẽ thực hiện xác thực trên mọi thiết bị đến SubmitOrderRequestMessage rồi trả lời bằng SubmitOrderResponseMessage.

Dưới đây là ví dụ về SubmitOrderResponseMessage để thành công xác thực:

Trường hợp sử dụng Cách triển khai
Trường hợp sử dụng 1: Đã tạo thành công đơn đặt hàng Một SubmitOrderResponseMessage có đơn đặt hàng CREATED trạng thái. Tệp này phải có actionOrderId, userVisibleId, orderManagementActionsestimatedFulfillmentTime.
Trường hợp sử dụng 2: Đơn đặt hàng bị từ chối do vấn đề về thanh toán Một SubmitOrderResponseMessage có đơn đặt hàng REJECTED trạng thái. Tệp này phải có actionOrderId, userVisibleId, orderManagementActionsrejectionInfo thuộc loại PAYMENT_DECLINED.
Trường hợp sử dụng 3: Đơn đặt hàng bị từ chối do người dùng bị gắn cờ là bị cấm Một SubmitOrderResponseMessage có đơn đặt hàng REJECTED trạng thái. Tệp này phải có actionOrderId, userVisibleId, orderManagementActionsrejectionInfo thuộc loại INELIGIBLE.
Trường hợp sử dụng 4: Đơn đặt hàng bị từ chối vì thông tin người dùng không đầy đủ hoặc không hợp lệ Một SubmitOrderResponseMessage có đơn đặt hàng REJECTED trạng thái. Tệp này phải có actionOrderId, userVisibleId, orderManagementActionsrejectionInfo thuộc loại INELIGIBLE.
Trường hợp sử dụng 5: Đơn đặt hàng bị từ chối vì lý do không xác định Một SubmitOrderResponseMessage có đơn đặt hàng REJECTED trạng thái. Tệp này phải có actionOrderId, userVisibleId, orderManagementActionsrejectionInfo thuộc loại UNKNOWN.

JSON

{
  "expectUserResponse": false,
  "finalResponse": {
    "richResponse": {
      "items": [
        {
          "structuredResponse": {
            "orderUpdate": {
              "actionOrderId": "sample_action_order_id",
              "orderState": {
                "state": "CREATED",
                "label": "Order received"
              },
              "updateTime": "2017-05-10T02:30:00.000Z",
              "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"
                    }
                  }
                }
              ]
            }
          }
        }
      ]
    }
  }
}

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

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": "INELIGIBLE",
                 "reason": "Sorry, we are not able to take orders from this user"
              },
              "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"
                    }
                  }
                }
              ]
            }
          }
        }
      ]
    }
  }
}

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": "INELIGIBLE",
                 "reason": "Sorry, the phone number must not be blank"
              },
              "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"
                    }
                  }
                }
              ]
            }
          }
        }
      ]
    }
  }
}

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": "UNKNOWN",
                 "reason": "Sorry, there is something wrong with this order."
              },
              "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"
                    }
                  }
                }
              ]
            }
          }
        }
      ]
    }
  }
}