Overview
Integrating with the Extend SDKs will allow you to display offers and sell extended warranty contracts in your online store. This guide will walk you through how to do the following:
- Install the Extend Client SDK
- Render the extended warranty offers
- Add extended warranties to your cart
- Support quantity matching and cart normalization for extended warranty product SKUs in your cart
Before you start: Make sure you have an Extend store created. You can obtain this via the merchant portal (merchants.extend.com) or reach out to your MSM if you have not yet been given an Extend store ID.
Setup
-
Generate a Stencil-CLI access token (if using a stencil theme. See here for instructions on how to do this)
-
Make a copy of the theme you intend to customize and download it to your local development environment.
-
Setup your local development environment using stencil CLI setup
-
Log in to your merchant account with extend at merchants.extend.com and retrieve your Extend store id. If you do not have a merchant account, contact your Merchant Success Manager to have one created for you.
-
Generate a BigCommerce API account in your BigCommerce account, and provide these credentials to your Merchant Success Manager or Solution Engineer at Extend. See the section labeled “Obtaining Store API Credentials” here. You will need to set the following scopes for this API Account:
- Orders: read-only
- Order Transactions: read-only
- Products: read-only
- Carts: modify
- Store Information: read-only
- Sites & Routes: read-only
Installation
Add the following scripts into your base.html file (if using a stencil theme) right before the closing </head>
tag and press save. If using a Blueprint theme or custom theme, please ensure the script tags are present in the <head>
of each page where a shopper can add items to the cart, including the cart page.
<script src="https://sdk.helloextend.com/extend-sdk-client/v1/extend-sdk-client.min.js"></script>
<script src="https://sdk.helloextend.com/extend-sdk-client-bigcommerce-addon/v1/extend-sdk-client-bigcommerce-addon.min.js"></script>
<script>Extend.config({ storeId: '<YOUR_EXTEND_STORE_ID>', environment: 'production' })</script>
To verify the scripts are running correctly, preview your theme copy, open your browser’s console, type ‘Extend’ or ‘ExtendBigCommerce’ and hit enter. Both scripts should appear in the console.
Add Extend Offer Element
Add an HTML element where you would like to place the Extend offer buttons. For highest conversion rates, we recommend placing it directly above the add to cart button. In most cases, the button is in the add-to-cart.html file, but if you have done previous work on your product page it may be located somewhere else in your theme.
<div id="extend-offer">This is where the buttons will render</div>
Verify that the div has been added to the correct spot by temporarily adding some text, saving, and previewing your product page. Once you confirm that the text is showing in the correct spot, make sure to remove it!
Render Extend Warranty buttons on product page
Now that the offers element is added, you can use the Extend.buttons.render() function to render the offer buttons on the product page. This function takes in 2 arguments:
- The ID of the
#extend-offer
element you added in the previous step - An object with a key of referenceId and a value of the selected product
sku
Extend.buttons.render('#extend-offer', {referenceId: <sku>})
Handling Multiple Variants
In order to prevent a customer from accidentally purchasing the wrong warranty for a product, the warranty offers need to be updated every time a shopper selects a different variant for a product. This is done by passing the variant sku
of the newly selected product to the Extend.setActiveProduct
function. Therefore, you will need to determine how your store updates the product page when a different product variant is selected. This is typically done by dispatching a JavaScript event or by manipulating the window location. Add an event listener to the page and invoke Extend.setActiveProduct()
with the newly selected sku
.
Extend.setActiveProduct('#extend-offer', <sku>)
Verify that you are setting the correct variant by adding a console log right before the Extend.setActiveProduct()
function is called. This ensures you are passing the correct variantId. You will also notice that if you change the variant on the page, the offer buttons will re-render.
Example - Using a Cornerstone-based Stencil Theme
The Cornerstone theme handles variant changes using a method called productOptionsChanged()
in the product-details.js file. This method exposes the sku of the selected variant. To set the active product include the following line, accessing the sku off of the productAttributesData object:
utils.api.productAttributes.optionChange(
productId,
$form.serialize(),
'products/bulk-discount-rates',
(err, response) => {
const productAttributesData = response.data || {};
const productAttributesContent = response.content || {};
this.updateProductAttributes(productAttributesData);
this.updateView(productAttributesData, productAttributesContent);
// ===== Extend SDK ===== //
Extend.buttons
.instance('#extend-offer')
.setActiveProduct(productAttributesData.sku);
// ===== End Extend SDK ===== //
}
);
Add the Extend offer modal and add warranties to the cart
The Modal Offer is a modal rendered before navigating the customer to a new page and adding a product to cart, or as an opportunity on the cart page. In the example below, the offer modal appears after the customer added the product to the cart without selecting one of the offered protection plans.
Example 1 - Add an eventListener to the Add to Cart button Select the Add to Cart button element on the product page using vanillaJS or jQuery and add an eventListener.
var addToCartButton = document.querySelector('<button_selector>');
addToCartButton.addEventListener('click', function (event) {});
In order to add the warranty to the cart or launch the offer modal, you need to prevent the default behavior of the Add to Cart button. You can do this by adding an event.preventDefault()
or event.stopImmediatePropagation()
inside the eventListener
Use the ExtendBigCommerce.handleAddToCart()
function inside the add to cart event listener. Make sure to select quantity value from product form and add to ExtendBigCommerce.handleAddToCart()
function.
addToCartButton.addEventListener('click', function (e) {
e.preventDefault();
var quantityEl = document.querySelector('[name="quantity"]');
var quantity = quantityEl && quantityEl.value;
ExtendBigCommerce.handleAddToCart('#extend-offer', {
quantity: quantity,
modal: true,
done: function () {
// call function to add your product here
},
});
});
Example 2 - Modify Existing Add to Cart Handler
Alternatively, the following code can be added directly to the existing add to cart handler.
if (window.ExtendBigCommerce && window.Extend) {
popModal();
const quantityInput = document.querySelector('input[id="qty[]"]');
const quantity = quantityInput && quantityInput.value;
window.ExtendBigCommerce.handleAddToCart('#extend-offer', {
quantity,
modal: true,
// done: popModal,
});
}
Display Cart Offers
The cart offer is the last chance your shoppers have to add an extended warranty before they checkout. Here you can display an offer button next to each eligible product in the cart that does not already have a protection plan associated with it.
Add an HTML element where you would like to place the Extend cart offer buttons. We recommend placing the element directly below each product in the cart. In the case of Cornerstone Stencil themes, this is in the content.html (and cart-preview.html for mini-cart).
You need to add this button under each product in the cart that does not have a warranty. Find where the cart items are being iterated on in the template. Then set the quantity
and sku
of the product to the cart offer div data attributes:
<div
id="extend-cart-offer"
data-extend-item-id="<id>"
data-extend-sku="<sku>"
data-extend-quantity="<quantity>"
></div>
You can verify that the div has been added to the correct spot by temporarily adding some text, saving, and previewing your cart page. Once you confirm that the text is showing in the correct spot, make sure to remove it.
You also need to verify that the quantity
and sku
and cartItemId
are being passed into the cart offer div correctly. In your preview, navigate to your cart and inspect the page. You won’t be able to see the Extend cart offer buttons on the page, but you should see the HTML element.
Render Cart Offer Buttons
Find the appropriate javascript file for the shopping cart (cart.js in the case of Cornerstone Stencil themes) and include the following two helper methods:
function findAll(element) {
var slice = Array.prototype.slice;
var items = document.querySelectorAll(element);
return items ? slice.call(items, 0) : [];
}
function addPlanToCart(sku, plan, quantity, cart) {
ExtendBigCommerce.addPlanToCart(
{
sku: sku,
plan: plan,
quantity: quantity,
cart: cart,
},
function (err) {
if (err) {
return;
} else {
window.location.reload();
}
}
);
}
Call the findAll
helper method we added in the last step to find all the Extend cart offer divs. Here you need to pass in the ID of the Extend cart offer element (#extend-cart-offer)
.
As you iterate through each item, pull out the sku
and the quantity
from the #extend-cart-offer
div data attributes.
var sku = el.getAttribute('data-extend-sku');
var quantity = el.getAttribute('data-extend-quantity');
Use the warrantyAlreadyInCart()
function to determine if you should show the offer button.
if (ExtendBigCommerce.warrantyAlreadyInCart(sku, cart)) {
return;
}
Then render the cart offer buttons using the Extend.buttons.renderSimpleOffer()
function.
Extend.buttons.renderSimpleOffer(el, {
referenceId: sku,
onAddToCart: function ({ plan }) {
ExtendBigCommerce.addPlanToCart(
{
sku: sku,
plan: plan,
quantity: quantity,
cart: cart,
},
function (err) {
if (err) {
return;
} else {
window.location.reload();
}
}
);
},
});
Verify the cart offer buttons are rendering correctly by previewing your theme and going to your cart page that has an active and enabled product in it. You should see the Extend cart offer button in the cart, and when you click it, it should launch the offer modal. When a shopper clicks this offer button, the modal described in the previous section will launch, and the shopper will be able to select which warranty plan he or she would like to purchase.
Setting the Image for Custom Items
Because the Extend BigCommerce SDK uses Custom Items to create protection plans dynamically, the Extend cart image must be included in your theme, and image markup included in your templates wherever cart items are displayed.
If you are using a Stencil theme built off of Cornerstone, you can do this by taking the following steps:
- Add the image file to your assets/img folder
- Set the image in the config.json file on both the settings and settings.variations properties.
"default_image_extend": "/assets/img/extend_logo.png"
- Update each template where cart items are displayed to include the following above where the existing item image is rendered:
{{#if type == 'Custom'}}
<img
class="cart-item-fixed-image"
data-sizes="auto"
src="{{cdn 'img/extend_logo.png'}}"
data-src="{{cdn ../theme_settings.default_image_extend}}"
alt="Extend Protection Plan"
title="Extend Protection Plan"
/>
{{else}}
Cart Normalization
As part of the checkout process, customers often update product quantities in their cart. The cart normalization feature will automatically adjust the quantity of Extend protection plans as the customer adjusts the quantity of the associated product. If a customer increases or decreases the quantity of products, the quantity for the related warranties in the cart should increase or decrease as well. In addition, if a customer has completely removed a product from the cart, any related warranties should be removed from the cart so the customer does not accidentally purchase a protection plan without a product.
To leverage cart normalization, you’ll need to include the cart normalize function provided by the BigCommerce SDK in your cart.
Place the following snippet in your cart logic so that it runs when your cart initially loads, as well as any time the cart content is refreshed.
ExtendBigCommerce.normalizeCart(
{ cart: cart, balance: false },
function (err, data) {
if (data && data.updates) {
return window.location.reload();
}
}
);
If you are using the stencil Cornerstone theme, this can be done by using this function within the cart.js file. Place the above snippet within the onReady() function, and again in the getContent callback within refreshContent().
ExtendBigCommerce.normalizeCart
will return a promise that will give you the data
and err
object to check if the cart needs to be normalized. If the data object exists and data.updates
is set to true
, you will then call your function to refresh the cart page. Typically reloading the page will work for most BigCommerce cart pages.
Balanced vs unbalanced carts
Now that you have the normalize function in place, you need to decide if you want a balanced or unbalanced cart.
- Balanced cart: Whenever the quantity of a product with a warranty associated with it is increased, the quantity of the extended warranty sku associated with it will also increase to match.
- Unbalanced cart: Whenever the quantity of a product with a warranty associated with it is increased, the quantity of the extended warranty sku will remain the same, and it is up to the shopper to decide if he or she wants to add warranties to protect those new products.
Balanced and unbalanced carts can be toggled with the balance: true/false
property.
Disabling Protection Plan Links within the Cart
First, navigate to the template that renders the shopping cart contents (in the case of Cornerstone Stencil templates, this will be templates/cart/content.html). Locate where the cart item links are rendered and conditionally remove the href values for warranty cart items.
For example, because the Extend BigCommerce SDK utilizes custom item types for warranty plans, you can target items with type ‘Custom’ by changing this line:
<h2 class="cart-item-name">
<a class="cart-item-name__label" href="{{url}}">{{name}}</a>
</h2>
To this:
{{#if type '==' 'Custom'}}
<h2 class="cart-item-name">
<a class="cart-item-name__label">{{name}}</a>
</h2>
{{else}}
<h2 class="cart-item-name">
<a class="cart-item-name__label" href="{{url}}">{{name}}</a>
</h2>
{{/if}}
If you are using Custom items for other functionality besides Extend, you can disable links on warranty items by targeting cart items with skus that contain the string ‘;xtd;’
ExtendBigCommerce API Reference
BigCommerce.addCartItem(opts: CartAddOpts, callback?: function)
This function adds a product from your catalog to the cart.
Attributes
Attribute | Data type | Description |
---|---|---|
opts required |
object | CartAddOpts |
callback optional |
function | Callback function that will have parameters (err, cart) that will be executed after the item is added to the cart |
CartAddOpts Object
Attribute | Data type | Description |
---|---|---|
cartId required |
string | The BigCommerce UUID for the current cart |
productId required |
number | Product associated with the warranty plan |
variantId required |
number | Variant associated with the warranty plan |
quantity required |
number | The product quantity to add |
optionSelections optional |
ItemOption array | Specific options selected by the shopper for this product |
Interface
interface ItemOption {
optionId: string;
optionValue: string;
}
BigCommerce.addPlanToCart(opts: AddToCartOpts, callback?: function)
This function adds an Extend warranty plan to the cart as a custom item.
Attributes
Attribute | Data type | Description |
---|---|---|
opts required |
object | AddToCartOpts |
callback optional |
function | Callback function that will be executed after the Extend plan is added to the cart |
AddToCartOpts Object
Attribute | Data type | Description |
---|---|---|
sku required |
string | The sku for the product associated with the warranty plan |
plan required |
string | The warranty plan to be added to the cart |
cart optional |
object | BigCommerce cart object for the current cart |
quantity optional |
number | The number of plans to add (defaults to 1 if not provided) |
BigCommerce.deleteCartItem(opts: CartRemoveOpts, callback?: function)
This function provides a convenient way to remove an item from the cart. In some cases it may be necessary to make an explicit call to remove an item from the cart in order to sort cart items properly (i.e. to ensure that a warranty item is directly beneath the corresponding product).
Attributes
Attribute | Data type | Description |
---|---|---|
opts required |
object | CartRemoveOpts |
callback optional |
function | Callback function that will have parameters (err, cart) that will be executed after the item is removed from the cart |
CartRemoveOpts Object
Attribute | Data type | Description |
---|---|---|
cartId required |
string | The sku for the product associated with the warranty plan |
itemId required |
string | The item you wish to remove from the cart |
BigCommerce.getCart(callback?: CartCallBack)
This function provides a convenient way to fetch the BigCommerce cart in the event that the current cart object is not available.
Attributes
Attribute | Data type | Description |
---|---|---|
callback optional |
function | Callback function that will have parameters (err, cart) that will be executed after the cart is fetched |
BigCommerce.getProductById(opts: GetProductByIdOpts)
This function provides a convenient way to fetch product details by productId in the event that required product information (e.g. sku) is not accessible.
Attribute | Data type | Description |
---|---|---|
opts required |
function | GetProductByIdOpts |
GetProductByIdOpts Object
Attribute | Data type | Description |
---|---|---|
productId required |
string | The productId of the product being fetched |
storefrontApiToken required |
string | The storefront API token required to make GraphQL calls |
done required |
function | Callback function that will have parameters (err, data) where data is the graphql product object |
BigCommerce.getProductBySelectedOptions(opts: GetProductBySelectedOptionsOpts)
This function provides a convenient way to get product information when the only available data is the specific product attributes selected by the user.
Attributes
Attribute | Data type | Description |
---|---|---|
opts optional |
object | GetProductBySelectedOptionsOpts |
GetProductBySelectedOptionsOpts Object
Attribute | Data type | Description |
---|---|---|
productId required |
string | The productId of the product being fetched |
productOptions required |
string | ProductOptions array interface defines the structure for product options if they are included in an add to cart request |
storefrontApiToken required |
string | The storefront API token required to make GraphQL calls |
done required |
function | Callback function that will have parameters (err, data) where data is the graphql product options object |
Interface
interface ProductOption {
optionEntityId: number;
valueEntityId: number;
}
BigCommerce.handleAddToCart(element: ElementRef, opts: HandleAddToCartOpts)
Attributes
Attribute | Data type | Description |
---|---|---|
element required |
object | The html element used to add products to the cart |
opts optional |
object | HandleAddToCartOpts |
HandleAddToCartOpts Object
Attribute | Data type | Description |
---|---|---|
modal optional |
boolean | If a shopper attempts to add a product to cart without selecting a warranty plan, setting modal to true will render the Offers modal. |
quantity optional |
number | The number of warranty plans to be added to cart. This should match the number of products added to cart. |
cart optional |
object | BigCommerce cart object for the current cart |
done required |
function | Callback function that will have parameters (err, data) |
BigCommerce.normalizeCart(optsOrCb: NormalizeCartOptions | Callback)
This function accepts and updates the BigCommerce cart object to ensure that the line item quantity of a warranty is not greater than the line item quantity of its associated product and returns an object containing the updated cart and cart updates. Therefore, this function should be executed every time the cart is updated in order to ensure a user cannot buy a warranty for a product not in the cart. While optional, a callback should almost always be passed as a second argument. This callback will be executed after the cart normalizes and should therefore be used to update the quantity input selectors on the page with their updated values, typically via a hard refresh.
Use case: Cart normalization
ExtendBigCommerce.normalizeCart(
{ cart: cart, balance: false },
function (err, data) {
if (data && data.updates) {
hardRefresh();
}
}
);
Attributes
Attribute | Data type | Description |
---|---|---|
normalizeCartOptions required |
object | NormalizeCartOptions |
callback optional |
function | Callback function that will be executed after the normalizeCart function is invoked (Typically refreshes the cart) |
NormalizeCartOptions Object
Attribute | Data type | Description |
---|---|---|
cart optional |
object | BigCommerce cart object to be normalized |
balance required |
boolean | When set to true warranty quantity will be equal the associated product quantity |
Interface
interface NormalizeCartOptions {
balance?: boolean;
cart?: Cart;
}
Normalize cart response object
Attribute | Data type | Description |
---|---|---|
cart |
object | Normalized Cart Object |
updates |
object or null | Object containing each updated sku and their updated quantities |
BigCommerce.warrantyAlreadyInCart(sku: string, cart: Cart)
This function accepts a BigCommerce sku
and the BigCommerce cart object. The function iterates through the BigCommerce cart items and returns a boolean indicating if there is already a warranty in the cart for that product sku
. This function is almost always used on the cart page to determine whether or not to render a cart offer button for a line item in the cart.
Attribute | Data type | Description |
---|---|---|
sku required |
string | The BigCommerce sku of the product to be checked for a warranty |
cart required |
object | BigCommerce cart object for the current cart |