How to Set Up Shoppable® DTC Lite (v5)

This article will walk you through how to get DTC Lite set up on your website or blog.

What is DTC LITE v5?

Shoppable® DTC Lite is a standardized Shoppable product that helps you embed Shoppable ecommerce technology on an existing faster. 

DTC Lite v5 is a compiled Es5 and Es6 compatible single file bundled app of our multi-retailer enabled shopping cart, allowing you to make any page Shoppable without the hassle and with no engineering lift required. Once you've implemented your own DTC Lite v5 Cart Script and load your page the cart authenticates itself through Oauth automatically connected to your main Shoppable Platform Account where you can access your cart builder to edit the look and other configurations for your cart. 

This guide will help you integrate Shoppable DTC Lite into your existing website. (If you don't have an existing website or application, you may want to check out Shoppable Instant Shop and Shoppable Ad Experience which do not require an existing website to use our technology.)

Jump to Section

  1. Cart, Checkout, and Order Confirmation Set up
  2. Product Selection
  3. Add Buy Button to your website
    1. Creating bundles
    2. Adding a PDP
  4. Cart Button/Icon
  5. Contact Your Customer Success Manager
  6. Send a Test Order
  7. Shoppable Events (Optional)
  8. ShoppableProduct() (Optional)
  9. Order Data API Setup (Select Access based on Subscription)

1. Cart, Checkout, and Order Confirmation Set up

A. Log into your Shoppable account and then mouse over "DTC Lite" in the left navigation.

Shoppable Cart Builder

B. Then click "Cart Builder" to open up your cart to begin customizing it.

C. Branding Section: 

1. Choose your font and highlight or accent color, then, hit "apply"

D. Thank You Page / Order Confirmation Page:

1. Upload your logo. Logo must be Transparent .Png, Minimum 365x120px

2. (Optional) Edit headline and body copy. If you like the default copy you can skip this step. If you edit the copy, select "apply" to see the changes reflected.

3. (Optional) Edit the copy on the email sign-up button.

E. Customer Relationship Management (CRM) Setup

1. (Optional) Edit the copy displayed with the email newsletter sign up

2. Paste in the link to your Privacy Policy and Terms of Use. Then hit "save"

Shoppable_-_Cart_Builder

2. Product Selection


A. Navigate to the left sidebar and hover over  "Products",  then select Find Products



B. Navigate to the search input and begin your search. You can search by keyword (ex. button up shirt) or UPC (ex. 309970231026, a 12 digit universal identifier)



C. Select the product you'd like to add and click on "Add Products", all new products selected will be added to your "My Products" any already existing won't add if you've selected them by error. Duplicate products can't exist in your account.



D. Navigate to the left sidebar and hover over  "Products",  then select My Products.



E. Navigate to the Product Card and click on and copy the "Buy-Button Embed Code". You have 2 different button variations you can select from:

No Variation: You can select this option if you would like for the button to add the exact product to the cart without the need for selecting variations (*if any applicable*).

<a class="btn ripple btn-primary text-center mb-2" style='width: 40%;' 
onclick="ShoppableCart({upc: '309972924605', variation: false});">Add Item 1</a>

With Variations: You can select this option if you would like for the button to add the product to the cart with a variation selector (a choice of Size or Color that takes place on the cart) (*if any applicable*).

<a class="btn ripple btn-primary text-center mb-2" style='width: 40%;' 
onclick="ShoppableCart({upc: '309972924605', variation: true});">Add Item 1</a>

F. Once you've selected a button and copied it you can then paste it on any page you have the DTC Lite V5 Cart Script in. 

Here's an example:

Shoppable Buy Buttons:

Shoppable DTC LITE v5 Script:

Our Buy Buttons have a simple onClick event that triggers our function to add the specific UPC you've selected to the cart. You are not bound to our Buy Buttons, you can initiate the same function with your own triggers/custom code. 

Our functions are bound to the window, you can access the Add To Cart function in the following method if you choose to build a more custom process.


Add To Cart (function)

ShoppableCart({upc: '381370033677', variation: false})

Parameters:

upc (String and/or Array): Unique 12 digit identifier for the selected product.  
variation (Boolean)(*if any applicable*): The option to have the selection of a products variation be displayed on the cart if set to "true"

 

Product Bundling:

Add Bundles to Cart (function)

ShoppableCart({upc: ['381370033677', '309976012100'], variation: false})

Parameters:

upc (Array): Unique 12 digit identifier for the products you'd like to add to the cart. The items will add to the cart based on the index order of the UPCs in the array.  
variation (Boolean)(*if any applicable*): The option to have the selection of a products variation be displayed on the cart if set to "true". If variation is set to 'true' for Bundles of products each selection must be made prior to adding to the cart. 

 

Pop-up PDP (function)

ShoppableCart({upc: ['381370033677'], variation: false, pdp: true})

Parameters:

upc (Array [*required*]): Unique 12 digit identifier. The parameter type could be an Array or a String, only a single value could be used, if an array is provided then only the first index value will be used. 
variation (Boolean [*not required*]): The option to have the selection of a products variation is displayed on the PDP regardless of the value in this parameter.

pdp (Boolean [*required*])The option to show a pop-up (in modal) PDP (product page), with the ability to select variations and quantity then add to cart from directly from the PDP.

3. Add Cart and Checkout Script Widget to your Website

 A. Mouse over "DTC Lite" in the left navigation, then select "Copy Cart Script"

Screen Shot 2021-07-27 at 9.32.34 PM

B. Paste the script right before the closing body tag (</body>) of your HTML document. This will ensure the script does not conflict with other potential scripts on the page.

Screen Shot 2021-07-29 at 5.19.09 PM

4. Cart Button/Icon

With our new version 5, you can either use the cart/shopping bag icon provided from the bundle automatically or create your icon for more customization. The bundle automatically recognizes the cart quantity id and hides the shoppable cart icon. If you wish to use the Shoppable Cart Icon then make sure to *not add the cart quantity id to any of the pages you have the script attached to.

How to build and manage your own cart button:

Shoppable Cart Quantity: We provide you with a unique Shoppable ID that when placed on any HTML element it will automatically append the Cart Quantity dynamically.

Cart Quantity ID: 

shoppable__cart__qty__v5

Example: 

<span id="shoppable__cart__qty__v5"> </span>

Shoppable Cart Toggle: We've also made available through the browser window an additional function that allows you to toggle the Shoppable cart.

Toggle Cart Function: 

window.ToggleShoppableCart()

Example: 

<button onclick={window.ToggleShoppableCart()}>
<span id="shoppable__cart__qty__v5"> </span>
</button>

5. Contact Your Customer Success Manager

Now contact your Customer Success Manager to let them know you're ready to launch. They will assist you with final checks before you launch. If you don't have a CSM, please email CS@shoppable.com 

6. Send a Test Order

Lastly, send an order through to test your experience. Test orders can be tested on checkout using the test card number 4111111111111111 and number entries for EXP Dates(must be in future) and CVV.

7. Shoppable Events (Optional)

We have created tracking events based on the shopper's usage of the cart. You can subscribe to these events and use the information to integrate them into your custom analytics platform. 

You can subscribe to events with the following method:

ShoppableEvents("TYPE", function(type, data) {console.log(type, data);})

There are different types of events you can subscribe to, according to your use case:

Event Types: 

Detailed: You'll need to subscribe to each individual event accordingly. Each event will have custom shoppable-built event objects based on each type. Each event will include in it

{ShoppableCart: {Object}, ShoppableEvent: {Object}, Time: String}

Type: 'ADD_TO_CART'

ShoppableCart: Includes the current state of the cart.

ShoppableCart: {
currentState: {
cartInfo: {
  partnerId: String,
customerId: String,
  partnerName: String,
  createdOn: String,
  modifiedOn: String,
  quantity: Number,
  merchants: Object,
  totalNan: Number,
  total: String,
    shippingNan: Number,
  subtotalNan: Number,
  subtotal: String,
  shipping: String,
  cartId: String,
  metadata: Object,
  error: Boolean
},
      selectedRetailers: [{
      merchantId: String,
      linkOff: Boolean,
      legacyId: String,
      digitalOnly: Boolean,
      source: String,
      freeShipping: Number,
      maxQuantity: Number,
      shippingCharge: String,
      shippingChargeNan: Number,
      shippingChargeNanLegacy: Number,
      merchantLogo: String,
      quantity: Number,
      customerServiceUrl: String,
      returnPolicy: String,
      selected: Boolean,
      items: Array,
      subtotal: String,
      subtotalNan: Number,
      upcs: Array,
      merchant: String,
      totalNan: Number,
      total: String
}],
       availableRetailers: [{
         groupedIndex: String,
        merchants: Array,
         linkOffMerchants: Array
        }],
        items: [{
      qty: Number,
      id: String,
        partNumber: String,
      name: String,
      merchant: String,
        merchantId: String,
      brand: String,
      category: String,
        merchantSku: String,
      upc: String,
      description: String,
        url: String,
      salePrice: Number,
      price: Number,
      size: String,
        color: String,
      status: Number,
      image: String,
        images: Array,
      asin: String,
      merchantLogo: String,
        maxQuantity: Number,
      shippingCharge: String,
      freeShipping: String,
        customerServiceUrl: String,
      returnPolicy: String
        }]
}
}

ShoppableEvent: Includes a product event.

ShoppableEvent: {
upc: String,
brand: String,
name: String,
color: String,
size: String,
price: String,
quantity: String,
total: String,
image: String,
retailer: String,
retailerTotal: String
}

Type: 'RETAILER_UPDATE'

ShoppableCart: Includes the current state and previous state of the cart.

ShoppableCart: {
currentState: {
cartInfo: {
  partnerId: String,
  customerId: String,
  partnerName: String,
  createdOn: String,
  modifiedOn: String,
  quantity: Number,
  merchants: Object,
  totalNan: Number,
  total: String,
  shippingNan: Number,
  subtotalNan: Number,
  subtotal: String,
  shipping: String,
  cartId: String,
  metadata: Object,
  error: Boolean
},
  selectedRetailers: [{
      merchantId: String,
      linkOff: Boolean,
      legacyId: String,
      digitalOnly: Boolean,
      source: String,
      freeShipping: Number,
      maxQuantity: Number,
      shippingCharge: String,
      shippingChargeNan: Number,
      shippingChargeNanLegacy: Number,
      merchantLogo: String,
      quantity: Number,
      customerServiceUrl: String,
      returnPolicy: String,
      selected: Boolean,
      items: Array,
      subtotal: String,
      subtotalNan: Number,
      upcs: Array,
      merchant: String,
      totalNan: Number,
      total: String
        }],
        availableRetailers: [{
           groupedIndex: String,
          merchants: Array,
           linkOffMerchants: Array
        }],
        items: [{
      qty: Number,
      id: String,
      partNumber: String,
      name: String,
      merchant: String,
      merchantId: String,
      brand: String,
      category: String,
      merchantSku: String,
      upc: String,
      description: String,
      url: String,
      salePrice: Number,
      price: Number,
      size: String,
      color: String,
      status: Number,
      image: String,
      images: Array,
      asin: String,
      merchantLogo: String,
      maxQuantity: Number,
      shippingCharge: String,
      freeShipping: String,
      customerServiceUrl: String,
      returnPolicy: String
        }]
},
previousState: {
cartInfo: {
  partnerId: String,
  customerId: String,
  partnerName: String,
  createdOn: String,
  modifiedOn: String,
  quantity: Number,
  merchants: Object,
  totalNan: Number,
  total: String,
  shippingNan: Number,
  subtotalNan: Number,
  subtotal: String,
  shipping: String,
  cartId: String,
  metadata: Object,
  error: Boolean
},
    selectedRetailers: [{
      merchantId: String,
      linkOff: Boolean,
      legacyId: String,
      digitalOnly: Boolean,
      source: String,
      freeShipping: Number,
      maxQuantity: Number,
      shippingCharge: String,
      shippingChargeNan: Number,
      shippingChargeNanLegacy: Number,
      merchantLogo: String,
      quantity: Number,
      customerServiceUrl: String,
      returnPolicy: String,
      selected: Boolean,
      items: Array,
      subtotal: String,
      subtotalNan: Number,
      upcs: Array,
      merchant: String,
      totalNan: Number,
      total: String
    }],
    availableRetailers: [{
        groupedIndex: String,
        merchants: Array,
        linkOffMerchants: Array
    }],
    items: [{
      qty: Number,
      id: String,
      partNumber: String,
      name: String,
      merchant: String,
      merchantId: String,
      brand: String,
      category: String,
      merchantSku: String,
      upc: String,
      description: String,
      url: String,
      salePrice: Number,
      price: Number,
      size: String,
      color: String,
      status: Number,
      image: String,
      images: Array,
      asin: String,
      merchantLogo: String,
      maxQuantity: Number,
      shippingCharge: String,
      freeShipping: String,
      customerServiceUrl: String,
      returnPolicy: String
        }]
}
}

ShoppableEvent: Includes a merchant event, includes the previous retailer and selected retailer.

ShoppableEvent: {
previousRetailer: {
    merchantId: String,
    linkOff: Boolean,
    legacyId: String,
    digitalOnly: Boolean,
    source: String,
    freeShipping: Number,
    maxQuantity: Number,
    shippingCharge: String,
    shippingChargeNan: Number,
    shippingChargeNanLegacy: Number,
    merchantLogo: String,
    quantity: Number,
    customerServiceUrl: String,
    returnPolicy: String,
    selected: Boolean,
    items: Array,
    subtotal: String,
    subtotalNan: Number,
    upcs: Array,
    merchant: String,
    totalNan: Number,
    total: String
  },
selectedRetailer: {
    merchantId: String,
    linkOff: Boolean,
    legacyId: String,
    digitalOnly: Boolean,
    source: String,
    freeShipping: Number,
    maxQuantity: Number,
    shippingCharge: String,
    shippingChargeNan: Number,
    shippingChargeNanLegacy: Number,
    merchantLogo: String,
    quantity: Number,
    customerServiceUrl: String,
    returnPolicy: String,
    selected: Boolean,
    items: Array,
    subtotal: String,
    subtotalNan: Number,
    upcs: Array,
    merchant: String,
    totalNan: Number,
    total: String
  }
}

Type: 'QTY_INCREASE'

ShoppableCart: Includes the current state and previous state of the cart.

ShoppableCart: {
currentState: {
cartInfo: {
  partnerId: String,
    customerId: String,
  partnerName: String,
  createdOn: String,
  modifiedOn: String,
  quantity: Number,
  merchants: Object,
  totalNan: Number,
  total: String,
  shippingNan: Number,
  subtotalNan: Number,
  subtotal: String,
  shipping: String,
  cartId: String,
  metadata: Object,
  error: Boolean
},
    selectedRetailers: [{
      merchantId: String,
      linkOff: Boolean,
      legacyId: String,
      digitalOnly: Boolean,
      source: String,
      freeShipping: Number,
      maxQuantity: Number,
      shippingCharge: String,
      shippingChargeNan: Number,
      shippingChargeNanLegacy: Number,
      merchantLogo: String,
      quantity: Number,
      customerServiceUrl: String,
      returnPolicy: String,
      selected: Boolean,
      items: Array,
      subtotal: String,
      subtotalNan: Number,
      upcs: Array,
      merchant: String,
      totalNan: Number,
      total: String
    }],
    availableRetailers: [{
        groupedIndex: String,
        merchants: Array,
        linkOffMerchants: Array
    }],
    items: [{
      qty: Number,
      id: String,
      partNumber: String,
      name: String,
      merchant: String,
      merchantId: String,
      brand: String,
      category: String,
      merchantSku: String,
      upc: String,
      description: String,
      url: String,
      salePrice: Number,
      price: Number,
      size: String,
      color: String,
      status: Number,
      image: String,
      images: Array,
      asin: String,
      merchantLogo: String,
      maxQuantity: Number,
      shippingCharge: String,
      freeShipping: String,
      customerServiceUrl: String,
      returnPolicy: String
        }]
},
previousState: {
cartInfo: {
  partnerId: String,
  customerId: String,
  partnerName: String,
  createdOn: String,
  modifiedOn: String,
  quantity: Number,
  merchants: Object,
  totalNan: Number,
  total: String,
  shippingNan: Number,
  subtotalNan: Number,
  subtotal: String,
  shipping: String,
  cartId: String,
  metadata: Object,
  error: Boolean
},
    selectedRetailers: [{
      merchantId: String,
      linkOff: Boolean,
      legacyId: String,
      digitalOnly: Boolean,
      source: String,
      freeShipping: Number,
      maxQuantity: Number,
      shippingCharge: String,
      shippingChargeNan: Number,
      shippingChargeNanLegacy: Number,
      merchantLogo: String,
      quantity: Number,
      customerServiceUrl: String,
      returnPolicy: String,
      selected: Boolean,
      items: Array,
      subtotal: String,
      subtotalNan: Number,
      upcs: Array,
      merchant: String,
      totalNan: Number,
      total: String
    }],
    availableRetailers: [{
        groupedIndex: String,
        merchants: Array,
        linkOffMerchants: Array
    }],
    items: [{
      qty: Number,
      id: String,
      partNumber: String,
      name: String,
      merchant: String,
      merchantId: String,
      brand: String,
      category: String,
      merchantSku: String,
      upc: String,
      description: String,
      url: String,
      salePrice: Number,
      price: Number,
      size: String,
      color: String,
      status: Number,
      image: String,
      images: Array,
      asin: String,
      merchantLogo: String,
      maxQuantity: Number,
      shippingCharge: String,
      freeShipping: String,
      customerServiceUrl: String,
      returnPolicy: String
        }]
}
}

ShoppableEvent: Includes a product event.

ShoppableEvent: {
upc: String,
brand: String,
name: String,
color: String,
size: String,
price: String,
quantity: String,
total: String,
image: String,
retailer: String,
retailerTotal: String
}

Type: 'QTY_DECREASE'

ShoppableCart: Includes the current state and previous state of the cart.

ShoppableCart: {
currentState: {
cartInfo: {
  partnerId: String,
  customerId: String,
  partnerName: String,
  createdOn: String,
  modifiedOn: String,
  quantity: Number,
  merchants: Object,
  totalNan: Number,
  total: String,
  shippingNan: Number,
  subtotalNan: Number,
  subtotal: String,
  shipping: String,
  cartId: String,
  metadata: Object,
  error: Boolean
},
     selectedRetailers: [{
           merchantId: String,
      linkOff: Boolean,
      legacyId: String,
      digitalOnly: Boolean,
    source: String,
      freeShipping: Number,
      maxQuantity: Number,
      shippingCharge: String,
      shippingChargeNan: Number,
      shippingChargeNanLegacy: Number,
      merchantLogo: String,
      quantity: Number,
      customerServiceUrl: String,
      returnPolicy: String,
      selected: Boolean,
      items: Array,
      subtotal: String,
      subtotalNan: Number,
      upcs: Array,
      merchant: String,
      totalNan: Number,
      total: String
     }],
     availableRetailers: [{
          groupedIndex: String,
          merchants: Array,
          linkOffMerchants: Array
     }],
     items: [{
      qty: Number,
      id: String,
      partNumber: String,
      name: String,
      merchant: String,
      merchantId: String,
      brand: String,
      category: String,
      merchantSku: String,
      upc: String,
      description: String,
      url: String,
      salePrice: Number,
      price: Number,
      size: String,
      color: String,
      status: Number,
      image: String,
      images: Array,
      asin: String,
      merchantLogo: String,
      maxQuantity: Number,
      shippingCharge: String,
      freeShipping: String,
      customerServiceUrl: String,
      returnPolicy: String
        }]
},
previousState: {
cartInfo: {
  partnerId: String,
  customerId: String,
  partnerName: String,
  createdOn: String,
  modifiedOn: String,
  quantity: Number,
  merchants: Object,
  totalNan: Number,
  total: String,
  shippingNan: Number,
  subtotalNan: Number,
  subtotal: String,
  shipping: String,
  cartId: String,
  metadata: Object,
  error: Boolean
},
     selectedRetailers: [{
      merchantId: String,
      linkOff: Boolean,
      legacyId: String,
      digitalOnly: Boolean,
      source: String,
      freeShipping: Number,
      maxQuantity: Number,
      shippingCharge: String,
      shippingChargeNan: Number,
      shippingChargeNanLegacy: Number,
      merchantLogo: String,
      quantity: Number,
      customerServiceUrl: String,
      returnPolicy: String,
      selected: Boolean,
      items: Array,
      subtotal: String,
      subtotalNan: Number,
      upcs: Array,
      merchant: String,
      totalNan: Number,
      total: String
     }],
     availableRetailers: [{
         groupedIndex: String,
         merchants: Array,
         linkOffMerchants: Array
     }],
     items: [{
      qty: Number,
      id: String,
      partNumber: String,
      name: String,
      merchant: String,
      merchantId: String,
      brand: String,
      category: String,
      merchantSku: String,
      upc: String,
      description: String,
      url: String,
      salePrice: Number,
      price: Number,
      size: String,
      color: String,
      status: Number,
      image: String,
      images: Array,
      asin: String,
      merchantLogo: String,
      maxQuantity: Number,
      shippingCharge: String,
      freeShipping: String,
      customerServiceUrl: String,
      returnPolicy: String
        }]
}
}

ShoppableEvent: Includes a product event.

ShoppableEvent: {
upc: String,
brand: String,
name: String,
color: String,
size: String,
price: String,
quantity: String,
total: String,
image: String,
retailer: String,
retailerTotal: String
}

Type: 'ITEM_REMOVED'

ShoppableCart: Includes the current state and previous state of the cart.

ShoppableCart: {
currentState: {
cartInfo: {
  partnerId: String,
  customerId: String,
  partnerName: String,
  createdOn: String,
  modifiedOn: String,
  quantity: Number,
  merchants: Object,
  totalNan: Number,
  total: String,
  shippingNan: Number,
  subtotalNan: Number,
  subtotal: String,
  shipping: String,
  cartId: String,
  metadata: Object,
  error: Boolean
},
       selectedRetailers: [{
      merchantId: String,
      linkOff: Boolean,
      legacyId: String,
      digitalOnly: Boolean,
      source: String,
      freeShipping: Number,
      maxQuantity: Number,
      shippingCharge: String,
      shippingChargeNan: Number,
      shippingChargeNanLegacy: Number,
      merchantLogo: String,
      quantity: Number,
      customerServiceUrl: String,
      returnPolicy: String,
      selected: Boolean,
      items: Array,
      subtotal: String,
      subtotalNan: Number,
      upcs: Array,
      merchant: String,
      totalNan: Number,
      total: String
       }],
       availableRetailers: [{
           groupedIndex: String,
           merchants: Array,
           linkOffMerchants: Array
       }],
       items: [{
      qty: Number,
      id: String,
      partNumber: String,
      name: String,
      merchant: String,
      merchantId: String,
      brand: String,
      category: String,
      merchantSku: String,
      upc: String,
      description: String,
      url: String,
      salePrice: Number,
      price: Number,
      size: String,
      color: String,
      status: Number,
      image: String,
      images: Array,
      asin: String,
      merchantLogo: String,
      maxQuantity: Number,
      shippingCharge: String,
      freeShipping: String,
      customerServiceUrl: String,
      returnPolicy: String
       }],
},
previousState: {
cartInfo: {
  partnerId: String,
customerId: String,
partnerName: String,
  createdOn: String,
modifiedOn: String,
quantity: Number,
merchants: Object,
totalNan: Number,
  total: String,
  shippingNan: Number,
  subtotalNan: Number,
subtotal: String,
shipping: String,
cartId: String,
metadata: Object,
error: Boolean
},
       selectedRetailers: [{
      merchantId: String,
      linkOff: Boolean,
      legacyId: String,
      digitalOnly: Boolean,
      source: String,
      freeShipping: Number,
      maxQuantity: Number,
      shippingCharge: String,
      shippingChargeNan: Number,
      shippingChargeNanLegacy: Number,
      merchantLogo: String,
      quantity: Number,
      customerServiceUrl: String,
      returnPolicy: String,
      selected: Boolean,
      items: Array,
      subtotal: String,
      subtotalNan: Number,
      upcs: Array,
      merchant: String,
      totalNan: Number,
      total: String
       }],
       availableRetailers: [{
           groupedIndex: String,
           merchants: Array,
           linkOffMerchants: Array
       }],
       items: [{
      qty: Number,
      id: String,
      partNumber: String,
      name: String,
      merchant: String,
      merchantId: String,
      brand: String,
      category: String,
      merchantSku: String,
      upc: String,
      description: String,
      url: String,
      salePrice: Number,
      price: Number,
      size: String,
      color: String,
      status: Number,
      image: String,
      images: Array,
      asin: String,
      merchantLogo: String,
      maxQuantity: Number,
      shippingCharge: String,
      freeShipping: String,
      customerServiceUrl: String,
      returnPolicy: String
        }]
}
}

ShoppableEvent: Includes a product event.

ShoppableEvent: {
upc: String,
brand: String,
name: String,
color: String,
size: String,
price: String,
quantity: String,
image: String,
retailer: String,
}

Type: 'CHECKOUT'

ShoppableCart: Includes the current state of the cart.

ShoppableCart: {
    currentState: {
       cartInfo: {
  partnerId: String,
  customerId: String,
  partnerName: String,
  createdOn: String,
  modifiedOn: String,
  quantity: Number,
  merchants: Object,
  totalNan: Number,
  total: String,
  shippingNan: Number,
  subtotalNan: Number,
  subtotal: String,
  shipping: String,
  cartId: String,
  metadata: Object,
  error: Boolean
       },
      selectedRetailers: [{
      merchantId: String,
      linkOff: Boolean,
      legacyId: String,
      digitalOnly: Boolean,
        source: String,
      freeShipping: Number,
      maxQuantity: Number,
      shippingCharge: String,
      shippingChargeNan: Number,
      shippingChargeNanLegacy: Number,
      merchantLogo: String,
      quantity: Number,
      customerServiceUrl: String,
      returnPolicy: String,
      selected: Boolean,
      items: Array,
      subtotal: String,
      subtotalNan: Number,
      upcs: Array,
      merchant: String,
      totalNan: Number,
      total: String
       }],
       availableRetailers: [{
          groupedIndex: String,
          merchants: Array,
          linkOffMerchants: Array
       }],
       items: [{
      qty: Number,
      id: String,
      partNumber: String,
      name: String,
    merchant: String,
      merchantId: String,
      brand: String,
      category: String,
      merchantSku: String,
      upc: String,
      description: String,
      url: String,
      salePrice: Number,
      price: Number,
      size: String,
      color: String,
      status: Number,
      image: String,
      images: Array,
      asin: String,
      merchantLogo: String,
      maxQuantity: Number,
      shippingCharge: String,
      freeShipping: String,
      customerServiceUrl: String,
      returnPolicy: String
       }]
    }
}

ShoppableEvent: Includes a checkout event.

ShoppableEvent: {
orderNumber: String
}

Actions: You can subscribe to this event get all actions in relation to the cart. Subscribing to this single event will provide you with all actions throughout the different interactions between the shopper and the cart. You'll always receive the current state of the cart along with the type of action.

Types:

  • CART_INITIALIZED
  • CART_CLOSED
  • CART_OPEN
  • ADD_TO_CART
  • ON_CHECKOUT_VIEW
  • ORDER_PLACED
  • ON_THANK_YOU_VIEW
  • RETAILER_UPDATE
  • QTY_INCREASE
  • QTY_DECREASE
  • ITEM_REMOVED
  • EMAIL_SECTION_INPUT
  • OPT_IN_SECTION_OFF
  • OPT_IN_SECTION_ON
  • SHIPPING_SECTION
  • BILLING_SECTION

ShoppableCart: Includes the current state and previous state of the cart.

ShoppableCart: {
    currentState: {
       cartInfo: {
  partnerId: String,
  customerId: String,
  partnerName: String,
  createdOn: String,
  modifiedOn: String,
  quantity: Number,
  merchants: Object,
  totalNan: Number,
  total: String,
  shippingNan: Number,
  subtotalNan: Number,
  subtotal: String,
  shipping: String,
  cartId: String,
  metadata: Object,
  error: Boolean
       },
   selectedRetailers: [{
        merchantId: String,
      linkOff: Boolean,
      legacyId: String,
      digitalOnly: Boolean,
      source: String,
      freeShipping: Number,
      maxQuantity: Number,
      shippingCharge: String,
      shippingChargeNan: Number,
      shippingChargeNanLegacy: Number,
      merchantLogo: String,
      quantity: Number,
      customerServiceUrl: String,
      returnPolicy: String,
      selected: Boolean,
      items: Array,
      subtotal: String,
      subtotalNan: Number,
      upcs: Array,
      merchant: String,
      totalNan: Number,
      total: String
       }],
       availableRetailers: [{
           groupedIndex: String,
           merchants: Array,
           linkOffMerchants: Array
       }],
       items: [{
      qty: Number,
      id: String,
      partNumber: String,
      name: String,
      merchant: String,
      merchantId: String,
      brand: String,
      category: String,
      merchantSku: String,
      upc: String,
      description: String,
      url: String,
      salePrice: Number,
      price: Number,
      size: String,
      color: String,
      status: Number,
      image: String,
      images: Array,
      asin: String,
      merchantLogo: String,
      maxQuantity: Number,
      shippingCharge: String,
      freeShipping: String,
      customerServiceUrl: String,
      returnPolicy: String
       }]
    }
}

ShoppableEvent: Includes a product event.

ShoppableEvent: {
type: String
}

Form Actions: You can subscribe to this event get all actions in relation to the form inputs. Subscribing to this single event will provide you with all actions throughout the different form inputs entered by the shopper. You'll always receive the current state of the cart along with this type of action.

Types:

  • EMAIL_INPUT
  • OPT_IN_SECTION_OFF
  • OPT_IN_SECTION_ON
  • SHIPPING_FIRST_NAME_INPUT
  • SHIPPING_LAST_NAME_INPUT
  • SHIPPING_ADDRESS_INPUT
  • SHIPPING_ADDRESS_TWO_INPUT
  • SHIPPING_CITY_INPUT
  • SHIPPING_ZIP_CODE_INPUT
  • SHIPPING_PHONE_INPUT
  • PAYMENT_CARD_INPUT
  • PAYMENT_EXPIRY_MONTH_INPUT
  • PAYMENT_EXPIRY_YEAR_INPUT
  • BILLING_FIRST_NAME_INPUT
  • BILLING_LAST_NAME_INPUT
  • BILLING_ADDRESS_INPUT
  • BILLING_ADDRESS_TWO_INPUT
  • BILLING_CITY_INPUT
  • BILLING_STATE_INPUT
  • BILLING_ZIP_CODE_INPUT

ShoppableCart: Includes the current state and previous state of the cart.

ShoppableCart: {
    currentState: {
       cartInfo: {
  partnerId: String,
  customerId: String,
  partnerName: String,
  createdOn: String,
  modifiedOn: String,
  quantity: Number,
  merchants: Object,
  totalNan: Number,
  total: String,
  shippingNan: Number,
  subtotalNan: Number,
  subtotal: String,
  shipping: String,
  cartId: String,
  metadata: Object,
  error: Boolean
       },
       selectedRetailers: [{
      merchantId: String,
      linkOff: Boolean,
      legacyId: String,
      digitalOnly: Boolean,
      source: String,
      freeShipping: Number,
      maxQuantity: Number,
      shippingCharge: String,
      shippingChargeNan: Number,
      shippingChargeNanLegacy: Number,
      merchantLogo: String,
      quantity: Number,
      customerServiceUrl: String,
      returnPolicy: String,
      selected: Boolean,
      items: Array,
      subtotal: String,
      subtotalNan: Number,
      upcs: Array,
      merchant: String,
      totalNan: Number,
      total: String
       }],
       availableRetailers: [{
           groupedIndex: String,
           merchants: Array,
           linkOffMerchants: Array
       }],
       items: [{
      qty: Number,
      id: String,
      partNumber: String,
      name: String,
      merchant: String,
      merchantId: String,
      brand: String,
      category: String,
      merchantSku: String,
      upc: String,
      description: String,
      url: String,
        salePrice: Number,
      price: Number,
      size: String,
      color: String,
      status: Number,
      image: String,
      images: Array,
      asin: String,
      merchantLogo: String,
      maxQuantity: Number,
      shippingCharge: String,
      freeShipping: String,
      customerServiceUrl: String,
      returnPolicy: String
       }]
    }
}

ShoppableEvent: Includes a product event.

ShoppableEvent: {
type: String
}

8. ShoppableProduct() (Optional)

This function was created to give customers the flexibility to accomplish two objectives:

a. Dynamically inject product data into HTML document
b. Retrieve product data and availability

ShoppableEvents() and Invoking ShoppableProduct() on Page Load

In order to invoke ShoppableProduct, we must wrap it within <script> tags and a ShoppableEvents function, which requires a couple of parameters (type, data) and a condition to ensure the Shoppable Cart has been initialized first.

This is required. 

<script>
  ShoppableEvents('ACTIONS', function (type, data) {
    if (data.ShoppableEvent.type === 'CART_INITIALIZED') {
    ShoppableProduct()
    }
  });
</script>


a. Dynamically inject product data into HTML document

ShoppableProduct({
upc: ['332171126074', '381456192098', '381364159604', '381382933615'],
type: ['price', 'status', 'variation', 'button']
}).then((upcDataResults) => {
console.log('*** Response ***', upcDataResults)
}).catch(err => console.log('*** Error ***', err))

Use Case: I would like to display updated product information on my PLP or PDP based on product availability and current merchant prices for each product. 

There are two parameters you will need to include in your function: upc and type. Up to four data types can be used to update your DOM's element. They are: button, price, status and variation. Please reference the Types section for a description of each type.

 

Parameter Type Min Qty Max Qty Values
upc array 1 12 universal product code, unique 12-Digit code
type string 1 4 button, price, status, variation

 

The 'type' parameter instructs ShoppableProduct to update your DOM element with product details for that UPC by targeting an element ID. It is not required to use all types.

For example, to display updated product prices based on merchant availability and let your customers know when a product is out of stock, only include price and status in your array. 

ShoppableProduct({
upc: ['332171126074'],
type: ['price', 'status']
})


Element ID:

In order to target your specific DOM element, ShoppableProduct concatenates upc and type. Subsequently, it searches for that element ID on your DOM. Please ensure your DOM's element IDs match this convention: 'upc_type'.

Example: 

ShoppableProduct({
upc: ['332171126074'],
type: ['price', 'status', 'variation', 'button']
})

ShoppableProduct will loop through your array of UPCs and Types to search your DOM for four elements in this example. The element IDs it will look for are: 

332171126074_price

332171126074_status

332171126074_variation

332171126074_button

<div>
Variation: <span id="332171126074_variation"></span>
</div>
<div>
Price: <span id="332171126074_price"></span>
</div>
<div>
Stock Status: <span id="332171126074_status"></span>
</div>
<div>
<button id="332171126074_button" onclick="ShoppableCart({upc: '332171126074', variation: false});">Add to Cart</button>
</div>

Response:

Append a then() method to ShoppableProduct to return a response object with error status and a message from the asynchronous operation. catch() will retrieve additional errors.

ShoppableProduct({
upc: ['332171126074', '381456192098', '381364159604', '381382933615'],
type: ['price', 'status', 'variation', 'button']
}).then((upcDataResults) => {
console.log('*** Response ***', upcDataResults)
}).catch(err => console.log('*** Error ***', err))


Error (Response) Object:

{
error: Boolean,
message: String
}

error - (false) if no errors and all DOM element ID's were injected with data || (true) if error exists and a specific element ID was not found on the document or the function was set up incorrectly. 

message - (error) with instructions || (success) all product elements have been updated

Example (Error - type not accepted):

  • type 'variations' is not accepted (types: button, price, status and variation)

Example (Error - element ID not found on DOM):

  • element ID '332171126074_variations' was not found because of a typo, which should have been '332171126074_variation' (convention: 'upc_type)

Example (Success - 🥳):

Parameters: 

'upc'

Description: Unique 12 digit identifier for the products you request details for 

Format: Array (strings) - ['UPC1', 'UPC2', 'UPC3', 'UPC4', 'UPC5']

Restrictions: Limit of 12 UPCs

'type'

Description: the product data you request for each UPC and use to update your DOM element ID 

Format: Array (strings) - ['button', 'price', 'status', 'variation']

Restrictions: You can use any or all data types 

Types (Explained): 

Type: 'button'

ShoppableProduct({ upc: ['UPC'], type: ['button'] })

Functionality: Search the DOM for your button's ID ('UPC_button') to add the attribute of disabled to your button, or update CSS { pointerEvents: 'none', opacity: '0.65' } for a tags used as buttons. 

Use Case: Enable/disable a 'Buy Now' button on your PLP/PDP based on product availability.


Type: 'price'

ShoppableProduct({ upc: ['UPC'], type: ['price'] })

Functionality:  Search the DOM for your element's ID ('UPC_price') to inject the price of the UPC in the document. Returns a price range (i.e. $1.99-$4.99) or a single price value ($1.99) if the range contains the same value for all merchants.

Use Case: Dynamically update the price details for the targeted UPC on your PLP/PDP. 


Type: 'status'

ShoppableProduct({ upc: ['UPC'], type: ['status'] })

Functionality:  Search the DOM for your element's ID ('UPC_status') to inject the product availability of the UPC in the document. Returns message: 'In Stock' or 'Out of Stock'

Use Case: Display an 'Out of Stock' message for a product that is not in stock at any merchants.


Type: 'variation'

ShoppableProduct({ upc: ['UPC'], type: ['variation'] })

Functionality: Search the DOM for your element's ID ('UPC_variation') to inject the variation (color/size) details (i.e. 12 fl oz) of the UPC in the document.

Use Case: Generate content for the targeted UPC's product variation details on your PLP/PDP.  

b. Retrieve product data and availability

While it is always required that you include UPCs in ShoppableProduct(), it is not necessary to include the 'type' parameter if you do not want DOM manipulation.

ShoppableProduct({
upc: ['332171126074', '381456192098', '381364159604', '381382933615']
}).then((upcDataResults) => {
console.log('*** Response ***', upcDataResults)
}).catch(err => console.log('*** Error ***', err))


This is very useful if you would like to retrieve product details for each UPC in a response object to manage the data how it best fits your organization's goals. 

Response:

The response data will the UPCs that are ins stock, and their properties in reference to stock availability, image, name, price, related products and color/size.


Product Data (Response) Object:

// UPC does have related products
{
UPC: {
active: Boolean,
  image: String,
  name: String,
  price: String,
   variations: [
     {
active: Boolean,
image: String,
name: String,
price: String,
upc: String,
variation: String
}
],
stockMessage: String,
  variation: String
}
}
// UPC does not have related products
{
UPC: {
active: Boolean,
image: String,
name: String,
price: String,
related_products: [],
   stockMessage: String,
variation: String
}
}
// Out of stock UPC will return static information
{
UPC: {
active: false,
  name: "OOS - Name",
   stockMessage: String,
  upc: String
}
}

Returned Data:

active - boolean value for stock availability from merchants

imageimage of product

name - name of product

price - price range ($1.99-$4.99) or a single price value ($1.99), if the range contains the same value for all merchants

variations - variations for the product, if available

stockMessage - stock availability message: "In Stock" or "Out of Stock"

variation - color and/or size of the product, if available

upc - UPC (only for out of stock items)

Example (Response Data):

Screen Shot 2022-08-22 at 2.57.59 PM

Example (Response Data, Out of Stock):
Screen Shot 2022-08-22 at 2.54.16 PM

9. Order Data API Setup (Select Access based on Subscription)

The Order API is included in all Enterprise licenses, but it is not available for all other subscription levels. Please see your subscription level and the Shoppable pricing page for more details or contact sales to upgrade.

In order to access the Order Data API, you will need API credentials from your customer success manager. When you are ready to implement it, please follow the Order Data API Setup documentation here