Promowanie

Promocje umożliwiają Tobie i Google zachęcenie klientów do spróbowania Twoich usług zamawiania jedzenia po obniżonych cenach. Google obsługuje kompleksowe działania związane z zamawianiem z Twoim systemem zarządzania promocjami.

Obsługiwane są te typy rabatów:

  • Kody promocyjne sponsorowane przez Google: kody promocyjne, które są automatycznie wypełniane przez Google lub wpisane przez użytkowników.
  • Sponsorowane przez inne firmy kody promocyjne: kody promocyjne, które użytkownicy mogą wpisywać, dostarczane przez Twoją firmę do zamawiania jedzenia.
  • Automatyczne rabaty sponsorowane przez firmę zewnętrzną: rabaty, które Twoja usługa zamawiania jedzenia jest stosowana automatycznie bez kodu promocyjnego.

Niezależnie od typu rabatu Google wykonuje połączenie z realizacją zamówienia, aby zweryfikować i zastosować rabat.

Deweloper usługi zamawiania jedzenia musi wprowadzić pewne zmiany w swojej implementacji, aby obliczać rabaty dla prawidłowych kodów promocyjnych lub przesyłać błędy w przypadku nieprawidłowych kodów promocyjnych, zarządzać limitami wykorzystania kodów promocyjnych oraz śledzić dane księgowe do uzyskania zwrotu kosztów.

Jak przetwarzać promocje

Aby wdrożyć realizację obsługującą promocje:

  1. Skonfiguruj integrację promocji (Pomiń ten krok, jeśli nie używasz kodów promocyjnych sponsorowanych przez Google).
  2. Wdrażanie płatności za pomocą promocji
  3. Wdróż funkcję przesyłania zamówienia z promocjami

Skonfiguruj integrację promocji

Z tej sekcji dowiesz się, jak skonfigurować integrację promocji, jeśli chcesz korzystać z kodów promocyjnych sponsorowanych przez Google. Jeśli chcesz obsługiwać tylko kody promocyjne lub rabaty sponsorowane przez inną firmę, możesz określić własną konfigurację i pominąć tę sekcję.

Google określa typ promocji dla sponsora i kontaktuje się z Tobą w celu skonfigurowania integracji. Podajemy te informacje:

  • kwotę rabatu.
  • Minimalna wartość koszyka.
  • daty rozpoczęcia i zakończenia korzystania z kodów promocyjnych.
  • Maksymalna kwota budżetu przeznaczona na kampanię promocyjną.
  • Liczba kodów promocyjnych, które można wykorzystać.

Przykłady kodów promocyjnych:

  • FopaNewUser: 10% (stała wartość procentowa), maksymalnie 50 USD zniżki.
  • FopaMoreThan50: 10 USD (stała zniżka).

Jeśli Google zatrzyma stosowanie kodu, skontaktujemy się z Tobą.

Skonfiguruj wypłaty

Aby skonfigurować proces wypłaty, skontaktuj się ze swoim konsultantem w programie Google dla użytkowników wczesnej wersji. Google zwraca koszty transakcji obejmujących kody promocyjne sponsorowane przez Google tylko wtedy, gdy ostateczny stan zamówienia to:

  • CONFIRMED
  • IN_TRANSIT
  • READY_FOR_PICKUP
  • IN_PREPARATION
  • FULFILLED

Wdrażanie procesu płatności z promocjami

W tej sekcji opisujemy, jak wdrożyć przetwarzanie płatności, gdy korzystasz z kodów promocyjnych (sponsorowanych przez Google lub innych firm). W przypadku rabatów automatycznych sponsorowanych przez inne firmy musisz zwrócić tylko element zamówienia ze zniżką w CheckoutResponseMessage (nie musisz sprawdzać kodu promocyjnego).

Podczas realizacji zamówienia na jedzenie Google wysyła pojedynczy kod promocyjny w CheckoutRequestMessage do Twojej realizacji. Użytkownicy mogą zmieniać koszyk lub kod promocyjny w przypadku kolejnych próśb o dokonanie płatności.

Aby sprawdzić, czy użytkownik stosuje kod promocyjny po raz pierwszy, wykonaj te czynności:

  • Sponsorowane przez Google kody promocyjne: sprawdzamy, czy powracający użytkownik nie próbuje ponownie użyć tego samego kodu promocyjnego. Nie musisz niczego robić.
  • Kody promocyjne sponsorowane przez inne firmy lub rabaty automatyczne: jeśli nie masz zaimplementowanego łączenia kont ani zgody użytkownika, podczas przetwarzania prośby o płatności nie będziesz mieć możliwości sprawdzenia danych użytkownika. Zamiast tego możesz to sprawdzić podczas przetwarzania SubmitOrderRequestMessage przy użyciu danych Contact (takich jak adres e-mail użytkownika) z obiektu FoodCartExtension.

Identyfikuj błędy lub obliczaj rabaty w ramach realizacji zamówienia na podstawie ostatniego żądania płatności. Upewnij się wtedy, że Twój system nie przechowuje nieaktualnych informacji.

Sprawdź poprawność kodu promocyjnego

Realizacja transakcji powinna polegać na sprawdzeniu ważności lub kwalifikacji danego kodu promocyjnego pod kątem określonych warunków, takich jak data ważności, maksymalne wykorzystanie i maksymalne rabaty. Następnie podaj w polu CheckoutResponseMessage obliczony rabat lub foodOrderErrors, jeśli nie można zastosować kodu promocyjnego. Jeśli wykryjesz błędy w kodzie promocyjnym, postępuj zgodnie z instrukcjami w sekcji Obsługa błędów związanych z promocjami.

Poniższy fragment zawiera przykładowy foodOrderErrors kodu promocyjnego. Upewnij się, że 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, realizacja powinna obliczyć wartość rabatu w dolarach i wysłać zwrot CheckoutResponseMessage z obliczoną wartością rabatu w tablicy otherItems. Łączna cena zamówienia nie może być ujemna. Jeśli kwota rabatu przekracza wartość koszyka, odeślij maksymalną kwotę w złotówkach, aby wyrenderować całkowitą cenę zamówienia do 0 zł.

Ten fragment kodu zawiera 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 niewykorzystanych promocji

Nie każde żądanie płatności prowadzi do złożenia zamówienia. Jeśli realizacja płatności powoduje wstrzymanie promocji w momencie procesu płatności, upewnij się, że korzystasz z mechanizmu umożliwiających anulowanie blokady w przypadku, gdy po upływie określonego czasu nie uda się skorzystać z promocji za pomocą zamówienia. Dzięki temu będziesz mieć pewność, że Twoja usługa zamawiania jedzenia utrzyma odpowiedni limit kampanii.

Postępowanie w przypadku błędów dotyczących promocji

Jeśli w ramach realizacji transakcji stwierdzisz, że kod promocyjny z elementu CheckoutRequestMessage jest nieprawidłowy (np. wygasł, został nieprawidłowy lub nie został rozpoznany), wyślij żądanie CheckoutResponseMessage z prośbą o foodOrderError, która zawiera odpowiedni kod błędu i tekst przyczyny, a także obiekty correctedProposedOrder i paymentOptions.

Jeśli w ramach realizacji transakcji znajdziemy wiele błędów związanych z kodem promocyjnym w ramach tego samego żądania, przed wysłaniem wiadomości o błędach możliwych do naprawienia odeślij je. Ustal priorytety weryfikacji w ten sposób (od wysokiego do niskiego priorytetu):

  • PROMO_NOT_RECOGNIZED
  • PROMO_EXPIRED
  • PROMO_USER_INELIGIBLE
  • PROMO_ORDER_INELIGIBLE
  • PROMO_NOT_APPLICABLE

Przykłady

Oto przykład prośby o płatność 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
}

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": []
    }
  }
}

Jeśli 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"
            }
          }
        }
      ]
    }
  }
}

Wdrażanie funkcji przesyłania zamówienia z promocjami

W trakcie przesyłania zamówienia sprawdź, czy użytkownik stosuje kod promocyjny po raz pierwszy. Podczas przetwarzania danych SubmitOrderRequestMessage możesz to sprawdzić, korzystając z danych Contact (takich jak adres e-mail użytkownika) z obiektu FoodCartExtension.

Musisz też ponownie sprawdzić zastosowanie kodu promocyjnego:

  • Jeśli kod można wykorzystać: potwierdź zamówienie i oznacz kupon jako wykorzystany.
  • Jeśli kod nie jest już odpowiedni: odrzuć zamówienie z błędem PROMO_NOT_APPLICABLE. Możesz podać konkretną przyczynę odrzucenia, korzystając z tego samego mechanizmu co w przypadku FoodOrderUpdateExtension.

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
}

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": []
    }
  }
}

Jeśli 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."
      }
    ]
  }
}