プロモーションを使用すると、飲食店と Google が協力して、割引価格で食事注文サービスを試すようユーザーに働きかけることができます。Google は、Ordering End-to-End Actions とプロモーション管理システムの統合をサポートしています。
次の種類の割引がサポートされています。
- Google がスポンサーとなるプロモーション コード: Google によって自動的に事前入力されるか、ユーザーが入力するプロモーション コード。
- サードパーティがスポンサーとなるプロモーション コード: ユーザーが入力するプロモーション コード。フード注文サービスから提供されます。
- 第三者スポンサーの自動割引: プロモーション コードなしで、フード注文サービスが自動的に適用する割引。
割引の種類にかかわらず、Google はデリバリー&テイクアウトのフルフィルメントに決済呼び出しを行い、割引を確認して適用します。
フード注文サービスのデベロッパーは、有効なプロモーション コードの割引を計算したり、無効なプロモーション コードのエラーを送信したり、プロモーション コードの利用制限を管理したり、返金の財務データを追跡したりするために、実装に変更を加える必要があります。
プロモーションを処理する方法
プロモーションをサポートするフルフィルメントを実装する手順は次のとおりです。
- プロモーションの統合を設定します。(Google がスポンサーとなっているプロモーション コードを使用していない場合は、この手順をスキップしてください)。
- プロモーション付きの購入手続きを実装する。
- プロモーション付きの注文送信を実装。
プロモーションの統合を設定する
このセクションでは、Google がスポンサーとなるプロモーション コードを使用する場合に、プロモーションの統合を設定する方法について説明します。サードパーティがスポンサーとなるプロモーション コードや割引のみをサポートする場合は、独自の設定を指定して、このセクションをスキップできます。
Google がスポンサーとなるプロモーションの種類を指定し、統合の設定についてご連絡いたします。以下の情報を提供します。
- 割引額。
- カートの最小金額。
- プロモーション コードの使用開始日と終了日。
- プロモーション キャンペーンに設定された最大予算額(米ドル)。
- プロモーション コードを利用できる回数。
プロモーション コードの例:
FopaNewUser
: 10%(固定の割合)で、最大 $50 オフ。FopaMoreThan50
: 10 ドル(固定額の割引)。
Google がコードの適用を停止する場合は、お客様に連絡いたします。
支払いを設定する
支払いプロセスを設定するには、Google EAP コンサルタントにお問い合わせください。Google がスポンサーとなるプロモーション コードを含む取引の払い戻しは、最終的な注文ステータスが次のいずれかである場合にのみ行われます。
CONFIRMED
IN_TRANSIT
READY_FOR_PICKUP
IN_PREPARATION
FULFILLED
プロモーション付きの購入手続きを実装する
このセクションでは、プロモーション コード(Google がスポンサーまたは第三者がスポンサー)をサポートする場合の購入手続きの処理の実装について説明します。サードパーティがスポンサーとなる自動割引の場合は、CheckoutResponseMessage
で割引の行アイテムを返すだけで済みます(プロモーション コードの確認は不要です)。
フード注文のフルフィルメント中に、Google から CheckoutRequestMessage
に 1 つのプロモーション コードが送信されます。ユーザーは、購入手続きのリクエストを繰り返す際にカートやプロモーション コードを変更することがあります。
お客様がプロモーション コードを初めて適用したかどうかを確認するには、次の手順を行います。
- Google がスポンサーとなるプロモーション コード: リピーターが同じプロモーション コードを再度使用しようとしているかどうかは Google が確認します。ショップ側で何もする必要はありません。
- サードパーティがスポンサーとなるプロモーション コードまたは自動割引: アカウントのリンクとユーザーのオプトインを実装していない場合、購入手続きのリクエスト処理中にユーザーの詳細を確認できません。代わりに、
SubmitOrderRequestMessage
処理中に、FoodCartExtension
オブジェクトのContact
の詳細(ユーザーのメールアドレスなど)を使用して、このことを確認します。
最新の購入手続きリクエストに基づいて、エラーを特定したり、フルフィルメントで割引を計算したりします。状態情報を古いままにしておかないでください。
プロモーション コードの有効性を確認する
フルフィルメントでは、特定のプロモーション コードの有効性または利用資格を、規定の利用規約(有効期限、利用上限、最大割引額など)と照らし合わせて確認する必要があります。次に、計算された割引を CheckoutResponseMessage
で適切に返すか、プロモーション コードを適用できない場合は foodOrderErrors
で返します。プロモーション コードにエラーが検出された場合は、プロモーションのエラーを処理するに記載されているプロセスに沿って対応します。
次のスニペットは、プロモーション コードの foodOrderErrors
の例を示しています。correctedProposedOrder
にプロモーション ノードが含まれていないことを確認します。
"foodOrderErrors": [
{
"error": "PROMO_NOT_APPLICABLE",
// Copy promotions.coupon string from CheckoutRequest as the ID
"id": "GoogleNewUser",
"description": "Promotion could not be applied"
}
],
"correctedProposedOrder": {// required ...},
"paymentOptions": {// required ...}
コンピューティング割引
プロモーション コードが有効な場合、フルフィルメントは割引額を計算し、計算された割引額を otherItems
配列に含めて CheckoutResponseMessage
を返します。注文の合計金額は負の値にすることはできません。割引額がカート内の金額を超える場合は、注文合計金額を $0 にするために最大金額を返します。
次のスニペットは、プロモーション割引の CheckoutResponseMessage
セクションの例を示しています。
"proposedOrder": {
"otherItems": [
. . .
{
"name": "Discount",
// copy promotions.coupon field from CheckoutRequest as the id
"id": "GoogleNewUser",
"price": {
"type": "ESTIMATE",
"amount": {
"currencyCode": "USD",
"units": "-3",
"nanos": -500000000
}
},
"type": "DISCOUNT",
}
]
}
未使用のプロモーションを解放する
すべての購入手続きリクエストが注文送信リクエストにつながるわけではありません。フルフィルメントが購入手続きの呼び出し時にプロモーションを保留する場合は、一定の時間が経過しても注文の送信でプロモーションが利用されていない場合に、保留を解除するメカニズムを確立してください。これにより、フード注文サービスで正しいキャンペーン割り当てが維持されます。
プロモーションのエラーを処理する
フルフィルメントで CheckoutRequestMessage
のプロモーション コードが有効でないと判断された場合(有効期限が切れている、無効である、認識されないなど)、該当するエラーコードと理由のテキストを含む foodOrderError
と、correctedProposedOrder
オブジェクトと paymentOptions
オブジェクトを含む CheckoutResponseMessage
を送信します。
フルフィルメントで同じリクエストから複数のプロモーション コード エラーが検出された場合は、復元可能なエラーを送信する前に、復元不可能なエラーを送信します。チェックの優先度を次のように設定します(優先度が高い順に)。
PROMO_NOT_RECOGNIZED
PROMO_EXPIRED
PROMO_USER_INELIGIBLE
PROMO_ORDER_INELIGIBLE
PROMO_NOT_APPLICABLE
例
プロモーション コードを含む購入手続きリクエストの例を次に示します。
{ "accessToken": "test_access_token", "lastSeen": "2018-06-22T19:25:39Z" }, "conversation": { "conversationId": "XYZ" }, "inputs": [ { "intent": "actions.foodordering.intent.CHECKOUT", "arguments": [ { "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.Cart", "merchant": { "id": "https://www.exampleprovider.com/merchant/id1", "name": "Falafel Bite" }, "lineItems": [ { "name": "Falafel Tray", "type": "REGULAR", "id": "sample_item_offer_id_1", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "9", "nanos": 950000000 } }, "offerId": "https://www.exampleprovider.com/menu/item/offer/id1", "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } } ], "promotions": [ { "coupon": "FOPAACTIVECODE" } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension", "fulfillmentPreference": { "fulfillmentInfo": { "pickup": { "pickupTimeIso8601": "P0M" } } } } } } ] } ], "directActionOnly": true, "isInSandbox": true }
プロモーション コードが有効な場合、フルフィルメントからの対応する購入手続きレスポンスは次のとおりです。
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "checkoutResponse": { "proposedOrder": { "otherItems": [ { "name": "Delivery Fees", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "3", "nanos": 500000000 } }, "type": "DELIVERY" }, { "name": "Tax", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "1", "nanos": 370000000 } }, "type": "TAX" }, { "name": "Promotion", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "-5", "nanos": 0 } }, "id": "FOPAACTIVECODE", "type": "DISCOUNT" } ], "cart": { "merchant": { "id": "https://www.exampleprovider.com/merchant/id1", "name": "Falafel Bite" }, "lineItems": [ { "name": "Falafel Tray", "type": "REGULAR", "id": "2529103", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "9", "nanos": 950000000 } }, "offerId": "https://www.exampleprovider.com/menu/item/offer/id1", "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } } ], "promotions": [ { "coupon": "FOPAACTIVECODE" } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension", "fulfillmentPreference": { "fulfillmentInfo": { "pickup": { "pickupTimeIso8601": "P0M" } } } } }, "totalPrice": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "9", "nanos": 820000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension", "availableFulfillmentOptions": [ { "fulfillmentInfo": { "pickup": { "pickupTimeIso8601": "P0M" } }, "expiresAt": "2018-06-22T19:30:52.596Z" } ] } }, "orderOptions": {}, "paymentOptions": { "googleProvidedOptions": { "tokenizationParameters": { "tokenizationType": "PAYMENT_GATEWAY", "parameters": { "gateway": "stripe", "stripe:publishableKey": "example_stripe_client_key", "stripe:version": "2017-04-06" } }, "supportedCardNetworks": [ "AMEX", "DISCOVER", "MASTERCARD", "VISA", "JCB" ], "prepaidCardDisallowed": true } } } } } ], "suggestions": [] } } }
プロモーション コードが無効な場合の購入手続きのレスポンスの例を次に示します。
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "error": { "foodOrderErrors": [ { "error": "PROMO_NOT_RECOGNIZED", "id": "SOMEPROMO", "description": "Coupon not found" } ], "correctedProposedOrder": { "cart": { "merchant": { "id": "https://www.exampleprovider.com/merchant/id1", "name": "Falafel Bite" }, "lineItems": [ { "id": "sample_item_offer_id_4", "name": "Prawns Biryani", "type": "REGULAR", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "18", "nanos": 750000000 } }, "offerId": "https://www.exampleprovider.com/menu/item/offer/id4", "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } } ], "extension": { "fulfillmentPreference": { "fulfillmentInfo": { "pickup": { "pickupTimeIso8601": "P0M" } } }, "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension" }, "promotions": [] }, "otherItems": [ { "name": "Tax", "type": "TAX", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "1", "nanos": 650000000 } } } ], "termsOfServiceUrl": "https://exampleprovider.com/terms", "totalPrice": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "20", "nanos": 400000000 } }, "extension": { "availableFulfillmentOptions": [ { "fulfillmentInfo": { "pickup": { "pickupTimeIso8601": "PT0M" } } } ], "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension" } }, "paymentOptions": { "googleProvidedOptions": { "prepaidCardDisallowed": false, "billingAddressRequired": true, "tokenizationParameters": { "tokenizationType": "PAYMENT_GATEWAY", "parameters": { "gateway": "braintree", "braintree:apiVersion": "v1", "braintree:sdkVersion": "1.4.0", "braintree:merchantId": "example_braintree_merchant_ID", "braintree:clientKey": "example_braintree_client_key", "braintree:authorizationFingerprint": "example_braintree_fingerprint" } } } }, "@type": "type.googleapis.com/google.actions.v2.orders.FoodErrorExtension" } } } ] } } }
プロモーション付きの注文送信を実装する
注文フルフィルメントの送信で、ユーザーがプロモーション コードを初めて適用しているかどうかを確認します。SubmitOrderRequestMessage
の処理中に、FoodCartExtension
オブジェクトの Contact
の詳細(ユーザーのメールアドレスなど)を使用して、このことを確認できます。
また、プロモーション コードの適用可能性も再度確認する必要があります。
- コードが適用される場合: 注文を確認し、クーポンが利用済みであることをマークします。
- コードが適用されなくなった場合:
PROMO_NOT_APPLICABLE
エラーで注文を拒否します。FoodOrderUpdateExtension
の場合と同じメカニズムを使用して、特定の不承認理由を指定できます。
例
プロモーションを使用した注文送信リクエストの例を次に示します。
{ "conversation": { "conversationId": "example_conversation_ID" }, "inputs": [ { "intent": "actions.intent.TRANSACTION_DECISION", "arguments": [ { "transactionDecisionValue": { "order": { "finalOrder": { "cart": { "merchant": { "id": "https://www.exampleprovider.com/merchant/id1", "name": "Falafel Bite" }, "lineItems": [ { "name": "Falafel Tray", "type": "REGULAR", "id": "sample_item_offer_id_1", "quantity": 1, "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "9", "nanos": 950000000 } }, "offerId": "https://www.exampleprovider.com/menu/item/addon/offer/id1", "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodItemExtension" } } ], "promotions": [ { "coupon": "FOPAACTIVECODE" } ], "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodCartExtension", "fulfillmentPreference": { "fulfillmentInfo": { "pickup": { "pickupTimeIso8601": "P0M" } } }, "contact": { "displayName": "Food Ordering", "email": "example.provider@gmail.com", "phoneNumber": "+19993334444", "firstName": "Food", "lastName": "Ordering" } } }, "otherItems": [ { "name": "Delivery Fees", "type": "DELIVERY", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "3", "nanos": 500000000 } } }, { "name": "Tax", "type": "TAX", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "1", "nanos": 370000000 } } }, { "name": "Promotion", "type": "DISCOUNT", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "-5" } }, "id": "FOPAACTIVECODE" }, { "name": "Subtotal", "type": "SUBTOTAL", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "9", "nanos": 950000000 } } }, { "name": "Tip", "type": "GRATUITY", "price": { "type": "ESTIMATE", "amount": { "currencyCode": "USD" } } } ], "totalPrice": { "type": "ESTIMATE", "amount": { "currencyCode": "USD", "units": "9", "nanos": 820000000 } }, "extension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderExtension" } }, "googleOrderId": "example_google_order_ID", "orderDate": "2018-06-22T19:30:59.502Z", "paymentInfo": { "displayName": "example_display_name", "googleProvidedPaymentInstrument": { "instrumentToken": "example_instrument_token" }, "paymentType": "PAYMENT_CARD" }, "locale": "en" } } } ] } ], "directActionOnly": true, "isInSandbox": true }
プロモーション コードが有効な場合、フルフィルメントから送信された注文のレスポンスの例を次に示します。
{ "expectUserResponse": false, "finalResponse": { "richResponse": { "items": [ { "structuredResponse": { "orderUpdate": { "actionOrderId": "example_action_order_ID", "orderState": { "state": "CREATED", "label": "Order is created with partner." }, "updateTime": "2018-06-22T19:31:01.556Z", "orderManagementActions": [ { "type": "CALL_RESTAURANT", "button": { "title": "Call Us", "openUrlAction": { "url": "tel:+1-111-111-1111" } } }, { "type": "EMAIL", "button": { "title": "Email Us", "openUrlAction": { "url": "mailto:example.provider@gmail.com" } } }, { "type": "CUSTOMER_SERVICE", "button": { "title": "Customer Service", "openUrlAction": { "url": "http://www.google.com" } } } ] } } } ], "suggestions": [] } } }
プロモーション コードが無効な場合の注文送信レスポンスの例を次に示します。
"orderUpdate": { "actionOrderId": "sample_action_order_id", "orderState": { "state": "REJECTED", "label": "Order rejected." }, "updateTime": "2017-05-10T02:30:00.000Z", "rejectionInfo": { "type": "PROMO_NOT_APPLICABLE", "reason": "Sorry, there's something wrong. Try another code?" }, "orderManagementActions": [ { "type": "CUSTOMER_SERVICE", "button": { "title": "Contact customer service", "openUrlAction": { "url": "mailto:support@example.com" } } }, { "type": "EMAIL", "button": { "title": "Email restaurant", "openUrlAction": { "url": "mailto:example.provider@example.com" } } }, { "type": "CALL_RESTAURANT", "button": { "title": "Call restaurant", "openUrlAction": { "url": "tel:+19993334444" } } } ], "infoExtension": { "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension", "foodOrderErrors": [ { "error": "PROMO_USER_INELIGIBLE", "description": "Sorry, you can only use this promotion once." } ] } }