Skip to content

Dynamic Upsell widget

The Dynamic Upsell widget allows you to offer ancillaries within your existing customer journey with a UI built by Gordian. These are some of the benefits of the widget:

  • You can add ancillaries onto any flight booking from any ticketing channel.
  • You can select which products to display at different points.
  • You can save time by leaving the interactive UI development to Gordian.

The following image is an example of how your widget may look. For details on how to customize the appearance of the widget, contact your account manager.

Dynamic Upsell widget sample

Placing the widget

The Dynamic Upsell widget fits within the customer journey as part of the “Building a trip” step. This means that you must implement the rest of the steps by using the Gordian API directly. See the flights tutorial for more information on using the API.

The following table is a summary of which steps of the customer journey need which implementation:

Step Implementation Notes
1. Search for flights API You can create a new trip from scratch or from a record locator.
2. Add flight to the basket API You can skip this step if you used a record locator.
3. Add ancillaries API or Widget You can select which products to display.
4. Verify basket items API or Widget You must keep track of every item from the widget in your local basket.
5. Fulfill a trip API

Widget implementation

After searching for flights and selecting at least one through the API, you can use the Dynamic Upsell widget to display ancillaries to the customers. To add the widget to your website funnel, add the following tag to the page:

<script src="https://sdk.gordiansoftware.com/javascript/v2.2/gordian.min.js"></script>

Gordian provides the widget through a 5kb SDK. The file is available through a CDN to allow fast loading of your page.

This guide covers the following implementation steps:

  1. Initialize the SDK
  2. Display ancillaries
  3. Integrate the basket

Throughout this guide, you can refer to the sandbox example to see the completed backend and frontend integration.

Note

If you fork the sandbox example, add the API_KEY environment variable in your code sandbox environment. For more information on secrets, see the Codesandbox Secrets documentation.

Initialize the SDK

To initialize the Gordian SDK, call the init function. This function requires:

  • The trip_id and trip_access_token you received from creating a trip.
  • A callback function into onBasketChange. This function helps you keep track of the products the customer has selected and the state of those products. See integrate the basket for more information.

The following code is a sample of the init function:

Gordian.init({
  tripId: "c1859ade-6ceb-4a7f-9a08-bf5ff33f1129",
  tripAccessToken: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0cl9pZCI6ImMxODU5YWRlLTZjZWItNGE3Zi05YTA4LWJmNWZmMzNmMTEyOSIsImluX2lkIjoiZjM5ZTRkZGQtNGM0Zi00ZTczLWJkOGUtNzBlNjRlZjBhNDdjIiwic2FuZGJveCI6ZmFsc2V9.F3hAHVoHut1Qkpm-wUUkK6b-_DHGMLpJ6CWf9A5ifuLBilwfK52aDVeW8axzwCA2dddKV8oq_Vdo90Z6sv-l_XfVoHsRkSBkSuZsLhj9TZ6WcYElstKr5NJxxUWG6muax_i4ceMTLbWIItr1QUtsSqVGHqrGj46Xvw5hebip-wCnhAjE3-N3rqzM_skDHnJEQwX9OiexrXFXtvwPyhp5UMaDCeuH2j9pw1VnURQVYsv8hBxdyCOWfdiHcwgFzKkSuja2PyYXTk9R1LgJm0KFICEbRer0L31lDYfuxo5_3OK8mnUD0P40xr4g9xoeiQkWumlDJ4fz6crIqlvv1hfj0g",
  onBasketChange: onBasketChange
});

Display Ancillaries

Once the SDK is initialized, you can display products to the customers. To display products, use the showUpsell function. The following is a sample code snippet:

Gordian.showUpsell({
  container: document.getElementById("upsell-container"),
  display: "card", // card | embedded | modal
  allowProducts: ["seats"], //"bags", "fare_family_upsell", "priority_boading"...
  excludeProducts: [""]
})

The showUpsell function has four inputs:

  • container: The element ID of the container you want to display the widget within.
  • display: (Available for seats) This controls how the product is presented to the customer.
  • allowProducts: The product type you want to display. For example, use allowProducts:["seats"] to display only seats.
  • excludeProducts: The product type you do not want to display. For example, use excludeProducts:["seats"] to display all products but seats.

For more information about display types, see the product specific guides.

Note

The widget uses a default color scheme. To customize it to fit your brand colors, fonts, and other styling, reach out to your account manager.

Using multiple display types

Each instance of the Dynamic Upsell widget can only have a single display type. To display two product types in two different displays, add two instances of the Dynamic Upsell widget on your page with different allowed and excluded products.

Integrate the basket

Now that your customers are able to view ancillaries, you need to keep track of the products the customer wants to purchase.

Attention

Any product that the customer selects must be added to your checkout basket and charged with your company as the merchant of record. Therefore, it is critical that you actively track which products are added or removed from the widget.

Whenever the basket has anything added or removed, or if an item in the basket expires, the widget calls the onBasketChange function. The following is a sample of this function:

const onBasketChange = ({ basket }) => {
  var basketBody = document.getElementById("basket-body");
  basketBody.innerHTML = "";
  for (var key in basket) {
    const product = basket[key];
    var row = document.createElement("tr");
    row.classList.remove("invalid");
    var productCell = document.createElement("td");
    var priceCell = document.createElement("td");
    productCell.innerText = product.display_name;
    priceCell.innerText = window.Gordian.formatPrice(
      product.price.total.amount,
      product.price.total.decimal_places,
      product.price.total.currency
    );
    var message = document.createElement("message");

    product.validity = product.validity;
    if (product.validity.state === "valid") {
    } else if (product.validity.state === "checking") {
      row.classList.add("checking");
      message.innerText = "Checking if this product is still available...";
    } else if (product.validity.state === "price_changed") {
      row.classList.add("price_changed");
      message.innerText = "The price for this product has changed!";
    } else if (product.validity.state === "unavailable") {
      row.classList.add("unavailable");
      message.innerText = "Sorry, this product is no longer available";
    }
    priceCell.appendChild(message);
    row.appendChild(productCell);
    row.appendChild(priceCell);
    basketBody.appendChild(row);
  }

The single parameter to onBasketChange is a JSON representation of the whole customer trip. When you receive the JSON object, update your local basket with this new set by replacing all the products previously selected.

The basket includes a lot of granularity on each product. At a minimum, include the display_name and the price of each product in your basket for the customer's reference. The function Gordian.formatPrice helps you render the price for your user.

Products can become invalid because of changed availability or because of new passenger information, such as the age of the passenger or loyalty program information. When the validity changes, the onBasketChanged function retrieves different values for the validity field. You must check the new value to decide if there are actions needed. The possible values are the following:

Validity value Description Action
valid This product is still valid. N/A
checking Checking is in progress. Show a spinner to the user.
price_changed The price changed. Show the price change to the user and allow them to accept or reject it.
unavailable The product is not available. Inform the user, remove the product from the basket and call the showUpsell function to select an alternative.