Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 15 Current »

Table of Contents


Problem statement

It was requested the ability to use a loyalty promo code through the checkout page. With that in mind, we extended the loyalty feature that before could only be used on /offers page.

The idea is to improve the user experience because the user now has the ability to add offers without the need to go back to the /offers page. The goal is to make it easier to redeem the offers, to ensure that customers perceive the value of this type of promotions. This will generate higher engagement / usage, and the end goal is to increase the overall order value, quantity and ultimately total revenue.

PS: This feature reused part of the deprecated/removed CBA Offers code. We are also using part of the loyalty offers logic to control the implementation.

For the feature to work as expected, the promo code should be configured using Sanity and the desired campaign tool (Voucherify, etc). The setup instructions are available here: Promo Codes Content Setup.

Solution restrictions:

  • The Item; Offer Activation; Swap are legacy options that came from the US fork and will not work for now.  

  • Currently, the promo code at checkout will only support the following types of “In-App Benefits” configured: Combo; Picker; Discount.

image-20240517-145726.png

  • Even if Sanity shows a list of “In-App Benefits” the legacy code for this will only support only one item independently of the type


Business requirements

  • The user should not be redirected to the menu page when applying a promotional code directly through the checkout page (for Offer Combo/Picker)

  • Add the offer item with the default selections for the Combo/Picker

  • Show the “edit” button on the cart offer item. The edit button should send the user to the menu page for the edited item

  • The behavior must be closely related to the legacy flow /offer page:

    • The item added to the cart should be exactly as we are adding it through the legacy flow /offer (sub-items, price, etc)

    • The item should be correct at Recent Orders or Email Receipt (like the legacy /offers flow).

    • The offer item should not be available to add again to a new order after being used (blocked by the application by default)

  • Only one offer item can be added by default. If the user tries to add another offer (Combo, Picker/Offer Discount), a modal will ask if the user wants to replace the current added offer with the new one.

  • If the user tries to apply the same code twice, the application should block this showing an error about “promo code already applied”

  • The feature should respect the rules from Sanity or the campaign platform. For example, if the user already finishes an order for a promo code that only has one available, they should not be able to reuse that promo code

  • The application should show the same errors that we already have for promotional codes (the old deprecated/removed CBA flow):

    • Unknown exception error

    • Code expired

    • Invalid code

    • Code already redeemed

    • Invalid Offer ID

    • Promo code already applied


Whitelabel solution

image-20240517-162609.png

General behavior demonstration

How will the look and feel for Combo/Picker be after it is added to the cart

image-20240517-170457.png

About the final price

As shown in the screenshot above, the Combo/Picker will not show what the discount was or a "discount value". Why?

  • Today our app doesn't have a discount at the item level

  • For the feature to work, we need to create an “Offer Combo” or “Offer Picker” on Sanity. This means that we always have an exclusive new item created for the promotion, and this item will already have the final price considering the promotion/discount

  • For the cart, total, subtotal, receipt, and email receipt, the prices will not show any different information about the offer

  • Important: when configuring the campaign platform (Voucherify, etc.), the type of discount in the coupon or the value of the coupon will not be used at all. The value for Combo/Picker will come from Sanity vendor configs. We can set 0 as value in the campaign platform.

PS: What can be different between Combo/Picker is the sub-items shown in the card. Sometimes the Picker will be converted as a single item and will not have any sub-items.

Videos demonstrations:

Adding an Offer Discount at checkout

image-20240517-173709.png

About the final price

  • As shown in the screenshot above, the “Offer Discount” is not considered a "cart item" (as a product, for example). We can think of this as an "informative card"

  • The "Offer Discount" will have a discount applied to the final price of the cart (total cart). The type of discount can be “Amount” (absolute value discounted) or “Percentage”

    image-20240521-133738.png

    image-20240527-132043.png

    For the screenshot above we can imagine that we have a Offer Discount of 50% applied. The sum of prices and taxes will be something close to 20 but the final value will be half of that.

    PS: Please disregard if the values are not exact in the screenshot above, as this comes from a dev environment and we have some problems with value consistency. The important thing here is the idea/behavior.

  • Important: when configuring the campaign platform (Voucherify, etc.), we need to select the coupon to be a percentage or fixed value as well to ensure the correct behavior

How we’ll show the errors

  • For errors that are related to the promo code when applying/redeem we’ll show the error below the promo code field

    image-20240517-173251.png

  • For errors that are related to the Sanity rules the application can show the error in two places

    • Inside the “header” of the Offer item added into the cart

      image-20240517-175750.png

    • Above the “continue” checkout page button. This use case is not the most common, and we don’t have all the scenarios mapped as this is legacy code. Please disregard the message, as the idea here is only to show where the error can appear.

      image-20240517-180105.png

About the edit button

image-20240517-171125.png

As the user is adding the offer directly to the checkout page, he/she needs the ability to edit the offer item if he/she wants to change some of the items. This can also be used as a “shortcut” to offer up-sells during the edit time.

The edit button will only be available if the offer was added first on the checkout page. The legacy /offers will already send the user to the menu page, where he can edit and choose what he wants. Demonstration is included below.

Videos demonstrations:

Replace logic example

image-20240517-172220.png

The visual is standardized and will be the same that we also have on the /offers page.

Videos demonstrations:

 Click here to expand...

Relationship between /offers page and promo code at checkout and reuse

As this feature uses the loyalty offer structure in its implementation, we'll have some states and connected behaviors:

  • Always, when we redeem an offer on the checkout page, this offer will also be available on the /offers page to be used later (e.g., when the user, for example, adds the offer on the checkout page but for some reason doesn't finish the order using that promo code)

  • The user can reuse a promo code until he/she finishes the order (as a default). Of course, this can be changed based on the Sanity rules for the configured offer. If the promo code is not valid anymore, an error will alert the user about it

Videos demonstrations:

 Click here to expand...

In the video below, we can see that after replacing an offer, the replaced offer will also be selected on the /offers page as the current selected offer.

Replace offer and legacy flow relationship.mp4

FAQ

Golden rule

 Click here to expand...

Most of the behaviors will be equal to what we have on the /offers page. If we don’t know if something is a bug or not, we need to first check the behavior of the offer if we add it through the /offers page.

Partners integration and POS vendors

 Click here to expand...

Integration by using sanity id

image-20240521-141817.png

We need to ensure that the campaign platform will have the Loyalty Engine ID properly configured to match the configured offer (for Offer Discount or Combo/Picker).

Using Winrest as an example, they register these sanityId on their system. This is necessary for Winrest to calculate the total cart price correctly. For other vendors/POS this can also be used for integration. This can be done manually by sending the Id to the POS vendor, or you can also use the orderDiscount object that the Whitelabel App is already sending in the request (see below).

Integration using orderDiscount object

For this, we are using the IWebhookPriceOrder when we send the orderDiscounts property. With this property, the vendor/POS can get the offer information automatically and then make the calculation correct to return to the Whitelabel the correct value.

Payload example:

{
  "callbackUrl": "https://euw3-dev-plk-partners-api.rbictg.com/api/v1/orders/84b5f1df-28df-4e6f-a871-a2783602436f/price/callback",
  "cart": {
    "menuSelections": [
      {
        "externalReferenceId": "800853",
        "id": "f9f5b02e-bee8-4dd1-a5fa-222b79516a98",
        "menuSelections": [
          {
            "externalReferenceId": "800852",
            "id": "item_67167",
            "menuSelections": [],
            "price": {
              "amount": 679,
              "currency": "EUR"
            },
            "quantity": 1
          }
        ],
        "price": {
          "amount": 1100,
          "currency": "EUR"
        },
        "quantity": 1
      }
    ]
  },
  "channel": "WHITELABEL_IN_STORE",
  "fees": [],
  "id": "84b5f1df-28df-4e6f-a871-a2783602436f",
  "instructions": [],
  "serviceMode": "TAKEOUT",
  "storeId": "1111",
  "orderDiscounts": [
    {
      "type": "percentage", // or amount
      "value": 50
    }
  ]
}

For Combo/Picker what's the difference from what we have on the /offers page?

 Click here to expand...

All the behavior regarding price, item information, etc. will be the same. The only difference is the following:

  • We'll add the item directly into the cart without passing it through the menu page

  • We'll show the edit button when the item is added using the promo code field at the checkout page

Can we replace an offer at the checkout page?

 Click here to expand...

Yes, the behavior will be the same that we have in the /offers page

Can we edit the Combo/Picker in the cart preview?

 Click here to expand...

Yes. In some cases, after editing the item, the user will not be redirected to the checkout page again, but this is an expected behavior regarding how the cart preview works. Always compare the editing function using other items to be sure if there is a bug or not

After adding the offer to the cart, the price is wrong, or I'm receiving an error saying that the offer is not available at the selected restaurant or that the product added is invalid

 Click here to expand...

Most of the times, we'll have a problem with configurations:

  • Offer configuration (invalid PLU in Sanity)

  • PLU not configured or is not available for the selected restaurant

Lokalize keys

For the errors:

  • promoCodeOfferUnknownException: default error if the backend or campaign platform doesn't return a specific one. 

  • promoCodeOfferExpiredCode: for the expired code message

  • promoCodeOfferInvalidCode: for the invalid code message

  • promoCodeOfferRedeemedCode: for the already redeemed code

  • invalidOfferId: invalid offer id configured in the offer message (for bad setup)

  • promoCodeAlreadyApplied: message when a code is already applied

For the promo code button texts:

  • apply: the text for the apply button. As this is a very generic key is not recommended to change because can affect other places

  • enterPromoCode: the label of the input

Feature Flags

  • enable-edit-offer-added-at-checkout: to show or not the edit button in the offer item (for Combo/Picker)

  • enable-loyalty-offer-promo-code-at-checkout: a main flag to disable/enable the whole feature

  • enablePromoCodeAtCheckout: This is legacy flag that already exists and control the promo code besides our feature. Needs to be on too if we want the feature to be working

  • No labels