NAV Navbar
javascript

Introduction

You can integrate Tipser in your website in multiple ways. The fastest way is to use Tipser Elements or Tipser React Elements - a complete toolkit of native commerce experience that requires less than 5 minutes of tech setup.

Need more control? Head out to Tipser SDK section for low-level JavaScript SDK or go check sections for advanced integrations, such as integrating AMP or setting up tracking with Analytics.

Tipser Elements

Tipser Elements is a set of shoppable elements built on top of Tipser REST API and Tipser SDK:

Tipser Elements


Quick start

This quick guide explains how to intialize and render Tipser Elements on your page. It requires you to have a publisher account created in order to get the posId, as well as have some collections created in your shop. For a guide how to manage your collections, check the Tipser Tools tutorial.

If you're all set up, follow these three steps to install Tipser Elements on your site!


Installation of Tipser Elements

To use Tipser Elements on your site, add the following script to your page. This is an entry point to Tipser Elements that exposes a global tipser object, that you will use later to initialize Elements and customize its behavior.

<script src="https://cdn.tipser.com/tipser-script/latest.js"></script>

Inserting Tipser Element

Insert this HTML snippet on your page in the place where you want the Store element to be rendered. Typically, this will be a new blank subpage created in your CMS, as the Store is best displayed in the full page mode.

<div id="tipser_store"></div>

Initializing Tipser Elements

Initializing Tipser Elements is a line of JavaScript code.

tipser.elements('posId')

Make sure that the posId is replaced with the actual id corresponding to your account.

If you need to pass custom settings (see: configuration), you can pass an options object as second argument.

tipser.elements('posId', options)

Complete working example could look like:

<!DOCTYPE html>
<html>
  <body>
    <div id="tipser_store"></div>
    <script src="https://cdn.tipser.com/tipser-script/latest.js"></script>
    <script>
      tipser.elements('posId')
    </script>
  </body>
</html>

If everything was setup correctly, you should see the Store element populated with all your collections in place of <div id="tipser_store">.

Tipser elements store

Open this snippet on Code Pen


Configuration

Main Tipser Elements function has two arguments.

tipser.elements(posId: string, config?: TipserElementsConfig)

Store Element

The Store is the best way to present a group of collections on a separate page. It is best to place it on a page where sufficient space is available, however, the script automatically blends in and adapts to the given space.

Collections are created using the Tipser Tools, or on "Manage store" dashboard on tipser.com (when logged in to a publisher account).

Before you insert Store on your page, make sure there is at least one collection created in your store, otherwise no content will be rendered.

Insert the following HTML snippet in your code in the place where you want the Store element to be rendered.

<div id="tipser_store"></div>

Product Element

In order to insert a Product Element in your content, insert the following code snippet in your content:

<div data-tipser-pid="5ba2334a781baa0001ccdf61" />

Elements with attribute data-tipser-pid will be replaced with Product Element. Product ID is taken from the value of the attribute. The code snippet for a certain product can be generated with tipser tools automatically. By default, a full inline product component is displayed (with product details and variant selection).

Full product


To display Product in a compact view, add the data-tipser-view="compact" attribute to above tag.

<div data-tipser-pid="57233dac89862012f8ec1001" data-tipser-view="compact" />

Compact product

To display a list of products (rendered as small product tiles), add data-tipser-pids attribute to the snippet together with the productIds of the products you would like to display.

<div data-tipser-pids="5a8ac10d9d2580326ca4cf47,5a9735d99d25801620c3d3fc,5a8af4909d2580132ca4c1f9" />

Product list


Collection Element

Collection is a group of simple product tiles. Clicking on any title displays a product dialog with more product details and add to cart button. Products displayed in a collection are defined in the tipser tools.

<p name="My collection" data-tipser-cid="5b2788909d25801adcb23f4f" />
<p name="My collection" data-tipser-cid="5b2788909d25801adcb23f4f" data-tipser-imgsize="small" />
<p name="My collection" data-tipser-cid="5b2788909d25801adcb23f4f" data-tipser-carousel />

Elements with attribute data-tipser-cid will be replaced with Collection element of given id (value of data-tipser-cid).

Collection

To make the collection items smaller / larger use the data-tipser-imgsize attribute with values small for smaller and large for lager product tiles. The default value for imgSize parameter is medium. When changing the value to small you get slightly smaller product-cards:

Collection imgsize

If you'd like the collection of more than several products to take less space, you can display it as one-row only carousel element. To do that, please use data-tipser-carousel attribute.

Collection carousel

Open this snippet on Code Pen


Cart Element

To keep the user informed about the state of their shopping cart and make it possible to finalize the checkout process at any time, you can attach a live shopping cart icon on your page.

tipser.elements('posId')
      .mountCart('.my-cart-container');

To activate the Cart, you need to dedicate an element on your page to host a shopping cart and pass a CSS selector to that element to the mountCart function, as in the example snippet.

The cart icon can be placed anywhere on your website. If you want to keep it visible at all times, please follow the instructions.

Versioning

Tipser Elements follows Semantic Versioning. This means that an increase in the major number in our version indicates potential breaking changes. Please be aware of that! For the react version, it is recommended to auto-update to the latest version with the same major number (see the caret (^) character in package.json file described here).

API reference

All configuration supported by Tipser Elements is listed below.

Parameter Default Description Example
lang 'en-US' a locale to be used by the Tipser content. Possible values: 'en-US', 'de-DE', 'fr-FR' and 'sv-SE'. More info at Language and localeEnvironment 'de-DE'
env 'prod' Tipser environment to be used by the Tipser content. Possible values: 'stage' and 'prod'. More info at Environment 'stage'
defaultAddedToCartPopup true Controls default Added To Cart Popup. It appears when user adds a product to the cart. It improves UX by highlighting the action and allowing to navigate quickly to the cart modal window. true or false
useDefaultErrorHandler true when set to false and error happens, default message won't be displayed see Adding onError handler
eventsHandlers {} the object of event handlers. See Event handlers object
useDeepLinking true Makes Shop element to use hash navigation when switching between categories. More info at Use Deep Linking: false
modalUi {} Customization of Tipser Dialog. More info at Parameters for dialog customization { hideSearchIcon : true}
primaryColor #333 Hex color code, affecting eg. buy-button color and Cart indicator #5F9F9F
disableDialog false If set to true, a redirect to the product page is done instead of opening the product dialog (read more at: Embedding Elements in native apps section) false

Event handlers

Event handlers can be passed as part of configuration. There is a number of event exposed by the Tipser Elements that can be listened to programatically, such as technical events, shopping behavior, errors and analytics. You may hook in your event listener into Tipser Elements via eventsHandlers option.

 tipser.elements('posId', { 
    eventsHandlers: {
      onAddToCart: payload => {
          console.log('Hurray, you have added item to cart. ', payload.product);
          console.log('Your cart size is now. ', payload.cartSize);
      }
    }
  })

Whenever an event occurs, Tipser Elements will call your event listener, passing only one argument - payload - which will hold event data (different to each event type). Above example demonstrates how to listen to the add to cart event and log current cart size and newly added product. Currently supported handlers are: onAddToCart and onError.


onAddToCart

onAddToCart: (cartSize: number, product: TipserProductModel)

TipserProductModel interface is as follows:

interface TipserProductModel {
    id: string;
    title: string;
    description: string;
    brand: string;
    images: any[];
    isInStock: boolean;
    deliveryTime: string;
    priceIncVat: PriceModel;
    deliveryCost: PriceModel;
    variants: TipserProductModel[];
    discountPriceIncVat: PriceModel;
    freeReturn: boolean;
}

onError

By default, in case of an unexpected error happening (connection issues or unhandled runtime exceptions), an error popup will appear. If you want to disable the deafult error messages, set useDefaultErrorHandler option to false, and listen to error messages via onError event handler.

 tipser.elements('posId', { 
    useDefaultErrorHandler: true, 
    eventsHandlers: {
      onError: error => {
          console.log(error);
      }
    }
  })

The payload of error event is as follows:

The onError event handler is used with useDefaultErrorHandler config option. When that option is set to false (default to true) the error will not be shown on the screen.

Starter projects

A working examples of page based on Tipser Widget can be found on Tipser Widget Bootstrap page.

The code of that page is available as a GitHub Tipser Widget Bootstrap project. Feel free to checkout it and play with it on your local machine!

Tipser React Elements

Tipser React Elements is a component library from Tipser enabling you to add shoppable content to your React APP with minimal effort. You can add simple components like products with buy buttons, collections of products and articles, but also more complex grids or whole pages.


Live demo

A working examples of page based on Tipser React Elements can be found on Tipser Elements Bootstrap page.

The code of that page is available as a GitHub Tipser Elements Bootstrap project. Feel free to checkout it and play with it on your local environment!


Quick React Start

This quick guide explains how to intialize and render Tipser React Elements on your React app. It requires you to have a publisher account created in order to get the posId, as well as have some collections created in your shop. For a guide how to manage your collections, check the Tipser Tools tutorial.

If you're all set up, follow this three steps to rock on your app with Tipser React Elements!


Instalation

Add the library to your project:

npm install --save @tipser/tipser-elements


Import Tipser React Elements

You can combine Tipser Elements with your own application.

import React from 'react';
import ReactDOM from 'react-dom';
import { Product, Cart, Store, TipserElementsProvider } from '@tipser/tipser-elements';
import history from 'path/to/your/history'; // path to your history object that has been passed to react-router'

// simple configuration
const config = {
    lang: 'en-US',
    primaryColor: '#0000FF',    
};

ReactDOM.render(
    <TipserElementsProvider posId="59e86b79b8f3f60a94ecd26a" config={config} history={history}>   
        <header>
            <nav>
                Welcome to my store! 
                <Cart />
            </nav>
        </header>
        <main>
            <Product productId="5ba2334a781baa0001ccdffc"/>
            <Store />
        </main>
        <footer>
            <span>This is the footer</span>
        </footer>
    </TipserElementsProvider>, 
    document.getElementById('root'));

Make sure your HTML document contains an element of id root (<div id="root"/>) so that React can mount the app to your HTML document, provide history object on which we can rely for client side routing, when not provided routing is based on window.history. Also check our configuration options.


API reference of Tipser React Elements

TipserElementsProvider

Entry point to Tipser Elements (creating a context for other Elements);

prop name description type required default value
posId id of Point of sale string true
config configuration object (see definition here) {} false {}
history history object {} false window.history

TipserElement

Generic Element that can render any Contentful content that's fed as a prop to the element.

Product

Element that renders the product given the Tipser product ID as the prop.

Cart

Element that displays the number of items in your cart and gives the user a way to open the checkout dialog.

Store

Element that displays the store consisting of all your collections.

All configuration options of Tipser React Elements

Configuration is an object, which should be inserted into TipserElementsProvider as config prop.

All properties are optional:

Parameter Default Description Example
lang 'en-US' a locale to be used by the Tipser content. Possible values: 'en-US', 'de-DE', 'fr-FR' and 'sv-SE'. More info at Language and localeEnvironment 'de-DE'
env 'prod' Tipser environment to be used by the Tipser content. Possible values: 'stage' and 'prod'. More info at Environment 'stage'
defaultAddedToCartPopup true Controls default Added To Cart Popup. It appears when user adds a product to the cart. It improves UX by highlighting the action and allowing to navigate quickly to the cart modal window. true or false
useDefaultErrorHandler true when set to false and error happens, default message won't be displayed see Adding onError handler
eventsHandlers {} the object of event handlers. See Event handlers object
useDeepLinking true Makes Shop element to use hash navigation when switching between categories. More info at Use Deep Linking: false
modalUi {} Customization of Tipser Dialog. More info at Parameters for dialog customization { hideSearchIcon : true}
disableDialog false If set to true, a redirect to the product page is done instead of opening product dialogs (read more at: Embedding Elements in native apps section) false

Event Handlers


let tipserConfig = {
    lang: 'en',
    primaryColor: '#FF0000',
    // ----- EVENT HANDLING START
    useDefaultErrorHandler: true,
    eventsHandlers: {
        onError: (error) => {
            console.log(error)
        },
        onAddToCart: ({cartSize, product}) => {
            console.log('Hurray, you have added item to cart. ', product);
            console.log('Your cart size is now. ', cartSize);
        }
    }
    // -- EVENT HANDLING END
};

// ... as in example above class App extends Component { ... }

Event handlers may be passed as a part of config option of TipserElementsProvider. There is a number of events exposed for developer.

Handler name description params
onError Main goal of this handler is to add additional behavior when the error appears. object of type EventError (see EventError
onAddToCart when product is being added to cart event is triggered object of type {cartSize, product} where cartSize is a current size of cart after adding to cart and product is a product object with properties see (see TipserProductModel)

Event Error interface

export interface EventError {
    type?: string;
    id?: string;
    message?: string;
    stack?: string;
}

Param of onError handlers

Tipser Product Model interface

export interface TipserProductModel {
    id: string;
    title: string;
    description: string;
    brand: string;
    images: any[];
    isInStock: boolean;
    deliveryTime: string;
    priceIncVat: PriceModel;
    deliveryCost: PriceModel;
    variants: TipserProductModel[];
    discountPriceIncVat: PriceModel;
    freeReturn: boolean;
}

When onAddToCart is being dispatched the handlers are triggered with object with cart size of type string and product of type TipserProductModel.

Components

Components are the building blocks of Tipser Elements. Any components need to be a descendant of TipserElementsProvider component.

Collection
Product
Store
Cart

For example Store component is a HTML widget displaying a list of all Tipser public collections for the POS.

It can be used with Store react component.

import { Store } from '@tipser/tipser-elements';
 ...
<Store />

Shop component

Note: the Store component is updating the top-level page URL (when it's tabs are clicked). For this reason, please double check if it won't interfere with your web framework. For the same reason, it's not recommended to include more than one <Store /> on a single page.

Customizing Tipser Elements Styles

Tipser Elements are the "building blocks" designed to fit your page as much as possible. We created the styling in a way that delivers a nice look & feel from the start, but also allows you to change them easily to fit your unique sense of style. For example, all elements' font-family and font-size attributes are set to inherit them from the host page. If you need to change some other styles, please overwrite the certain CSS classes.

Product Card

The Product Card is an item used for displaying single Collection or Store component, among others. The font-family used in the description section of the Product Card is inherited from your website's styles, and the font-size is expressed in the relative em units controlled in .te-product-card class. The default value used there is 12px, which you can easily change by adding to your CSS the following style:

.te-product-card {
    font-size: 14px;
}

All the description elements (product name, brand and price) will become bigger / smaller according to the value you specify in the px unit. If you wish to change single description element, please use its specific class names:

.te-product-card-name
.te-product-card-brand
.te-product-card-price
and:
.te-product-card-sales-price
.te-product-card-price-regular-price
for products on sale.

Cart

The Cart component with the cart icon can be placed anywhere on your website. (It is highly advisable to place it in your navigation element among other icons such as search, home etc.) However, if you want to keep it visible at all times, attached to the right side of the viewport, you can use these styles:

.cart-icon {
    position: fixed;
    right: 0;
    top: 121px;
    background: #fff;
    padding: 10px;
    box-shadow: -2px 2px 7px rgba(0,0,0,0.3);
    z-index: 10;
}

Adding Primary color

If you'd like to unify our design with your own color-theme, you can use our primary-color configuration option. If your primary color is a bright one, you might want to change also the text color of the elements with primary color background. For example in buttons by default the color we use is white.


/* if your primary color is bright,
    you may consider changing also the text color for elements like buttons: */
.te-button-text {
    color: #fff;
}

If you'd like to change other elements' color as well, please use specific classes to override the styles.

Advanced usage

Getting Tipser Product Id

Adding POS data

If you need to associate some custom data to orders made from Tipser on your site (e.g. session id or user id on your site), pass it in the posData field to the Elements configuration. You will be later able to get that data back when requesting the orders from the Tipser orders API.

const tipserOptions = {
    posData: {
      userId: '123'
    }
};

Opening product dialog programatically

Tipser product dialog can be openend programatically by using the underlying Tipser SDK instance.

If you use Tipser Elements:

const elements = tipser.elements(posId, config);
elements.sdkInstance.openProductDialog(productId);

If you use Tipser React Elements:

  1. Create a custom React component and mount it anywhere under TipserElementsProvider in React elements hierarchy.
  2. Inside that component you can use tipserSdk instance from the context TipserContext. This how it can be done with React Hooks:
import { TipserContext } from `@tipser/tipser-elements`;

const DialogOpener = () => {
  const context = useContext(TipserContext());
  const sdk = context.data.tipserSdk;

  useEffect(() => { sdk.openProductDialog(productId); }, []);
}

Your React components hierarchy should look as following:

<TipserElementsProvider>
  <!-- Any number of other components -->
  <DialogOpener />
</TipserElementsProvider>

Buyable banners

Buyable banners

Tipser dialogs can be opened by the banners on your site. That way you can use your banners for E-commerce.

To connect your banner to Tipser, you need to do the following two steps:

  1. follow the instructions from Initializing Tipser Elements
  2. Add the line of javascript posted below to you banner. It should be invoked when the banner is clicked.

To display product dialog:

 window.top.postMessage({command: 'tipser.api.displayProduct', productId: tipserProductId}, '*')

To open the checkout view for a product directly:

  window.top.postMessage({command: 'tipser.api.directToCheckout', productId: tipserProductId}, '*')

Check this section to learn how to obtain the tipserProductId.

Live demo

 window.postMessage({command: 'tipser.api.displayProduct', productId: '5b59bfa4ca60310e30c9ac37'}, '*')


Server side rendering

If you want to render Tipser-Elements' components on the server side, you can do it in three steps:

  1. At the beginning you have to know ids of products and collections that you want to render on specific url.
  2. Before rendering you have to prepare the state which contains the data necessary to render specific components. It is easy to build this state - our lib includes the tool to do it!
  3. The state you have to apply to TipserElementsProvider as initialState prop
  4. You have to transfer the state on the frontend side and apply as initialState to TipserElementsProvider on the frontend side.

Building the state

We assume that you know ids of products, collections and you know if you want to render Shop component on the specific url. Let's say that following four variables are defined: POS_ID, PRODUCT_IDS, COLLECTION_IDS and IS_SHOP_ON_PAGE.
Please note that PRODUCT_IDS, COLLECTION_IDS and IS_SHOP_ON_PAGE should depend on URL - different pages can have different products/collections. To build the state you should use our StateBuilder class. You can do it in the following way:

import { StateBuilder } from '@tipser/tipser-elements';

const stateBuilder = new StateBuilder(POS_ID);

Now you can use it in your request handler:

stateBuilder.buildState(PRODUCT_IDS, COLLECTION_IDS, IS_SHOP_ON_PAGE): Promise<TipserState>

Full example:

stateBuilder
  .buildState(PRODUCT_IDS, COLLECTION_IDS, IS_SHOP_ON_PAGE)
  .then(initialState => {
    renderToString(
      <TipserElementsProvider posId={POS_ID} initialState={initialState}>
        <YourAppHere />
      </TipserElementsProvider>
    );
  });

The state should be transferred to the frontend app. You can use the pattern that is known from Redux based apps. All you need to do is including the following line in your html response:

<script>window.TIPSER_STATE = ${JSON.stringify(initialState)}</script>

then on the frontend side you are able to reuse it:

hydrate(
    <TipserElementsProvider posId={POS_ID} initialState={window.TIPSER_STATE}>
        <YourAppHere />
    </TipserElementsProvider>,
    document.getElementById('root')
);

That's all! The complete example is available here.

Native apps

Tipser Elements is a web-based library and currently we don't provide a native version for Android or iOS (let us know if you'd like us to build it for you!)

However it is possible to embed Elements in a native app if you are using WebViews. We recommend you to follow one of the patterns described below.

Pattern 1: Full web integration

In case your articles are managed by a Web CMS and are displayed in WebView you can simply install and use Tipser Elements in your web articles. Just follow the instructions from Tipser Elements or Tipser Elements React sections, depending on your technology of choice.

The only customization that we recommend is using disableDialog option, as described below.

Replacing dialogs with redirects

By default, when a product tile is clicked, it opens a full screen product dialog. It may not be desired behavior in your mobile app. Set the configuration option: disableDialog to true to replace the dialog with a redirect to the product page. That way pressing the back button will bring the user back to your article.

Pattern 2: API integration

If you want to deliver native experience to your users, you can build your custom native e-commerce components (product tiles, shopping cart icon, etc) and use Tipser Rest API to populate them. With this pattern, only the checkout part needs to be displayed in a WebView.

Below is a basic example of a native view with a single product that opens Tipser checkout view when clicked.

Step 1: Rendering a product on your page

  1. Use the Tipser product API to get the product that you want to sell, e.g: https://t3-stage-api.tipser.com/v3/products/5d932be284da04000116ae3c?pos=59e86b79b8f3f60a94ecd26a (please, replace the example product id with the desired product and the pos parameter with your own POS id)
  2. Render your custom product component based on the response data

Step2: Opening the checkout view

  1. Create a WebView screen in your app project
  2. When your product is clicked, open the WebView with the URL like: https://www.tipser.com/direct-checkout?productId=productId&posId=59e86b79b8f3f60a94ecd26a (again, please make sure to replace the posId with your POS id and productId with the Tipser id of the product that was clicked)

Merchant signup on your site

It is possible to let merchants sign-up to Tipser directly from your site.

To make it possible, you need to have Tipser Elements installed on your page and you need to prepare a dedicated subpage for merchants, with a "Sign up" button that invokes the following code:

const elements = tipser.elements(posId, config);
elements.sdkInstance.openDialog(`https://merchant-signup.netlify.app/#/start/${posId}`);

Tipser SDK

Tipser SDK is a modular version of the Tipser script that provides only the core functionality necessary for integration with Tipser, specifically built for customers who have their own development resources and plan to build their shopping experience on their own.

Installation

Using npm or yarn

You can add the Tipser SDK to your project by adding it through npm or yarn.

Yarn:

yarn add @tipser/tipser-sdk

NPM:

npm install --save @tipser/tipser-sdk

Package instructions

Using a script tag in your page HTML source

Add a script to your page:

<script src="https://cdn.tipser.com/tipser-sdk/latest.js"></script>

Initialization

To initialize you need to create an instance of Tipser SDK:

const tipser = TipserSDK(posId: string, options: TipserSdkConfig): TipserSDKInstance;

Arguments:

posId (string) - id of shop's account in Tipser (required)

options (object) - an object of options (optional).

Returns:

Initialized Tipser SDK object that can be used to perform API calls further in this document.

Example:

const tipser = TipserSDK("59e86b79b8f3f60a94ecd26a", {primaryColor: "#FFFF00"});

The example starts Tipser SDK instance in which Tipser shop has the primary color set to yellow.

For configuration options see the configuration chapter of our documentation.

Customization of Tipser environment

By default, Tipser SDK connects to the production Tipser environment. Yet, if the testing environment is preferred (e.g. in order to do test purchase), then it can be customized with env parameter in TipserSDK options, which accepts the following values:

prod or production

stage or staging

dev or development

Example:

var tipser = TipserSDK("5aa12d639d25800ff0e56fc5", {env: "stage"});

The script API

productId: string passed in product-related API calls. It consists of the masterProductId and, if the product has variants, the variantId, concatenated with an underscore "_". Then the productId should look like this:

<masterProductId>_<variantId>

posData string passed in the options is returned with other order fields from Tipser commissions API.

Adding product to cart

addToCart(productId: string, options: {posData?: string}): Promise<void>

Adds a product with a given productId (specific to Tipser) to a cart.

productId: string, with the stucture described here.

options: currently the only supported option is posData, which is a string to be attached to a product order.

Returns:

A Promise that resolves to no value but gives a chance to check if the request was successful or not (using .then()/.catch() semantics)

Example:

tipser.addToCart("5a98be67c0bdfb0c30865609_5a98be67c0bdfb0c30866509")
  .then(() => console.log("successfuly added to cart"))
  .catch((err) => console.log("failed to add to cart", err))

Opening product dialog

openProductDialog(productId: string): void

Opens Tipser product dialog for a product with given tipser product id.

Example:

tipser.openProductDialog("5a16534aa5af9b3af450c33d_5a16537da5af9b3af450c33f");

Opening purchase dialog

openPurchaseDialog(): void

Opens Tipser purchase (checkout) dialog with products that are currently in the shopping cart.

Getting cart size:

getCurrentCartSize(): Promise<number>;

Returns current Tipser cart size (including items added to cart from other shops). That value can change over time, so it may be necessary to call it repeatedly (e.g. on every page load or polling with a certain interval).

Returns:

A Promise returning current Tipser cart size.

Example:

tipser.getCurrentCartSize().then((cartSize) => {
   console.log("Tipser cart size is: ", cartSize);
   useCartSize(cartSize);
});

Direct to Checkout

By using the method Direct To Checkout, you add a product to the cart, at the same time as you open the checkout dialog window.

 openDirectToCheckoutDialog(productId: string, options: {posData?: string}): void

Adds the product with a given id to the shopping cart and then opens Tipser purchase (checkout) dialog with products that are currently in the shopping cart (including the newly added product).

productId: string, with the stucture described here.

options: currently the only supported option is posData, which is a string to be attached to a product order.

Opening search dialog

openSearchDialog(searchTerm: string): void

Opens Tipser product search dialog with using a given search term.

Opening collection dialog

openCollectionDialog(shopName: string, collectionName: string): void

Opens Tipser collection browsing dialog for a given Tipser shop name and collection name.

Closing Tipser dialog

closeDialog(): void

Closes the active Tipser dialog.

Listening to analytics events

addTrackEventListener(listener: (event) => void)
removeTrackEventListener(listener: (event) => void)

The listener callback is called every time payment analytics event (like product dialog opened or product added to cart) is fired by Tipser code.

Listening to dialog closed event

addDialogClosedListener(listener: (event) => void)
removeDialogClosedListener(listener: (event) => void)

The listener callback is called when every type of Tipser Dialog is closed (including "Thank You page" dialog - in this case, both dialogClosed and thankYouPageClosed listeners will be called).

Listening to thank you page closed event

addThankYouPageClosedListener(listener: (orderId: number) => void)
removeThankYouPageClosedListener(listener: (orderId: number) => void)

The listener callback is called when payment confirmation dialog (thank you page) is closed by the user. orderId of the order is passed as a callback argument.

Complete Tipser SDK example

var tipser = TipserSDK("5aa12d639d25800ff0e56fc5", {
   primaryColor: "yellow",
   modalUi: {
      hideSearchIcon: true,
      hideFavouritesIcon: true,
      hideCartIcon: true,
      hideMoreIcon: true,
      useCustomCss: true
   }
});
tipser.getCurrentCartSize().then((cartSize) => {
   console.log("cartSize = ", cartSize);
});
tipser.openProductDialog("5a16534aa5af9b3af450c33d_5a16537da5af9b3af450c33f");

tipser.addTrackEventListener(function(evt) {
    console.log("analytics event: ", evt);
});
tipser.addThankYouPageClosedListener(function() {
    console.log("thank you page closed event");
});

setTimeout(() => {
   tipser.closeDialog();
}, 5000);

The code snippet above initializes tipser SDK with custom primary color and some modal customizations, gets and prints the current cart size, opens a tipser dialog and then closes it after 5 seconds.

Tipser Tools

Tipser enables commerce on almost any site. An easy way to enable shopping on your site is to install the Tipser script and use the Tipser Tools to insert product listings and buy buttons directly into your site. The installation of the script on your site typically takes less than 5 minutes, and can be done even by non-technical people.

To get Tipser Tools you can either download our chrome extension or visit www.tipser.com/pos/tools, log into your POS account and follow the instructions there.

Tipser tools

You can also create an empty bookmark in the bookmarks bar and insert the following script where the URL normally goes:

javascript:(function(){(typeof TipserBookmarklet!='undefined')?TipserBookmarklet.init():document.getElementsByTagName('head')[0].appendChild(document.createElement('script')).src='//www.tipser.com/widget/bookmarklet.js?'+Math.random();}());

Once you have the Tipser Tools on your bookmark bar, simply click it to open on top of any other site.


Products collections

You can add a list of products into a post, an article or a specific area on a page. A ready to copy and paste snippet is curated by clicking the Insert Products in the Tipser Tools.

Tipser tools insert

You will be asked to pick products from Tipser inventory and click the generate snippet button.

Tipser tools products

When the snippet is generated simply click the copy button and paste the snippet into your CMS or into your HTML code directly.

Tipser tools copy snippet

The product list will appear on your site exactly where you placed it.

Product list

Configuration options

Both Tipser Elements and Tipser SDK initialization functions accept configuration object as a second parameter.

Tipser Elements example:

const tipserElements = tipser.elements("59e86b79b8f3f60a94ecd26a", {primaryColor: "#222"});

Tipser SDK Example:

const tipserSdk = TipserSDK("59e86b79b8f3f60a94ecd26a", {primaryColor: "#222"});

The example connects Tipser SDK and sets primary color to #0000FF.

All the available configuaration options are:

const configurationOptions = {
  primaryColor: "#0000FF",
  env: "stage",
  lang: 'en-US',
  modalUi: {
    hideSearchIcon: true,
    hideFavouritesIcon: true,
    hideCartIcon: false,
    hideMoreIcon: true,
    hideSimilarProducts: false,
    useCustomCss: true
  },
  addToCartSettings: {
      directToCheckoutMode: false,
  },
  useDeepLinking: false,
  customLabels: {
    buy: 'custom button label'
  },
  posData: {
    key: "value"
  }
}

They will be described in the following sections.


Primary Color

If you'd like to unify our design with your own color-theme, you can use our primary color configuration option to change the color of buy buttons in Product and indicator of items number in Cart. You only need to make sure to use the right hex color code.

const tipserSdk = TipserSDK("59e86b79b8f3f60a94ecd26a", {primaryColor: "#5F9F9F"});

Primary color


Environment

const tipser = tipser.elements("59e86b79b8f3f60a94ecd26a", {env: "stage"});

By default, Tipser Elements and SDK connect to production Tipser environment. Yet if testing environment is preferred (e.g. in order to do test purchase), then it can be customized with env parameter in Tipser options, which accept the following values:


Language and locale

lang configuration option specifies the language to be used. Supported languages are currently: en-US, de-DE, fr-FR and sv-SE.

  tipser.elements('posId', {
    lang: 'en-US'
  })

It affects all the localizable texts in the UI - buy buttons, store, shopping cart and checkout. It does not affect the currency in which the customer will pay for the product.


Parameters for dialog customization

Sometimes Tipser dialogue styling and functionality needs to be customized. It is possible with modalUi parameters group.

Complete example of dialog customizations:

const tipserOptions = {
    modalUi: {
      hideSearchIcon: true,
      hideFavouritesIcon: true,
      hideCartIcon: false,
      hideMoreIcon: true,
      hideSimilarProducts: false,
      useCustomCss: true
    }
};

Hiding icons on menu bar

The following parameters under modalUi can be used to selectively hide tipser icons on the dialog menu bar:

hideSearchIcon
hideFavouritesIcon
hideCartIcon
hideMoreIcon

Widget1

Hiding Similar Products Module

Similarly, hideSimilarProducts parameter, if set to true, can be used to hide Similar Products Module on product page

Widget2

Add To Cart Settings

When thedirectToCheckoutMode option is set to true, after clicking the buy button in Product component you go directly to checkout, without displaying the product dialog.

Custom CSS

If there is a need to use custom css stylesheet inside the Tipser dialog iframe, it may be activated in two steps:

  1. set useCustomCss parameter to true

  2. Send the custom css stylesheet to Tipser administrator in order for it to be uploaded to your account.


Deep linking

By default the Store component saves the active collection in the browser's URL hash part (everything after the # symbol in the URL). It means that your shopping page may be bookmarked by the user or shared with other users by sending a browser link (the same collection will be active in the Store when opening that link).

If, you wish to turn this behaviour off (e.g. because it interferes with your the routing system of your site), set the useDeepLinking parameter to false.


Custom Labels

If you want to override our default text with your own, you can do it via customLabels option. At the moment we allow to change the label of the buy button only.

const tipserOptions = {
    customLabels: {
      buy: 'buy now!'
    }
};

Custom label

POS data

Go to this section to see the usage. ```

Analytics

You can connect to Tipser analytics by listening to the tw-track event on your page:

<script>
var tipserEventsCallback = function (e) {
  //put here your own code handling the event, example below
  var detail = e.detail; 
  console.log('Tipser analytics event: ', e);
  console.log('Action',detail.action);
  console.log('Description',detail.description);
  console.log('Target',detail.target);
  console.log('Object',detail.object);
}
document.addEventListener('tw-track', tipserEventsCallback);
</script>

Example events intercepted this way are:

For complete list of supported events refer to the List of supported interactions section.

What you do with those events is up to you. Typical usage examples are:

Events structure

Each event passed to tipserEventsCallback function follows the following structure:

{
  detail: {
    action: string, # what action is taken on the target, mandatory
    target: string, # where this action is taken, mandatory
    description: string, # describing what is being logged
    object: # details about the tracked object, e.g. product name, product price, etc.
    [    
      {  
        # some properties here               
      },     
      ..., # this array can contain more than 1 object
    ]
  } 
}

As you can see, all the useful data is contained in the top-level detail field of the event object.

Typical use case: Google Analytics

In case you want to forward Tipser Analytics events to your Google Analytics, you can use this code snippet:

document.addEventListener('tw-track', function(e) {
    // ga() function coming from analytics.js library
    ga('send', {
        hitType: 'event',
        eventCategory: e.detail.description,
        eventAction: e.detail.action,
        eventLabel: e.detail.target,
    });
});

The code above assumes that you use analytics.js GA client library on your page. For other libraries, like gtag.js, that code needs to be slightly adjusted.

For the instructions how to setup analytics.js script on your site and connect it to your GA account, refer to the official documentation.

Typical use case: Facebook Pixel

In case you want to forward Tipser Analytics events to your Facebook Pixel account, you can use the following code snippet:

document.addEventListener('tw-track', function(e) {
    // fbq() function coming from Facebook Pixel analytics script
    fbq('trackCustom', e.detail.action, {
        content_name: e.detail.target, 
        content_category: e.detail.description,
        content_type: e.detail.action,
    });
});

The example above doesn't translate Tipser events to standard Pixel events, you will have to make a correlation in the Pixel dashboard or you can write a custom mapping function.

  1. Expand and copy the snippet script.
  2. Paste it above addEventListener for tw-track event.
  3. Use it the same way as in the example below

    Snippet

    const callPixelEvent = function(e) {
      const action = e.detail.action;
      const target = e.detail.target;
      const object = e.detail.object;
    
      switch (true) {
        case action === 'Click' && target === 'Product tile': {
          const product = object[0];
          fbq('track', 'ViewContent', {
            currency: (product.salesPrice || product.listPrice || product.priceIncVat).currency,
            value: (product.salesPrice || product.listPrice || product.priceIncVat).value,
            content_name: product.name || product.title,
            content_ids: [product.id],
          });
          break;
        }
        case action === 'Cart' && target === 'Product': {
          const product = object[0];
          if ((product.name || product.title) && (product.salesPrice || product.listPrice || product.priceIncVat)) {
            fbq('track', 'AddToCart', {
              currency: (product.salesPrice || product.listPrice || product.priceIncVat).currency,
              value: (product.salesPrice || product.listPrice || product.priceIncVat).value,
              content_name: product.name || product.title,
              content_ids: [product.id],
            });
          } else {
            fbq('track', 'AddToCart', {
              content_ids: [product.id],
            });
          }
          break;
        }
        case action === 'Cart' && target === 'Payment': {
          const products = object;
          fbq('track', 'InitiateCheckout', {
            content_ids: products.map((p) => p.id),
            contents: products.map((p) => p.name).join(', '),
            currency: (products[0].salesPrice || products[0].listPrice || products[0].priceIncVat).currency,
            num_items: products.reduce((totalQuantity, product) => product.quantity + totalQuantity, 0),
            value: products.reduce((totalPrice, product) => product.quantity * (product.salesPrice || product.listPrice).value + totalPrice, 0),
          });
          break;
        }
        case action === 'Purchase' && target === 'Order': {
          const products = object.map((order) => order.Products).flat();
          fbq('track', 'Purchase', {
            value: products.reduce(
              (totalPrice, product) => totalPrice + (product.salesPrice || product.listPrice || product.priceIncVat).value,
              0
            ),
            currency: (products[0].salesPrice || products[0].listPrice || products[0].priceIncVat).currency,
            content_ids: products.map((product) => product.id),
            contents: products,
            content_type: 'product',
          });
          break;
        }
        default:
          break;
      }
    };
    

document.addEventListener('tw-track', callPixelEvent);

The code above assumes that you use pixel.js facebook client library on your page.

For the instructions how to setup pixel.js script on your site and connect it to your Facebook for Developers account, refer to the official documentation.

List of supported interactions

View collection

When a collection appears in the viewport.

detail object structure

{
  description: ‘Collection viewed’,
  action: 'View',
  target: 'List',
  object:  {
    id: string,
    ownerUserId: string,
    created: string, #e.g. DateTime ISO 2019-06-11T08:40:29.377Z
    modified: string, #e.g. DateTime ISO 2019-06-11T08:40:29.377Z
    postComment: null | ?
    product: Product     
  }[]
}

Quick links to object structures: Product

Click product in collection

When a product in a collection is clicked.

detail object structure

{
  description: 'Product tile clicked',
  action: 'Click',
  target: 'Product tile',
  object: Product[]
}

Quick links to object structures: Product

View product details

It is emitted every time product tile is clicked and product dialog is displayed.

detail object structure

{
  description: 'Product detail page viewed',
  action: 'View',
  target: 'Product',
  object: Product[] # Product which interests us is the first element of an Array 
}

Quick links to object structures: Product

View the Store

When the Tipser store appears in the viewport.

detail object structure

{
  description: 'Shop viewed',
  action: 'View',
  target: 'Shop',
  object: [
    { 
      id: string, # collection id
      items: Product[], # products
      url_slug: string # store url slug 
    }
  ]
}

When a category is changed in the store, this event will be sent again with a different set of products and collection id.

Click cart tab

When the shopping cart tab is clicked.

detail object structure

{
  description: 'Cart clicked',
  action: 'Click',
  target: 'Cart-tab',
  object: []
}

Add product to cart

When a product is added to a shopping cart.

detail object structure

{
  description: ‘Product added to cart’,
  action: 'Cart',
  target: 'Product',
  object: ProductLegacy[]
}

Quick links to object structures: ProductLegacy

View cart - with purchase intent

When cart appears in the viewport, and getting payment in view.

detail object structure

{
  description: 'View cart - payment in viewport',
  action: 'View',
  target: 'Payment',
  object: OrderedProductLegacy[]
}

Quick links to object structures: OrderedProductLegacy

Product purchased

When a product was bought (thank you page).

detail object structure

{
  description: ‘Product purchased’,
  action: 'Purchase',
  target: 'Order',
  object: [
    {
      OrderId: string, 
      Products: ProductLegacy[]
    }
  ]
}

Quick links to object structures: ProductLegacy

View cart

When cart icon appears in the viewport.

detail object structure

{
  description: ‘View cart’,
  action: 'View',
  target: 'Cart-tab',
  object: []
}

Objects structures

ProductLegacy structure

{ # Representation of product, but slightly different schema than Product
  id: string,
  name: string,
  brand: string,
  campaign: undefined,
  categories: CategoriesLegacy
  image: string, # url
  listPrice: Price,
  salesPrice: Price,
  variant: [],
  merchant: undefined
}

Quick links to object structures: CategoriesLegacy, Price

OrderedProductLegacy structure

{ # Representation of product, but slightly different schema than Product
  id: string,
  name: string,
  brand: string,
  campaign: undefined,
  categories: CategoriesLegacy 
  merchant: string
  image: string, # url
  listPrice: Price,
  salesPrice: Price,
  variant: [],
  posId: string,
  quantity: number
}

Quick links to object structures: CategoriesLegacy, Price

CategoriesLegacy structure

{

}[]

Product structure

{
  id: string,
  title: string,
  images: Image[],
  brand: string,
  catgories: Categories
  currency: string, #ISO 4217
  description: string,
  priceInVat: Price,
  isInStock: boolean,
  variants: [],
  vat: { # percentage of VAT
    value: number,
    formatted: string, # human readable value percentage string
  }      
  categoriesValue: string
}

Quick links to object structures: Categories, Price, Image

Image structure

{

  id: string,
  original: string
}

Each value is url for the certain variation of an image. key determines size, and it is one of following: 250x, 450x, 960x, 50x50.

Categories structure

  department: string,
  section: string,
  productType: string

Price structure

{
  value: number,
  currency: string, #ISO 4217
  formatted: string, # human readable price string    
}

Rest API

Tipser provides a RESTful API you can use to fully integrate your platform with Tipser.

You can find the full documentation here.

AMP

Tipser Elements can be also rendered as a part of an AMP-based page.

Due to the limitations of AMP format, AMP snippet is limited in functionality compared to standard Tipser Elements.

Limitations

But despite those limitations, the basic shopping experience is sustained, allowing AMP articles to generate income from E-commerce.

Installation

Required imports

Add the following AMP imports to the <head> element of your page or make sure they are already there.

<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>
<script async custom-element="amp-iframe" src="https://cdn.ampproject.org/v0/amp-iframe-0.1.js"></script>
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>

Styles

Add the following Tipser styles to the <head> element of your page. They are not mandatory but highly recommended.

<style amp-custom>*{box-sizing:border-box}.list{display:flex}.tipser-product-tile{cursor:pointer;float:left;max-width:250px;min-width:160px;position:relative;overflow:hidden;width:25%;padding:10px}.tipser-product-tile:hover .tipser-product-text{opacity:1;transform:translate(0,-3)}.tipser-tile-img-container{display:block;position:relative;background:#fff;height:250px;width:100%}amp-img.tipser-tile-img img{object-fit:contain}amp-img.tipser-tile-img-hover{transition:.7s;opacity:0}.tipser-product-tile:hover .tipser-tile-img-hover{opacity:1}.tipser-product-text{background:rgba(255,255,255,0.9);bottom:0;border-top:1px solid #ececec;color:black;margin-left:auto;margin-right:auto;min-height:140px;left:0;letter-spacing:.3px;opacity:0;position:absolute;right:0;text-align:center;transition:.7s;z-index:2}.tipser-tile-product-text,.tipser-tile-product-text[data-tipser-hide-text="slide"]{font-size:12px;padding:10px;text-align:center;transition:.5s}.tipser-tile-prod-brand{color:#afafaf;line-height:1.8em;text-transform:uppercase;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.tipser-tile-prod-name{line-height:1.8em;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.tipser-buy-button-small{background-color:#e91e63;border-radius:0;color:white;display:inline-block;font-size:12px;font-weight:700;line-height:1.8;margin:5px auto 0;padding:5px 30px;padding:10px 30px;position:relative;text-transform:uppercase;text-align:center;transition:.5s;width:auto}.tipser-tile-price{height:30px;overflow:hidden}.tipser-label-price-new{color:#cd5550;font-size:13.2px;font-weight:bold;white-space:nowrap}.tipser-label-price-new+.tipser-label-price-old{text-decoration:line-through}.tipser-label-price-save{color:#cd5550}.overlay{background:rgba(255,255,255,0.7);bottom:0;left:0;overflow:auto;position:fixed;right:0;top:0;z-index:10}.dialog{background-color:#fff;border:1px solid lightgray;bottom:5px;left:5px;position:fixed;right:5px;top:5px;z-index:1}.tipser-dialog{display:block;transition:opacity 2s ease;opacity:0;overflow:hidden;border:1px red solid;position:fixed;top:4%;left:5%;bottom:5%;right:5%}.tipser-dialog_closed{pointer-events:none;opacity:0;height:1px}.tipser-dialog_open{opacity:1;pointer-events:all}.close_button{cursor:pointer;float:right;padding:10px 15px;z-index:2}.list-overflow[overflow]{position:absolute;bottom:0;left:10px;background:lightgray;color:gray;font-size:12px;padding:6px 35px;width:130px}.tipser-product-text[data-tipser-hide-text="false"]{background-color:transparent;border:0;opacity:1;position:relative;width:100%}@media(max-width:900px){.tipser-product-tile{max-width:300px;width:calc((100% - 20px) / 3)}.tipser-product-text{background-color:transparent;border:0;opacity:1;position:relative;width:100%}.tipser-tile-product-text{padding:10px 0 0 0}.tipser-buy-button-small{width:100%}}@media(max-width:620px){.tipser-product-tile{max-width:250px;width:calc((100% - 20px) / 2)}}@media(max-width:360px){.tipser-product-tile{max-width:unset;width:calc(100% - 20px)}}</style>

Insert collection

This step assumes that your are familiar with Tipser Tools. Feel free to write to support@tipser.com to get a more personalized introduction.

  1. Log-in to Tipser Bookmarklet
  2. Click "Insert collections" button
  3. From the collections list, select the collection that you want to embed
  4. Click "Insert collection" button and in the dialog that opens tick "Google AMP ready" checkbox
  5. Copy the code from the dialog and paste it somewhere into the body section of your page