購入手続きを設定

ユーザーがカートを作成すると、購入手続きが呼び出されます。ユーザーのカートの内容と注文の詳細が注文エンドツーエンド ウェブサービスに送信されます。この情報はウェブサービスによって検証されると、続行するか、必要に応じてカートに調整を加えることができます。

ウェブサービスのチェックアウト ハンドラは、POST リクエストに応答する必要があります。お客様が購入手続きを選択すると、Google は注文エンドツーエンド ウェブサービスに、お客様の Cart の詳細を含む CheckoutRequestMessage 形式の JSON リクエストの本文を送信します。ウェブサービスから CheckoutResponseMessage が返されます。次の図は、このプロセスを示しています。

CheckoutResponseMessage は、顧客の未変更のカートまたはエラーを返します。

購入手続きリクエストを受け取ると、注文エンドツーエンド ウェブサービスは次のことを行う必要があります。

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

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

決済リクエスト メッセージ

お客様のカートを検証するために、ユーザーが購入手続きを選択すると、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
}

購入手続き応答メッセージ

Ordering End-to-End サービスからリクエストを受け取った後、購入手続きウェブサービスはそれを処理し、CheckoutResponseMessage で応答する必要があります。CheckoutResponseMessage は、成功したリクエストまたは失敗したリクエストのいずれかを網羅する必要があります。

リクエストが正常に完了しました

チェックアウト リクエストが成功した場合は、CheckoutResponseMessageProposedOrderPaymentOptions を含める必要があります。

  • ProposedOrder

    • cart: CheckoutRequestMessage で指定されたカートと同一の cart オブジェクト。カートの内容のいずれかを変更する必要がある場合は、代わりに CheckoutResponseMessageProposedOrder を修正した 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 アイテムのリストが含まれます。カート内の商品アイテムの価格変更など、注文に回復可能なエラーがある場合、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 プロパティを読み取り、フルフィルメント タイプが 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 で指定)を返します。カート項目のすべての価格の合計が、カート価格または SUBTOTAL です。

カートの商品アイテムの検証の例をご覧ください。

サービス手数料を計算する

  1. eligibleRegionvalidFromvalidThroughpriority に基づいて、サービスの正しい Fee エンティティを見つけます。
  2. エンティティが pricepercentageOfCart、または pricePerMeter プロパティで定義されているかどうかに基づいて、料金を計算します。
  3. 宅配またはテイクアウトのサービス手数料は、それぞれ LineItem として LineItemTypeDELIVERY FEE として返します。料金を [Cart.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. プロモーションが適用されたカートpromotionsを返送します。

  6. プロモーションを LineItemType DISCOUNTLineItemとして返します。マイナスの値を指定して、カート.otherItems リストに割引を追加します。

レスポンスを返す

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