購入手続きを設定する

購入手続きは、ユーザーがカートを作成したときに呼び出されます。ユーザーのカートの中身と注文の詳細が、注文の End-to-End ウェブサービスに送信されます。この情報はウェブサービスによって検証され、必要に応じてカートの手続きを進めるか、調整を行うことができます。

ウェブサービスの購入手続きハンドラは、POST リクエストに応答する必要があります。お客様が購入手続きを選択すると、Google は Ordering End-to-End ウェブサービスに CheckoutRequestMessage 形式の JSON リクエスト本文を送信します。この本文には、お客様の Cart の詳細が含まれています。ウェブサービスは CheckoutResponseMessage で応答します。次の図は、このプロセスを表しています。

CheckoutResponseMessage は、お客様の変更されていないカートまたはエラーを返します。

購入手続きリクエストを受信すると、Ordering End-to-End ウェブサービスは次の処理を行う必要があります。

  • 商品の現在の価格、在庫状況、プロバイダのサービスに基づいて、カートの有効性を確認します。
  • 合計金額(割引、税金、配送料を含む)を計算します。
  • 成功した場合は、変更されていないカートで応答します。
  • 失敗した場合は、エラー メッセージと新しい注文案を返信します。

購入手続きの実装を開始する前に、フルフィルメントの概要のドキュメントを確認することをおすすめします。

購入手続きリクエスト メッセージ

お客様が購入手続きを選択すると、Google はお客様のカートを検証するために、CheckoutRequestMessage 形式の JSON 本文を含むリクエストをウェブサービスに送信します。エンドツーエンドの注文フローの後半まで、お客様の注文は送信されません。

CheckoutRequestMessage に含まれるデータには次のものが含まれます。

  • インテント: すべての購入手続きリクエスト本文の inputs[0].intent フィールドには、actions.foodordering.intent.CHECKOUT 文字列値が含まれています。
  • カート: 購入手続きリクエストの inputs[0].arguments[0].extension フィールドには、お客様のカートを表す Cart オブジェクトが含まれています。
  • 宅配またはテイクアウト: Cart オブジェクトの拡張フィールドには、宅配またはテイクアウトのプロパティを指定する FoodCartExtension オブジェクトが含まれています。
    • 配送注文の場合、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: CheckoutRequestMessage で指定されたカートと同じ cart オブジェクト。カートのコンテンツを変更する必要がある場合は、CheckoutResponseMessage に修正済みの ProposedOrder を含む FoodErrorExtension を含める必要があります。
    • 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": []
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }
}

リクエストが失敗しました

購入手続きリクエストが失敗した場合は、CheckoutResponseMessageFoodErrorExtension を含める必要があります。これには、発生したエラーを説明する FoodOrderError アイテムのリストが含まれます。カート内の商品の価格変更など、注文に復元可能なエラーがある場合は、FoodErrorExtensioncorrectedProposedOrder を含める必要があります。

失敗したレスポンスの例

{
  "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 プロパティを読み取り、フルフィルメント タイプが deliverypickup かを判断します。
  2. 必要に応じて、次のエラータイプを返します。

    エラーのタイプ ユースケース
    INVALID フルフィルメントの種類が無効です。
    NOT_FOUND フルフィルメント タイプが見つかりません。
    クローズ
    • 注文のOperationHours ウィンドウがない。
    • 注文が ASAP 注文で、現在の時間帯に利用可能な ASAP ServiceHours がない。
    • 緊急事態による閉鎖が発生している、またはサービス isDisabled が true である。
    なお、特別なウィンドウは通常のウィンドウよりも優先されます。注文期間の検証サービス エンティティを一時的に削除するの例をご覧ください。
    UNAVAILABLE_SLOT 事前注文の時間帯を満たすことができない。
    NO_CAPACITY レストランは混み合っており、現在注文を受け付けていません。
    OUT_OF_SERVICE_AREA お客様の住所に注文を配送できません。例については、配送先住所の検証をご覧ください。
    NO_COURIER_AVAILABLE 配送人員が限られているため、注文品を配送できません。

カートを検証して価格を設定する

  1. カートを検索し、lineItemsシステムまたは販売者のシステムの現在のデータと照合します。フィード エンティティの MenuItemOffer.sku 値は、LineItem.offerId として含まれます。必要に応じて、広告申込情報ごとに FoodOrderError を作成します。アイテムごとに最大 1 つのエラーを作成します。必要に応じて、次のエラータイプを返します。

    エラーのタイプ ユースケース 回復できる
    INVALID 商品データまたはオプションデータのいずれかが無効です。 いいえ
    NOT_FOUND アイテムまたはオプションが見つからない。 いいえ
    PRICE_CHANGED 商品アイテムまたはアドオンの組み合わせの価格が変更されました。このエラーは復元可能と見なすことができます。 はい
    AVAILABILITY_CHANGED 広告申込情報またはオプションでリクエストされた金額を使用できません。 はい
    REQUIREMENTS_NOT_MET 注文の最小金額または最大金額を満たしていません。これは、カートの価格が Fee.eligibleTransactionVolumeMin を下回っているか、Fee.eligibleTransactionVolumeMax を上回っているかを確認することで判断できます。最低注文額の検証の例をご覧ください。 いいえ
  2. LineItemType REGULAR で検証済みの LineItem のリストを返します。カート内のすべての項目の価格の合計がカート価格(SUBTOTAL)です。

例については、カート内の商品の検証をご覧ください。

サービス料金を計算する

  1. eligibleRegionvalidFromvalidThroughpriority に基づいて、サービスに適した Fee エンティティを見つけます。
  2. エンティティが pricepercentageOfCart、または pricePerMeter プロパティで定義されているかどうかに基づいて、料金の金額を計算します。
  3. 宅配またはテイクアウトのサービス料金は、LineItemType がそれぞれ DELIVERY または FEELineItem として返します。カート otherItems リストに料金を追加します。

プロモーションの適用

  1. Promotion.coupon の値と Deal.dealCode の値を照合して、Deal エンティティを見つけます。
  2. 取引を検証し、必要に応じて FoodOrderError を返します。これらのエラーは回復可能なエラーとして扱うことができます。必要に応じて、次のエラータイプを返します。

    エラーのタイプ ユースケース
    PROMO_NOT_RECOGNIZED クーポンコードが認識されませんでした。
    PROMO_EXPIRED 取引の有効期限が切れています。
    PROMO_ORDER_INELIGIBLE 注文はクーポンの対象外です。
    PROMO_NOT_APPLICABLE その他の理由。
  3. Deal.discount または Deal.discountPercentage に基づいて取引価格の金額を計算します。

  4. 取引に応じて、カートの合計額または手数料の合計額を使用して、取引価格の金額を適用します。dealType

  5. プロモーションが適用された Cart.promotions を返します。

  6. プロモーションを LineItemType DISCOUNTLineItem として返します。割引を Cart.otherItems リストにマイナスの価格で追加します。

レスポンスを返す

  1. ProposedOrder を作成します。cart 検証中にエラーが発生しなかった場合、レスポンス カートの内容はリクエスト カートと同じになります。
  2. 税金、手数料、チップ、割引(適用される場合)を含む ProposedOrder.otherItems リストを返します。手当項目の設定方法の詳細については、手当をご覧ください。
  3. カートの価格、手数料、割引、税金、チップを追加して、ProposedOrder.totalPrice を含めます。
  4. それぞれの FulfillmentOption とともに FoodOrderExtension.availableFulfillmentOptions を返します。受け取りまたは配達の予定時刻を更新します。
  5. 前の検証チェックで生成された FoodOrderError がある場合:
    • StructuredResponse.error とエラーのリストを FoodErrorExtension.foodOrderErrors に含めます。
    • すべてのエラーが復元可能な場合は、correctedProposedOrder フィールドに ProposedOrder を返します。
    • すべてのエラーが復元可能な場合は、paymentOptions フィールドに PaymentOptions を返します。
    • 他の支払いオプションが利用可能で、すべてのエラーが復元可能な場合は、必要に応じて additionalPaymentOptions を含めます。
  6. 検証エラーがない場合、CheckoutResponse オブジェクトの proposedOrderpaymentOptions を返します。他の支払いオプションが利用可能な場合は、必要に応じて additionalPaymentOptions を含めます。