设置结账

系统会在用户创建购物车时调用结账流程。该 用户的购物车以及订单详情会发送到您的端到端下单网站 服务。您的网络服务会验证此信息,然后您就可以 您可以继续进行交易,也可以根据需要调整购物车中的商品。

网络服务的结账处理程序必须响应 POST 请求。当 当客户选择结账时,Google 会将订单端到端网络服务 采用 CheckoutRequestMessage 形式的 JSON 请求正文,其中包含 客户Cart的详细信息。您的网络服务随后会返回 CheckoutResponseMessage。下图演示了该过程。

CheckoutResponseMessage 返回客户未经修改的购物车或
错误。

收到结账请求后,您的端到端订购网络服务必须 以下:

  • 请根据当前商品价格、库存状况 和提供程序服务。
  • 计算总价(包括所有折扣、税费和运费) 费用)。
  • 如果成功,则返回未经修改的购物车。
  • 如果操作不成功,请回复一条错误消息并提供新的建议订单。

在开始实现结账之前,我们建议您先查看 Fulfillment 概览 文档。

结账请求消息

为了验证客户的购物车,当客户选择结账时, Google 会向您的网络服务发送请求,其中包含 JSON 正文,格式为 CheckoutRequestMessage。客户订单要到稍后 端到端订购流程。

以下各项中包含的数据 CheckoutRequestMessage 包括:

  • 意图: inputs[0].intent 字段包含 actions.foodordering.intent.CHECKOUT 字符串值。
  • 购物车:结账请求的 inputs[0].arguments[0].extension 字段 包含一个表示客户购物车的 Cart 对象。
  • 送货或外带:Cart 对象的扩展字段包含 FoodCartExtension 对象,用于指定投放属性或 导出: <ph type="x-smartling-placeholder">
      </ph>
    • 对于送货订单,FoodCartExtension 对象包含 送货地址。
    • 对于自提或外卖订单,FoodCartExtension 对象不适用 包含任何位置信息。
  • 沙盒:结账请求的 isInSandbox 字段包含一个布尔值 值,用于指明交易是否使用沙盒付款。

结账请求示例

下面是一个 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
}

结账响应消息

收到端到端订购服务的请求后,您的结账网页 服务必须对其进行处理并返回 CheckoutResponseMessage。通过 CheckoutResponseMessage 需要涵盖成功或失败情况 请求。

请求成功

如果结账请求成功,CheckoutResponseMessage 需要包含 ProposedOrderPaymentOptions

  • ProposedOrder

    • cart:与以下字段中提供的购物车完全相同的 cart 对象: CheckoutRequestMessage。如果购物车内的任何内容 CheckoutResponseMessage 应改为包含一个 FoodErrorExtension 已更正 ProposedOrder
    • otherItems:提供商添加的商品,例如运费、 税费和其他费用。可能还包含用户支付的小费。
    • totalPrice:订单的总价格。
    • extension:用于定义履单信息的 FoodOrderExtension 例如送货时间
  • PaymentOptions

    • 后文中的设置 Google Pay。 您可以在 CheckoutResponseMessage 中使用占位符 JSON,直到 准备实施付款处理。
    • 如需在您的CheckoutResponseMessage中添加占位付款方式,请执行以下操作: 请参阅下面的示例,其中使用了 PaymentOptions 的支付网关示例。

成功响应示例

{
    "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": []
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }
}

请求失败

如果结账请求不成功,CheckoutResponseMessage需要 包括 FoodErrorExtension,它包含 FoodOrderError 来描述出现的所有错误。如有任何可恢复的 订单错误,如购物车中商品的价格变动、 FoodErrorExtension 必须包含 correctedProposedOrder

失败响应示例

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

结账流程实现

实现结账时应执行以下步骤。

验证服务

针对第一个服务错误情况返回 FoodOrderError 找到。这些错误无法恢复,因此遇到的第一个错误应该 返回。有关以下内容的说明,请参阅处理错误: 可恢复的错误。

  1. 阅读 FulfillmentOptionInfo 属性, 请求,以确定执行方式类型是针对 delivery 还是 pickup
  2. 如果需要,返回以下错误类型:

    错误类型 使用场景
    无效 履单类型无效。
    NOT_FOUND 找不到履单类型。
    已解决
    • 订单没有 OperationHours 时段。
    • 订单为“尽快”订单,且当前时间没有“尽快”ServiceHours 可用。
    • 发生紧急封闭或 isDisabled 服务为 true。
    请注意,特殊窗口的优先级高于常规窗口。请参阅订购期限验证中的示例和暂时移除服务实体
    UNAVAILABLE_SLOT 无法提前履行订单。
    NO_CAPACITY 餐馆很忙,目前没有接受订单。
    OUT_OF_SERVICE_AREA 订单无法送至用户的地址。有关示例,请参阅送货地址验证
    NO_COURIER_AVAILABLE 由于配送人员有限,订单无法配送。

验证购物车并为其定价

  1. 查找每个 Cart.lineItems 并使用以下内容中的当前数据进行验证: 您的系统或商家的系统中。通过 包含 Feed 实体中的 MenuItemOffer.sku 值 作为 LineItem.offerId。创建 FoodOrderError。创建 每个商品最多出现一个错误。如果存在以下情况,则返回以下错误类型: 所需内容:

    错误类型 使用场景 可恢复
    无效 商品数据或任何选项数据无效。
    NOT_FOUND 未找到商品或任何选项。
    PRICE_CHANGED 商品或附加服务组合的价格已更改。可以将此错误视为可恢复错误。
    AVAILABILITY_CHANGED 无法提供为订单项请求的金额或任何选项。
    REQUIREMENTS_NOT_MET 未达到最低订餐额要求。可通过查看购物车价格是低于费用eligibleTransactionVolumeMin还是高于费用eligibleTransactionVolumeMax来确定。请参阅最低订单金额验证中的示例。
  2. 返回具有 LineItemType 的经过验证的订单项列表 REGULAR。所有购物车订单项价格的总和为购物车价格或 SUBTOTAL

请参阅购物车商品验证中的示例。

计算服务费

  1. 根据 eligibleRegionvalidFromvalidThroughpriority
  2. 根据实体是否使用 price 定义计算费用金额, percentageOfCartpricePerMeter 属性。
  3. 将配送或外卖服务费作为 LineItem 返回, LineItemType DELIVERYFEE。添加费用 进入购物车.otherItems 列表。

使用促销优惠

  1. 根据 促销.coupon值替换为特惠dealCode
  2. 验证交易并返回 FoodOrderError(如果需要)。 这些错误可被视为可恢复。返回以下错误类型 (如果需要的话):

    错误类型 使用场景
    PROMO_NOT_RECOGNIZED 无法识别优惠券代码。
    PROMO_EXPIRED 此交易已过期。
    PROMO_ORDER_INELIGIBLE 该订单不符合使用优惠券的条件。
    PROMO_NOT_APPLICABLE 任何其他原因。
  3. 根据交易计算交易价格金额。discount交易discountPercentage

  4. 根据交易价格的总金额,使用购物车总金额或费用总额来应用交易价格金额 交易dealType

  5. 返回应用了促销优惠的购物车.promotions

  6. 将促销信息作为 LineItem 返回, LineItemType DISCOUNT。将折扣添加到 购物车.otherItems 列表中包含负价格。

返回响应

  1. 创建 ProposedOrder.cart,响应购物车即为 如果在验证过程中未遇到任何错误,则与请求购物车相同。
  2. 返回 ProposedOrder.otherItems 列表,其中包含 税费、费用、小费和折扣(如果适用)。请参阅免费赠送 有关如何配置小费商品的详细信息。
  3. 通过添加购物车添加 ProposedOrder.totalPrice 价格、费用、折扣、税费和小费。
  4. 返回 FoodOrderExtension.availableFulfillmentOptions 替换为 相应的 FulfillmentOption。更新估算数据 提货或送货时间。
  5. 如果之前的验证检查生成了 FoodOrderErrors: <ph type="x-smartling-placeholder">
      </ph>
    • 包含 StructuredResponse.errorFoodErrorExtension.foodOrderErrors 中出现了错误。
    • 在系统返回 ProposedOrder correctedProposedOrder 字段(如果所有错误都可以恢复)。
    • paymentOptions 中返回 PaymentOptions 字段。
    • (可选)如果有其他内容,请添加 additionalPaymentOptions 可用的付款方式,并且所有错误均可恢复。
  6. 如果没有验证错误,则返回 proposedOrderCheckoutResponse 对象中的 paymentOptions。 (可选)如果有其他内容,请添加 additionalPaymentOptions 可用的付款方式。