Promocje umożliwiają Ci i Google zachęcanie klientów do skorzystania z usługi zamawiania jedzenia z rabatem. Google obsługuje integrację działań typu end-to-end z systemem zarządzania promocjami.
Obsługiwane są te typy rabatów:
- Kody promocyjne sponsorowane przez Google: kody promocyjne automatycznie wypełniane przez Google lub wpisywane przez użytkowników.
- Kody promocyjne sponsorowane przez firmy zewnętrzne: kody promocyjne, które użytkownicy mogą wpisywać, udostępnione przez Twoją usługę zamawiania jedzenia.
- Automatyczne rabaty sponsorowane przez osoby trzecie: rabaty, które usługa zamawiania jedzenia automatycznie stosuje bez kodu promocyjnego.
Bez względu na rodzaj rabatu Google wysyła do Twojej firmy obsługującej zamawianie jedzenia zapytanie o płatność, aby zweryfikować rabat i go zastosować.
Jako twórca usługi zamawiania jedzenia musisz wprowadzić pewne zmiany w swojej implementacji, aby obliczyć rabaty dla prawidłowych kodów promocyjnych lub wysyłać błędy w przypadku nieprawidłowych kodów promocyjnych, zarządzać ograniczeniami w wykorzystywaniu kodów promocyjnych oraz śledzić dane księgowe na potrzeby zwrotu kosztów.
Jak przetwarzać promocje
Aby wdrożyć realizację, która obsługuje promocje:
- Skonfiguruj integrację promocji. (Pomiń ten krok, jeśli nie używasz kodów promocyjnych sponsorowanych przez Google).
- Wdróż proces płatności z promocjami.
- Wdróż przesyłanie zamówienia z promocjami.
Konfigurowanie integracji z promocjami
W tej sekcji opisaliśmy, jak skonfigurować integrację promocji, jeśli planujesz używać kodów promocyjnych sponsorowanych przez Google. Jeśli chcesz obsługiwać tylko kody promocyjne lub zniżki sponsorowane przez osoby trzecie, możesz określić własną konfigurację i pominąć tę sekcję.
Google określa typ promocji, którą chcesz sponsorować, i kontaktuje się z Tobą w celu skonfigurowania integracji. Udostępniamy te informacje:
- kwota rabatu,
- Minimalna wartość koszyka.
- Data rozpoczęcia i zakończenia korzystania z kodów promocyjnych.
- Maksymalna kwota budżetu przeznaczona na kampanię promocyjną.
- Określa, ile razy można wykorzystać kody promocyjne.
Przykłady kodów promocyjnych:
FopaNewUser
: 10% (stała wartość procentowa) z maksymalnym rabatem 50 zł.FopaMoreThan50
: 10 zł (stała kwota zniżki).
Jeśli Google zdecyduje się wstrzymać stosowanie kodu, skontaktujemy się z Tobą.
Konfigurowanie wypłat
Aby skonfigurować proces wypłaty, skontaktuj się z konsultantem Google EAP. Google zwraca środki za transakcje z użyciem kodów promocyjnych sponsorowanych przez Google tylko wtedy, gdy ostateczny stan zamówienia jest jeden z tych:
CONFIRMED
IN_TRANSIT
READY_FOR_PICKUP
IN_PREPARATION
FULFILLED
Wdrożenie płatności z promocjami
W tej sekcji opisano implementację przetwarzania płatności w przypadku obsługi kodów promocyjnych (sponsorowanych przez Google lub przez osoby trzecie). W przypadku automatycznych rabatów sponsorowanych przez strony trzecie wystarczy zwrócić pozycję linii rabatu w sekcji CheckoutResponseMessage
(nie trzeba sprawdzać kodu promocyjnego).
Podczas realizacji zamówienia na jedzenie Google wysyła do Twojego centrum obsługi klienta pojedynczy kod promocyjny w CheckoutRequestMessage
. Użytkownicy mogą zmieniać koszyk lub kod promocyjny podczas powtarzanych procesów płatności.
Aby sprawdzić, czy użytkownik po raz pierwszy stosuje kod promocyjny, wykonaj te czynności:
- Kody promocyjne sponsorowane przez Google: Google sprawdza, czy powracający użytkownik próbuje ponownie użyć tego samego kodu promocyjnego. Nie musisz nic robić.
- Kody promocyjne sponsorowane przez firmy zewnętrzne lub rabaty automatyczne: jeśli nie wdrożysz łączenia kont i zgód użytkowników, nie będziesz mieć możliwości sprawdzenia danych użytkownika podczas przetwarzania prośby o płatność. Zamiast tego sprawdź to podczas przetwarzania
SubmitOrderRequestMessage
, używając szczegółówContact
(takich jak adres e-mail użytkownika) z obiektuFoodCartExtension
.
Identyfikowanie błędów lub obliczanie rabatów w ramach realizacji na podstawie najnowszego żądania płatności. Pamiętaj, aby Twój system nie przechowywał nieaktualnych informacji o stanie.
Sprawdzanie ważności kodu promocyjnego
Proces realizacji powinien sprawdzać ważność lub kwalifikowanie się danego kodu promocyjnego na podstawie określonych warunków, takich jak data ważności, maksymalna liczba użyć i maksymalny rabat. Następnie odpowiedz odpowiednio w CheckoutResponseMessage
z obliczonym rabatem lub foodOrderErrors
, jeśli kod promocyjny nie może zostać zastosowany. Jeśli wykryjesz błędy związane z kodem promocyjnym, postępuj zgodnie z procesem opisanym w artykule Rozwiązywanie problemów z promocjami.
Poniższy fragment kodu pokazuje przykładowy kod foodOrderErrors
dla kodu promocyjnego.
Upewnij się, że element correctedProposedOrder
nie zawiera węzła promocji.
"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 ...}
Rabaty na moc obliczeniową
Jeśli kod promocyjny jest prawidłowy, Twoja usługa powinna obliczyć wartość rabatu w dolarach i przesłać z powrotem element CheckoutResponseMessage
z obliczoną wartością rabatu w tablicy otherItems
. Łączna cena zamówienia nie może być ujemna. Jeśli kwota rabatu przekracza kwotę koszyka, podaj maksymalną kwotę w dolarach, aby łączna cena zamówienia wynosiła 0 USD.
Ten fragment kodu pokazuje przykładową sekcję CheckoutResponseMessage
dotyczącą rabatu promocyjnego:
"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",
}
]
}
Zwalnianie nieużywanych promocji
Nie każda prośba o płatność prowadzi do przesłania zamówienia. Jeśli Twój zespół realizacji zamówień wstrzymuje promocję w momencie składania zamówienia, upewnij się, że masz mechanizm, który umożliwi zwolnienie wstrzymania, jeśli promocja nie zostanie wykorzystana przez przesłanie zamówienia po upływie określonego czasu. Dzięki temu usługa zamawiania jedzenia będzie miała odpowiednią pulę kampanii.
Rozwiązywanie problemów z promocjami
Jeśli Twoje usługi ustalą, że kod promocyjny z CheckoutRequestMessage
jest nieprawidłowy (np. wygasł, jest nieprawidłowy lub nierozpoznany), wyślij odpowiedź CheckoutResponseMessage
z obiektem foodOrderError
, który zawiera odpowiedni kod błędu i tekst powodu, a także obiekty correctedProposedOrder
i paymentOptions
.
Jeśli usługa realizacji zamówienia znajdzie wiele błędów kodu promocyjnego w ramach tego samego żądania, prześlij błędy nieodwracalne przed błędami możliwymi do naprawienia. Nadaj priorytety kontrolom w następujący sposób (od najwyższego do najniższego priorytetu):
PROMO_NOT_RECOGNIZED
PROMO_EXPIRED
PROMO_USER_INELIGIBLE
PROMO_ORDER_INELIGIBLE
PROMO_NOT_APPLICABLE
Przykłady
Oto przykład żądania płatności z kodem promocyjnym:
{ "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 }
Oto odpowiednia odpowiedź z miejsca realizacji po zakończeniu płatności, jeśli kod promocyjny jest prawidłowy:
{ "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": [] } } }
Oto przykład odpowiedzi z procesu płatności, gdy kod promocyjny jest nieprawidłowy:
{ "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" } } } ] } } }
Implement submit order with promotions
W spełnianiu zamówienia po przesłaniu sprawdź, czy użytkownik po raz pierwszy stosuje kod promocyjny. Podczas przetwarzania SubmitOrderRequestMessage
możesz to sprawdzić, korzystając z szczegółów Contact
(np. adresu e-mail użytkownika) obiektu FoodCartExtension
.
Sprawdź też, czy kod promocyjny jest ważny:
- Jeśli kod jest ważny: potwierdź zamówienie i oznacz kupon jako wykorzystany.
- Jeśli kod nie jest już ważny: odrzuć zamówienie z błędem
PROMO_NOT_APPLICABLE
. Możesz podać konkretny powód odrzucenia, korzystając z tego samego mechanizmu co w przypadkuFoodOrderUpdateExtension
.
Przykłady
Oto przykład prośby o przesłanie zamówienia z promocjami:
{ "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 }
Oto przykład odpowiedzi na przesłanie zamówienia z wykonania, jeśli kod promocyjny jest prawidłowy:
{ "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": [] } } }
Oto przykład odpowiedzi na przesłanie zamówienia, gdy kod promocyjny jest nieprawidłowy:
"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." } ] } }