系统会在用户创建购物车时调用结账流程。该 用户的购物车以及订单详情会发送到您的端到端下单网站 服务。您的网络服务会验证此信息,然后您就可以 您可以继续进行交易,也可以根据需要调整购物车中的商品。
网络服务的结账处理程序必须响应 POST 请求。当
当客户选择结账时,Google 会将订单端到端网络服务
采用 CheckoutRequestMessage
形式的 JSON 请求正文,其中包含
客户Cart
的详细信息。您的网络服务随后会返回
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
需要包含
ProposedOrder
和
PaymentOptions
:
ProposedOrder
cart
:与以下字段中提供的购物车完全相同的cart
对象:CheckoutRequestMessage
。如果购物车内的任何内容CheckoutResponseMessage
应改为包含一个FoodErrorExtension
已更正ProposedOrder
。otherItems
:提供商添加的商品,例如运费、 税费和其他费用。可能还包含用户支付的小费。totalPrice
:订单的总价格。extension
:用于定义履单信息的FoodOrderExtension
例如送货时间
PaymentOptions
- 后文中的设置 Google
Pay。
您可以在
CheckoutResponseMessage
中使用占位符 JSON,直到 准备实施付款处理。 - 如需在您的
CheckoutResponseMessage
中添加占位付款方式,请执行以下操作: 请参阅下面的示例,其中使用了PaymentOptions
的支付网关示例。
- 后文中的设置 Google
Pay。
您可以在
成功响应示例
{
"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 找到。这些错误无法恢复,因此遇到的第一个错误应该 返回。有关以下内容的说明,请参阅处理错误: 可恢复的错误。
- 阅读 FulfillmentOptionInfo 属性,
请求,以确定执行方式类型是针对
delivery
还是pickup
。 如果需要,返回以下错误类型:
错误类型 使用场景 无效 履单类型无效。 NOT_FOUND 找不到履单类型。 已解决 - 订单没有 OperationHours 时段。
- 订单为“尽快”订单,且当前时间没有“尽快”ServiceHours 可用。
- 发生紧急封闭或
isDisabled
服务为 true。
UNAVAILABLE_SLOT 无法提前履行订单。 NO_CAPACITY 餐馆很忙,目前没有接受订单。 OUT_OF_SERVICE_AREA 订单无法送至用户的地址。有关示例,请参阅送货地址验证。 NO_COURIER_AVAILABLE 由于配送人员有限,订单无法配送。
验证购物车并为其定价
查找每个 Cart.
lineItems
并使用以下内容中的当前数据进行验证: 您的系统或商家的系统中。通过 包含 Feed 实体中的 MenuItemOffer.sku
值 作为 LineItem.offerId
。创建 FoodOrderError。创建 每个商品最多出现一个错误。如果存在以下情况,则返回以下错误类型: 所需内容:错误类型 使用场景 可恢复 无效 商品数据或任何选项数据无效。 否 NOT_FOUND 未找到商品或任何选项。 否 PRICE_CHANGED 商品或附加服务组合的价格已更改。可以将此错误视为可恢复错误。 是 AVAILABILITY_CHANGED 无法提供为订单项请求的金额或任何选项。 是 REQUIREMENTS_NOT_MET 未达到最低订餐额要求。可通过查看购物车价格是低于费用 eligibleTransactionVolumeMin
还是高于费用eligibleTransactionVolumeMax
来确定。请参阅最低订单金额验证中的示例。否 返回具有 LineItemType 的经过验证的订单项列表
REGULAR
。所有购物车订单项价格的总和为购物车价格或SUBTOTAL
。
请参阅购物车商品验证中的示例。
计算服务费
- 根据
eligibleRegion
、validFrom
、validThrough
和priority
。 - 根据实体是否使用
price
定义计算费用金额,percentageOfCart
或pricePerMeter
属性。 - 将配送或外卖服务费作为 LineItem 返回,
LineItemType
DELIVERY
或FEE
。添加费用 进入购物车.otherItems
列表。
使用促销优惠
- 根据
促销.
coupon
值替换为特惠。dealCode
。 验证交易并返回 FoodOrderError(如果需要)。 这些错误可被视为可恢复。返回以下错误类型 (如果需要的话):
错误类型 使用场景 PROMO_NOT_RECOGNIZED 无法识别优惠券代码。 PROMO_EXPIRED 此交易已过期。 PROMO_ORDER_INELIGIBLE 该订单不符合使用优惠券的条件。 PROMO_NOT_APPLICABLE 任何其他原因。 根据交易价格的总金额,使用购物车总金额或费用总额来应用交易价格金额 交易。
dealType
。返回应用了促销优惠的购物车.
promotions
。将促销信息作为 LineItem 返回, LineItemType
DISCOUNT
。将折扣添加到 购物车.otherItems
列表中包含负价格。
返回响应
- 创建 ProposedOrder.
cart
,响应购物车即为 如果在验证过程中未遇到任何错误,则与请求购物车相同。 - 返回 ProposedOrder.
otherItems
列表,其中包含 税费、费用、小费和折扣(如果适用)。请参阅免费赠送 有关如何配置小费商品的详细信息。 - 通过添加购物车添加 ProposedOrder.
totalPrice
价格、费用、折扣、税费和小费。 - 返回
FoodOrderExtension.
availableFulfillmentOptions
替换为 相应的 FulfillmentOption。更新估算数据 提货或送货时间。 - 如果之前的验证检查生成了 FoodOrderErrors:
<ph type="x-smartling-placeholder">
- </ph>
- 包含 StructuredResponse.
error
和 FoodErrorExtension.foodOrderErrors
中出现了错误。 - 在系统返回 ProposedOrder
correctedProposedOrder
字段(如果所有错误都可以恢复)。 - 在
paymentOptions
中返回 PaymentOptions 字段。 - (可选)如果有其他内容,请添加
additionalPaymentOptions
可用的付款方式,并且所有错误均可恢复。
- 包含 StructuredResponse.
- 如果没有验证错误,则返回
proposedOrder
。 CheckoutResponse 对象中的paymentOptions
。 (可选)如果有其他内容,请添加additionalPaymentOptions
可用的付款方式。