Source: Ecommerce/ecommerce.js

/**
 * @class
 * @classdesc Plugin used to manage ecommerce event sending.
 * @name Ecommerce
 * @memberof ATInternet.Tracker.Plugins
 * @type {function}
 * @param parent {object} Instance of the Tag used
 * @public
 */
window['ATInternet']['Tracker']['Plugins']['Ecommerce'] = function (parent) {
    "use strict";

    var _config = {};
    var _domain = '';

    // Types of SalesInsights events
    var Types = {
        product: {
            add_to_cart: 'product.add_to_cart',
            click: 'product.click',
            display: 'product.display',
            page_display: 'product.page_display',
            purchased: 'product.purchased',
            remove_from_cart: 'product.remove_from_cart'
        },
        cart: {
            confirmation: 'cart.confirmation',
            creation: 'cart.creation',
            delivery: 'cart.delivery',
            display: 'cart.display',
            payment: 'cart.payment',
            update: 'cart.update'
        },
        transaction: {
            confirmation: 'transaction.confirmation'
        }
    };
    //  Main keys of SalesInsights objects
    var Keys = {
        product: 'j:product',
        cart: 'j:cart',
        shipping: 'j:shipping',
        payment: 'j:payment',
        customer: 'j:customer',
        transaction: 'j:transaction',
        promotionalCode: 'a:s:promotionalCode'
    };
    //  Property keys of SalesInsights objects
    var Properties = {
        product: {
            id: 's:id',
            variant: 's:variant',
            name: 's:name',
            brand: 's:brand',
            discount: 'b:discount',
            priceTaxIncluded: 'f:priceTaxIncluded',
            priceTaxFree: 'f:priceTaxFree',
            currency: 's:currency',
            stock: 'b:stock',
            quantity: 'n:quantity',
            category1: 's:category1',
            category2: 's:category2',
            category3: 's:category3',
            category4: 's:category4',
            category5: 's:category5',
            category6: 's:category6',
            cartcreation: 'b:cartcreation'
        },
        cart: {
            id: 's:id',
            currency: 's:currency',
            turnoverTaxIncluded: 'f:turnoverTaxIncluded',
            turnoverTaxFree: 'f:turnoverTaxFree',
            quantity: 'n:quantity',
            nbDistinctProduct: 'n:nbDistinctProduct',
            creation_utc: 'd:creation_utc'
        },
        shipping: {
            delivery: 's:delivery',
            costTaxIncluded: 'f:costTaxIncluded',
            costTaxFree: 'f:costTaxFree'
        },
        payment: {
            mode: 's:mode'
        },
        customer: {
            new: 'b:new'
        },
        transaction: {
            id: 's:id'
        }
    };
    // Debug object error
    var debugError = {
        trigger: 'Event:event:set:Error',
        level: 'ERROR',
        messageArray: 'Not an array',
        messageObject: 'Not an object'
    };

    // Plugin configuration.
    parent.configPlugin('Ecommerce', dfltPluginCfg || {}, function (newConf) {
        _config = newConf;
    });

    /* ---------------------------------- Utility methods ------------------------------------------------- */

    /**
     * Check if type of tag is object.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param tagObject {object} Object from tag
     * @return {boolean}
     * @private
     */
    var _isObject = function (tagObject) {
        return ((typeof tagObject === 'object') && !(tagObject instanceof Array));
    };

    /**
     * Get parameter value.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param tagObject {object} Object from tag
     * @param hitKey {string} Name of the parameter in buffer
     * @param tagKey {string} Name of the property to get
     * @param hitObject {object} Hit object
     * @private
     */
    var _setValueFromKey = function (tagObject, hitKey, tagKey, hitObject) {
        if (tagObject.hasOwnProperty(tagKey)) {
            if (typeof tagObject[tagKey] !== 'undefined') {
                hitObject[hitKey] = tagObject[tagKey];
            }
        }
    };

    /* ---------------------------------- SalesTracker methods ------------------------------------------------- */

    /**
     * Process cart object for SalesTracker order
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param cartObject {object} Cart object
     * @private
     */
    var _processOrder = function (cartObject) {
        var cart = cartObject || {};
        var turnoverTaxIncluded = Number(cart['turnoverTaxIncluded']) || 0;
        var turnoverTaxFree = Number(cart['turnoverTaxFree']) || 0;
        var taxAmount = (turnoverTaxIncluded || turnoverTaxFree) - (turnoverTaxFree || turnoverTaxIncluded);
        parent.order.set({
            turnover: turnoverTaxIncluded,
            amount: {
                amountTaxIncluded: turnoverTaxIncluded,
                amountTaxFree: turnoverTaxFree,
                taxAmount: taxAmount.toFixed(2)
            }
        });
    };

    /**
     * Process cart object for SalesTracker cart
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param cartObject {Object} Cart object
     * @param isBasketPage {Boolean}
     * @private
     */
    var _processCart = function (cartObject, isBasketPage) {
        var cart = cartObject || {};
        parent.cart.set({
            cartId: cart['id'],
            isBasketPage: isBasketPage
        });
    };

    /**
     * Process promotional code object for SalesTracker order
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param promotionalCodeArray {Array} Promotional code array
     * @private
     */
    var _processPromotionalCode = function (promotionalCodeArray) {
        parent.order.set({
            discount: {
                promotionalCode: encodeURIComponent((promotionalCodeArray || []).join('|'))
            }
        });
    };

    /**
     * Process transaction object for SalesTracker order
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param transactionObject {object} Transaction object
     * @private
     */
    var _processTransaction = function (transactionObject) {
        var transaction = transactionObject || {};
        parent.order.set({
            orderId: transaction['id'],
            status: 3,
            paymentMethod: '',
            confirmationRequired: false
        });
    };

    /**
     * Process shipping object for SalesTracker order
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param shippingObject {object} Shipping object
     * @private
     */
    var _processShipping = function (shippingObject) {
        var shipping = shippingObject || {};
        parent.order.set({
            delivery: {
                shippingFeesTaxIncluded: shipping['costTaxIncluded'],
                shippingFeesTaxFree: shipping['costTaxFree'],
                deliveryMethod: encodeURIComponent(shipping['delivery'])
            }
        });
    };

    /**
     * Process customer object for SalesTracker order
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param customerObject {object} Customer object
     * @private
     */
    var _processCustomer = function (customerObject) {
        var customer = customerObject || {};
        parent.order.set({
            newCustomer: !!customer['new']
        });
    };

    /**
     * Process product categories
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param salesTrackerProduct {Object} SalesTracker object
     * @param salesInsightsProduct {Object} SalesInsights object
     * @private
     */
    var _processProductCategories = function (salesTrackerProduct, salesInsightsProduct) {
        for (var x = 1; x <= 6; x++) {
            if (typeof salesInsightsProduct['category' + x] !== 'undefined') {
                salesTrackerProduct['category' + x] = salesInsightsProduct['category' + x] ? '[' + encodeURIComponent(salesInsightsProduct['category' + x]) + ']' : '';
            }
        }
    };

    /**
     * Process products array for SalesTracker cart
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param productsArray {Array} Products array
     * @private
     */
    var _processCartProducts = function (productsArray) {
        var products = productsArray || [];
        var salesTrackerProduct;
        for (var i = 0; i < products.length; i++) {
            salesTrackerProduct = {
                productId: products[i]['id'] + (products[i]['name'] ? '[' + encodeURIComponent(products[i]['name']) + ']' : ''),
                quantity: products[i]['quantity'],
                unitPriceTaxIncluded: products[i]['priceTaxIncluded'],
                unitPriceTaxFree: products[i]['priceTaxFree']
            };
            _processProductCategories(salesTrackerProduct, products[i]);
            parent.cart.add({
                product: salesTrackerProduct
            });
        }
    };

    /**
     * Process products array for SalesTracker viewed products
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param productsArray {Array} Products array
     * @private
     */
    var _processViewedProducts = function (productsArray) {
        var products = productsArray || [];
        var salesTrackerProduct;
        for (var i = 0; i < products.length; i++) {
            salesTrackerProduct = {
                productId: products[i]['id'] + (products[i]['name'] ? '[' + encodeURIComponent(products[i]['name']) + ']' : '')
            };
            _processProductCategories(salesTrackerProduct, products[i]);
            parent.product.add(salesTrackerProduct);
        }
    };

    /* ---------------------------------- Ecommerce methods ------------------------------------------------- */

    /**
     * Get cart object from type
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param type {String} Type name
     * @return {Object}
     * @private
     */
    var _getCartFromType = function (type) {
        // Get cart if already defined
        var typeCart;
        var cart = {};
        var contextEcommerceObject = parent.getContext('ecommerce') || [];
        for (var i = 0; i < contextEcommerceObject.length; i++) {
            typeCart = contextEcommerceObject[i][type] || {};
            if (typeCart[Keys.cart]) {
                cart = typeCart[Keys.cart];
                break;
            }
        }
        return cart;
    };

    /**
     * Get transaction ID from type
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param type {String} Type name
     * @return {String}
     * @private
     */
    var _getTransactionIdFromType = function (type) {
        // Get transaction ID if already defined
        var confirmation;
        var idTransaction = '';
        var contextEcommerceObject = parent.getContext('ecommerce') || [];
        for (var i = 0; i < contextEcommerceObject.length; i++) {
            confirmation = contextEcommerceObject[i][type] || {};
            if (confirmation[Keys.transaction]) {
                idTransaction = confirmation[Keys.transaction][Properties.transaction.id];
                break;
            }
        }
        return idTransaction;
    };

    /**
     * Generate events from products array.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param type {string} Event type
     * @param productsArray {Array} Products array
     * @param idCart {string} Cart id
     * @private
     */
    var _setEventFromProducts = function (type, productsArray, idCart) {
        var products = productsArray || [];
        var addObject;
        for (var i = 0; i < products.length; i++) {
            addObject = {};
            if (i === 0) {
                parent.event.set(type, products[i], Keys.product, 'ecommerce');
            }
            else {
                addObject[Keys.product] = products[i];
                if (idCart) {
                    addObject[Keys.cart] = {};
                    addObject[Keys.cart][Properties.cart.id] = idCart;
                }
                parent.event.add(type, addObject, 'ecommerce');
            }
        }
    };

    /**
     * Generate 'product.display' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param productsArray {Array} Products array
     * @private
     */
    var _setProductDisplay = function (productsArray) {
        _setEventFromProducts(Types.product.display, productsArray, '');
    };

    /**
     * Generate 'product.click' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param productsArray {Array} Products array
     * @private
     */
    var _setProductClick = function (productsArray) {
        _setEventFromProducts(Types.product.click, productsArray, '');
    };

    /**
     * Generate 'product.page_display' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param productsArray {Array} Products array
     * @private
     */
    var _setProductPageDisplay = function (productsArray) {
        _setEventFromProducts(Types.product.page_display, productsArray, '');
    };

    /**
     * Generate 'product.add_to_cart' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param productsArray {Array} Products array
     * @param idCart {String} cart ID
     * @private
     */
    var _setProductAddToCart = function (productsArray, idCart) {
        _setEventFromProducts(Types.product.add_to_cart, productsArray, idCart);
    };

    /**
     * Generate 'product.remove_from_cart' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param productsArray {Array} Products array
     * @param idCart {String} cart ID
     * @private
     */
    var _setProductRemoveFromCart = function (productsArray, idCart) {
        _setEventFromProducts(Types.product.remove_from_cart, productsArray, idCart);
    };

    /**
     * Generate 'cart.creation' event.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param cart {Object} cart
     * @private
     */
    var _setCartCreation = function (cart) {
        var cartCreation = {};
        cartCreation[Keys.cart] = {};
        cartCreation[Keys.cart][Properties.cart.id] = cart.idCart;
        cartCreation[Keys.cart][Properties.cart.currency] = cart.currency;
        cartCreation[Keys.cart][Properties.cart.turnoverTaxIncluded] = cart.turnoverTaxIncluded;
        cartCreation[Keys.cart][Properties.cart.turnoverTaxFree] = cart.turnoverTaxFree;
        cartCreation[Keys.cart][Properties.cart.quantity] = cart.quantity;
        cartCreation[Keys.cart][Properties.cart.nbDistinctProduct] = cart.nbDistinctProduct;
        parent.event.set(Types.cart.creation, cartCreation, null, 'ecommerce');
    };

    /**
     * Complete 'cart.creation' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param idCart {String} cart ID
     * @private
     */
    var _updateCartCreation = function (idCart) {
        // Complete 'cart.creation' events if necessary
        var cartCreation;
        var contextEcommerceObject = parent.getContext('ecommerce') || [];
        for (var i = 0; i < contextEcommerceObject.length; i++) {
            cartCreation = contextEcommerceObject[i][Types.cart.creation];
            if (cartCreation && cartCreation[Keys.cart]) {
                cartCreation[Keys.cart][Properties.cart.id] = idCart;
                contextEcommerceObject[i][Types.cart.creation] = cartCreation;
            }
        }
    };

    /**
     * Generate 'cart.confirmation' event.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param cart {Object} cart object
     * @private
     */
    var _setCartConfirmation = function (cart) {
        var cartConfirmation = {};
        cartConfirmation[Keys.cart] = ATInternet.Utils.cloneSimpleObject(cart);
        parent.event.set(Types.cart.confirmation, cartConfirmation, null, 'ecommerce');
    };

    /**
     * Complete 'cart.confirmation' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param idTransaction {String} transaction ID
     * @param cart {Object} cart object
     * @private
     */
    var _updateCartConfirmation = function (idTransaction, cart) {
        // Complete 'cart.confirmation' events if necessary
        var cartConfirmation;
        var contextEcommerceObject = parent.getContext('ecommerce') || [];
        for (var i = 0; i < contextEcommerceObject.length; i++) {
            cartConfirmation = contextEcommerceObject[i][Types.cart.confirmation];
            if (cartConfirmation) {
                if (idTransaction) {
                    cartConfirmation[Keys.transaction] = {};
                    cartConfirmation[Keys.transaction][Properties.transaction.id] = idTransaction;
                }
                else if (cart && cartConfirmation[Keys.cart]) {
                    cartConfirmation[Keys.cart] = ATInternet.Utils.completeFstLevelObj(cartConfirmation[Keys.cart], cart, true);
                }
                contextEcommerceObject[i][Types.cart.confirmation] = cartConfirmation;
            }
        }
    };

    /**
     * Generate 'product.purchased' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param idTransaction {String} transaction ID
     * @param idCart {String} cart ID
     * @param productsArray {Array} Products array
     * @private
     */
    var _setProductPurchased = function (idTransaction, idCart, productsArray) {
        var products = productsArray || [];
        var eventObject;
        for (var i = 0; i < products.length; i++) {
            eventObject = {};
            eventObject[Keys.transaction] = {};
            eventObject[Keys.transaction][Properties.transaction.id] = idTransaction;
            eventObject[Keys.cart] = {};
            eventObject[Keys.cart][Properties.cart.id] = idCart;
            eventObject[Keys.product] = products[i];
            if (i === 0) {
                parent.event.set(Types.product.purchased, eventObject, null, 'ecommerce');
            }
            else {
                parent.event.add(Types.product.purchased, eventObject, 'ecommerce');
            }
        }
    };

    /**
     * Complete 'product.purchased' events.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param idTransaction {String} transaction ID
     * @param idCart {String} cart ID
     * @private
     */
    var _updateProductPurchased = function (idTransaction, idCart) {
        // Complete 'product.purchased' events if necessary
        var productPurchased;
        var contextEcommerceObject = parent.getContext('ecommerce') || [];
        for (var i = 0; i < contextEcommerceObject.length; i++) {
            productPurchased = contextEcommerceObject[i][Types.product.purchased];
            if (productPurchased) {
                if (idTransaction && productPurchased[Keys.transaction]) {
                    productPurchased[Keys.transaction][Properties.transaction.id] = idTransaction;
                }
                else if (idCart && productPurchased[Keys.cart]) {
                    productPurchased[Keys.cart][Properties.cart.id] = idCart;
                }
                contextEcommerceObject[i][Types.product.purchased] = productPurchased;
            }
        }
    };

    /**
     * Get full page label
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @param tagObject {Object} tag object
     * @returns string {String} Click name completed with chapters from tag object
     * @private
     */
    var _getFullName = function (tagObject) {
        var name = tagObject['name'];
        parent['exec']('Utils', 'manageChapters', [tagObject, 'chapter', 3], function (data) {
            name = data + (name ? name : '');
        });
        return name;
    };

    /**
     * [Object added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tags to manage ecommerce sending.
     * @name ecommerce
     * @memberof ATInternet.Tracker.Tag
     * @inner
     * @type {object}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.displayProduct.products.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.displayPageProduct.products.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.addProduct.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.addProduct.products.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.removeProduct.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.removeProduct.products.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.displayCart.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.displayCart.products.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.updateCart.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.deliveryCheckout.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.deliveryCheckout.shipping.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.paymentCheckout.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.paymentCheckout.shipping.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.transactionConfirmation.cart.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.transactionConfirmation.discount.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.transactionConfirmation.transaction.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.transactionConfirmation.shipping.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.transactionConfirmation.payment.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.transactionConfirmation.customer.set}
     * @property {function} set Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.transactionConfirmation.products.set}
     * @property {function} reset Tag helper, see details here {@link ATInternet.Tracker.Tag#ecommerce.reset}
     * @public
     */
    parent.ecommerce = {
        displayProduct: {},
        displayPageProduct: {},
        addProduct: {},
        removeProduct: {},
        displayCart: {},
        updateCart: {},
        deliveryCheckout: {},
        paymentCheckout: {},
        transactionConfirmation: {}
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Reset ecommerce context.
     * @alias ecommerce.reset
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @example
     * <pre><code class="javascript">tag.ecommerce.reset();
     * </code></pre>
     * @public
     */
    parent.ecommerce.reset = function () {
        parent.event.reset('ecommerce');
    };

    /* ---------------------------------- Type product.display ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for product display (helper).
     * @alias ecommerce.displayProduct.products.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * @example
     * <pre><code class="javascript">tag.ecommerce.displayProduct.products.set([{
                    "id": "7",
                    "variant": "1",
                    "name": "Robe en mousseline imprimée",
                    "brand": "Fashion Manufacturer",
                    "discount": 1,
                    "priceTaxIncluded": 19.68,
                    "priceTaxFree": 16.4,
                    "currency": "EUR",
                    "stock": 1,
                    "category1": "Accueil",
                    "category2": "Femmes",
                    "category3": "Robes",
                    "category4": "Robes d'été"
                }]);
     * </code></pre>
     * @public
     */
    parent.ecommerce.displayProduct.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {
                var product;
                var products = [];
                for (var i = 0; i < tagObject.length; i++) {
                    product = {};
                    _setValueFromKey(tagObject[i], Properties.product.id, 'id', product);
                    _setValueFromKey(tagObject[i], Properties.product.variant, 'variant', product);
                    _setValueFromKey(tagObject[i], Properties.product.name, 'name', product);
                    _setValueFromKey(tagObject[i], Properties.product.brand, 'brand', product);
                    _setValueFromKey(tagObject[i], Properties.product.discount, 'discount', product);
                    _setValueFromKey(tagObject[i], Properties.product.priceTaxIncluded, 'priceTaxIncluded', product);
                    _setValueFromKey(tagObject[i], Properties.product.priceTaxFree, 'priceTaxFree', product);
                    _setValueFromKey(tagObject[i], Properties.product.currency, 'currency', product);
                    _setValueFromKey(tagObject[i], Properties.product.stock, 'stock', product);
                    _setValueFromKey(tagObject[i], Properties.product.category1, 'category1', product);
                    _setValueFromKey(tagObject[i], Properties.product.category2, 'category2', product);
                    _setValueFromKey(tagObject[i], Properties.product.category3, 'category3', product);
                    _setValueFromKey(tagObject[i], Properties.product.category4, 'category4', product);
                    _setValueFromKey(tagObject[i], Properties.product.category5, 'category5', product);
                    _setValueFromKey(tagObject[i], Properties.product.category6, 'category6', product);
                    products.push(product);
                }
                _setProductDisplay(products);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageArray, {
                    type: Types.product.display,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- Type product.page_display ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for product page display (helper).
     * @alias ecommerce.displayPageProduct.products.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.displayPageProduct.products.set([{
                    "id": "3",
                    "variant": "1",
                    "name": "Robe imprimée",
                    "brand": "Fashion Manufacturer",
                    "discount": 0,
                    "priceTaxIncluded": 31.2,
                    "priceTaxFree": 26,
                    "currency": "EUR",
                    "stock": 1,
                    "category1": "Accueil",
                    "category2": "Femmes",
                    "category3": "Robes",
                    "category4": "Robes décontractées"
                }]);
     * </code></pre>
     * @public
     */
    parent.ecommerce.displayPageProduct.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {
                var product;
                var products = [];
                for (var i = 0; i < tagObject.length; i++) {
                    product = {};
                    _setValueFromKey(tagObject[i], Properties.product.id, 'id', product);
                    _setValueFromKey(tagObject[i], Properties.product.variant, 'variant', product);
                    _setValueFromKey(tagObject[i], Properties.product.name, 'name', product);
                    _setValueFromKey(tagObject[i], Properties.product.brand, 'brand', product);
                    _setValueFromKey(tagObject[i], Properties.product.discount, 'discount', product);
                    _setValueFromKey(tagObject[i], Properties.product.priceTaxIncluded, 'priceTaxIncluded', product);
                    _setValueFromKey(tagObject[i], Properties.product.priceTaxFree, 'priceTaxFree', product);
                    _setValueFromKey(tagObject[i], Properties.product.currency, 'currency', product);
                    _setValueFromKey(tagObject[i], Properties.product.stock, 'stock', product);
                    _setValueFromKey(tagObject[i], Properties.product.category1, 'category1', product);
                    _setValueFromKey(tagObject[i], Properties.product.category2, 'category2', product);
                    _setValueFromKey(tagObject[i], Properties.product.category3, 'category3', product);
                    _setValueFromKey(tagObject[i], Properties.product.category4, 'category4', product);
                    _setValueFromKey(tagObject[i], Properties.product.category5, 'category5', product);
                    _setValueFromKey(tagObject[i], Properties.product.category6, 'category6', product);
                    products.push(product);
                }
                _setProductPageDisplay(products);
                // SalesTracker
                if (_config.autoSalesTracker) {
                    _processViewedProducts(tagObject);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageArray, {
                    type: Types.product.page_display,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- Type product.add_to_cart ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for product add (helper).
     * @alias ecommerce.addProduct.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.addProduct.cart.set({"id": "34"});
     * </code></pre>
     * @public
     */
    parent.ecommerce.addProduct.cart = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var addProduct = {};
                addProduct[Keys.cart] = {};
                _setValueFromKey(tagObject, Properties.cart.id, 'id', addProduct[Keys.cart]);
                parent.event.set(Types.product.add_to_cart, addProduct[Keys.cart], Keys.cart, 'ecommerce');
                _updateCartCreation(addProduct[Keys.cart][Properties.cart.id]);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageObject, {
                    type: Types.product.add_to_cart,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for product add (helper).
     * @alias ecommerce.addProduct.products.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.addProduct.products.set([{
                    "id": "3",
                    "variant": "1",
                    "name": "Robe imprimée",
                    "brand": "Fashion Manufacturer",
                    "discount": 0,
                    "priceTaxIncluded": 31.2,
                    "priceTaxFree": 26,
                    "currency": "EUR",
                    "stock": 1,
                    "category1": "Accueil",
                    "category2": "Femmes",
                    "category3": "Robes",
                    "category4": "Robes décontractées",
                    "quantity": 1,
                    "cartcreation": 1
                }]);
     * </code></pre>
     * @public
     */
    parent.ecommerce.addProduct.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {
                var product;
                var products = [];
                var isCartCreation = false;
                var cart = {
                    idCart: _getCartFromType(Types.product.add_to_cart)[Properties.cart.id],
                    currency: '',
                    turnoverTaxIncluded: 0,
                    turnoverTaxFree: 0,
                    quantity: 0,
                    nbDistinctProduct: 0
                };
                for (var i = 0; i < tagObject.length; i++) {
                    product = {};
                    _setValueFromKey(tagObject[i], Properties.product.id, 'id', product);
                    _setValueFromKey(tagObject[i], Properties.product.variant, 'variant', product);
                    _setValueFromKey(tagObject[i], Properties.product.name, 'name', product);
                    _setValueFromKey(tagObject[i], Properties.product.brand, 'brand', product);
                    _setValueFromKey(tagObject[i], Properties.product.discount, 'discount', product);
                    _setValueFromKey(tagObject[i], Properties.product.priceTaxIncluded, 'priceTaxIncluded', product);
                    _setValueFromKey(tagObject[i], Properties.product.priceTaxFree, 'priceTaxFree', product);
                    _setValueFromKey(tagObject[i], Properties.product.currency, 'currency', product);
                    _setValueFromKey(tagObject[i], Properties.product.stock, 'stock', product);
                    _setValueFromKey(tagObject[i], Properties.product.quantity, 'quantity', product);
                    _setValueFromKey(tagObject[i], Properties.product.category1, 'category1', product);
                    _setValueFromKey(tagObject[i], Properties.product.category2, 'category2', product);
                    _setValueFromKey(tagObject[i], Properties.product.category3, 'category3', product);
                    _setValueFromKey(tagObject[i], Properties.product.category4, 'category4', product);
                    _setValueFromKey(tagObject[i], Properties.product.category5, 'category5', product);
                    _setValueFromKey(tagObject[i], Properties.product.category6, 'category6', product);
                    _setValueFromKey(tagObject[i], Properties.product.cartcreation, 'cartcreation', product);
                    cart.currency = tagObject[i]['currency'];
                    cart.turnoverTaxIncluded += (Number(tagObject[i]['priceTaxIncluded']) || 0) * (Number(tagObject[i]['quantity']) || 0);
                    cart.turnoverTaxFree += (Number(tagObject[i]['priceTaxFree']) || 0) * (Number(tagObject[i]['quantity']) || 0);
                    cart.quantity += Number(tagObject[i]['quantity']) || 0;
                    cart.nbDistinctProduct += 1;
                    if (Boolean(Number(tagObject[i]['cartcreation']))) {
                        isCartCreation = true;
                    }
                    products.push(product);
                }
                _setProductAddToCart(products, cart.idCart);
                isCartCreation && _setCartCreation(cart);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageArray, {
                    type: Types.product.add_to_cart,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- Type product.remove_from_cart ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for product remove (helper).
     * @alias ecommerce.removeProduct.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.removeProduct.cart.set({"id": "34"});
     * </code></pre>
     * @public
     */
    parent.ecommerce.removeProduct.cart = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var removeProduct = {};
                removeProduct[Keys.cart] = {};
                _setValueFromKey(tagObject, Properties.cart.id, 'id', removeProduct[Keys.cart]);
                parent.event.set(Types.product.remove_from_cart, removeProduct[Keys.cart], Keys.cart, 'ecommerce');
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageObject, {
                    type: Types.product.remove_from_cart,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for product remove (helper).
     * @alias ecommerce.removeProduct.products.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.removeProduct.products.set([{
                    "id": "4",
                    "variant": "1",
                    "name": "Robe imprimée",
                    "brand": "Fashion Manufacturer",
                    "discount": 0,
                    "priceTaxIncluded": 61.19,
                    "priceTaxFree": 50.99,
                    "currency": "EUR",
                    "stock": 1,
                    "category1": "Accueil",
                    "category2": "Femmes",
                    "category3": "Robes",
                    "category4": "Robes de soirée",
                    "quantity": 1
                }]);
     * </code></pre>
     * @public
     */
    parent.ecommerce.removeProduct.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {
                var product;
                var products = [];
                var idCart = _getCartFromType(Types.product.remove_from_cart)[Properties.cart.id];
                for (var i = 0; i < tagObject.length; i++) {
                    product = {};
                    _setValueFromKey(tagObject[i], Properties.product.id, 'id', product);
                    _setValueFromKey(tagObject[i], Properties.product.variant, 'variant', product);
                    _setValueFromKey(tagObject[i], Properties.product.name, 'name', product);
                    _setValueFromKey(tagObject[i], Properties.product.brand, 'brand', product);
                    _setValueFromKey(tagObject[i], Properties.product.discount, 'discount', product);
                    _setValueFromKey(tagObject[i], Properties.product.priceTaxIncluded, 'priceTaxIncluded', product);
                    _setValueFromKey(tagObject[i], Properties.product.priceTaxFree, 'priceTaxFree', product);
                    _setValueFromKey(tagObject[i], Properties.product.currency, 'currency', product);
                    _setValueFromKey(tagObject[i], Properties.product.stock, 'stock', product);
                    _setValueFromKey(tagObject[i], Properties.product.quantity, 'quantity', product);
                    _setValueFromKey(tagObject[i], Properties.product.category1, 'category1', product);
                    _setValueFromKey(tagObject[i], Properties.product.category2, 'category2', product);
                    _setValueFromKey(tagObject[i], Properties.product.category3, 'category3', product);
                    _setValueFromKey(tagObject[i], Properties.product.category4, 'category4', product);
                    _setValueFromKey(tagObject[i], Properties.product.category5, 'category5', product);
                    _setValueFromKey(tagObject[i], Properties.product.category6, 'category6', product);
                    products.push(product);
                }
                _setProductRemoveFromCart(products, idCart);
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageArray, {
                    type: Types.product.remove_from_cart,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- Type cart.display ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for cart display (helper).
     * @alias ecommerce.displayCart.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.displayCart.cart.set({
                    "id": "53",
                    "currency": "EUR",
                    "turnoverTaxIncluded": 10.81,
                    "turnoverTaxFree": 9.01,
                    "quantity": 1
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.displayCart.cart = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var displayCart = {};
                displayCart[Keys.cart] = {};
                _setValueFromKey(tagObject, Properties.cart.id, 'id', displayCart[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.currency, 'currency', displayCart[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.turnoverTaxIncluded, 'turnoverTaxIncluded', displayCart[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.turnoverTaxFree, 'turnoverTaxFree', displayCart[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.quantity, 'quantity', displayCart[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.nbDistinctProduct, 'nbDistinctProduct', displayCart[Keys.cart]);
                parent.event.set(Types.cart.display, displayCart[Keys.cart], Keys.cart, 'ecommerce');
                if (_config.autoSalesTracker) {
                    _processCart(tagObject, true);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageObject, {
                    type: Types.cart.display,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for cart display (helper).
     * @alias ecommerce.displayCart.products.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.displayCart.products.set([{
                    "id": "1",
                    "name": "T-shirt délavé à manches courtes",
                    "priceTaxIncluded": 10.81,
                    "priceTaxFree": 9.01,
                    "quantity": 1,
                    "category1": "Femmes",
                    "category2": "Tops",
                    "category3": "T-shirts",
                    "category4": "Manches Courtes",
                    "category5": "Cols Ronds",
                    "category6": "Coton"
                }]);
     * </code></pre>
     * @public
     */
    parent.ecommerce.displayCart.products = {
        set: function (tagObject) {
            // SalesTracker
            if (_config.autoSalesTracker) {
                if (tagObject instanceof Array) {
                    _processCartProducts(tagObject);
                }
                else if (tagObject) {
                    /* @if debug */
                    parent.debug(debugError.trigger, debugError.level, debugError.messageArray, {
                        type: Types.cart.display,
                        data: tagObject,
                        origin: 'ecommerce'
                    });
                    /* @endif */
                }
            }
        }
    };

    /* ---------------------------------- Type cart.update ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for cart update (helper).
     * @alias ecommerce.updateCart.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.updateCart.cart.set({
                    "id": "34",
                    "currency": "EUR",
                    "turnoverTaxIncluded": 62.4,
                    "turnoverTaxFree": 52,
                    "quantity": 2
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.updateCart.cart = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var updateCart = {};
                updateCart[Keys.cart] = {};
                _setValueFromKey(tagObject, Properties.cart.id, 'id', updateCart[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.currency, 'currency', updateCart[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.turnoverTaxIncluded, 'turnoverTaxIncluded', updateCart[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.turnoverTaxFree, 'turnoverTaxFree', updateCart[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.quantity, 'quantity', updateCart[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.nbDistinctProduct, 'nbDistinctProduct', updateCart[Keys.cart]);
                parent.event.set(Types.cart.update, updateCart[Keys.cart], Keys.cart, 'ecommerce');
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageObject, {
                    type: Types.cart.update,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- Type cart.delivery ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for delivery checkout (helper).
     * @alias ecommerce.deliveryCheckout.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.deliveryCheckout.cart.set({
                    "id": "34",
                    "currency": "EUR",
                    "turnoverTaxIncluded": 40.8,
                    "turnoverTaxFree": 34,
                    "quantity": 1
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.deliveryCheckout.cart = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var deliveryCheckout = {};
                deliveryCheckout[Keys.cart] = {};
                _setValueFromKey(tagObject, Properties.cart.id, 'id', deliveryCheckout[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.currency, 'currency', deliveryCheckout[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.turnoverTaxIncluded, 'turnoverTaxIncluded', deliveryCheckout[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.turnoverTaxFree, 'turnoverTaxFree', deliveryCheckout[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.quantity, 'quantity', deliveryCheckout[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.nbDistinctProduct, 'nbDistinctProduct', deliveryCheckout[Keys.cart]);
                parent.event.set(Types.cart.delivery, deliveryCheckout[Keys.cart], Keys.cart, 'ecommerce');
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageObject, {
                    type: Types.cart.delivery,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for delivery checkout (helper).
     * @alias ecommerce.deliveryCheckout.shipping.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.deliveryCheckout.shipping.set({
                    "delivery": "My carrier",
                    "costTaxIncluded": 8.4,
                    "costTaxFree": 7
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.deliveryCheckout.shipping = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var deliveryCheckout = {};
                deliveryCheckout[Keys.shipping] = {};
                _setValueFromKey(tagObject, Properties.shipping.delivery, 'delivery', deliveryCheckout[Keys.shipping]);
                _setValueFromKey(tagObject, Properties.shipping.costTaxIncluded, 'costTaxIncluded', deliveryCheckout[Keys.shipping]);
                _setValueFromKey(tagObject, Properties.shipping.costTaxFree, 'costTaxFree', deliveryCheckout[Keys.shipping]);
                parent.event.set(Types.cart.delivery, deliveryCheckout[Keys.shipping], Keys.shipping, 'ecommerce');
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageObject, {
                    type: Types.cart.delivery,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- Type cart.payment ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for payment checkout (helper).
     * @alias ecommerce.paymentCheckout.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.paymentCheckout.cart.set({
                    "id": "34",
                    "currency": "EUR",
                    "turnoverTaxIncluded": 40.8,
                    "turnoverTaxFree": 34,
                    "quantity": 1
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.paymentCheckout.cart = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var paymentCheckout = {};
                paymentCheckout[Keys.cart] = {};
                _setValueFromKey(tagObject, Properties.cart.id, 'id', paymentCheckout[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.currency, 'currency', paymentCheckout[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.turnoverTaxIncluded, 'turnoverTaxIncluded', paymentCheckout[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.turnoverTaxFree, 'turnoverTaxFree', paymentCheckout[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.quantity, 'quantity', paymentCheckout[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.nbDistinctProduct, 'nbDistinctProduct', paymentCheckout[Keys.cart]);
                parent.event.set(Types.cart.payment, paymentCheckout[Keys.cart], Keys.cart, 'ecommerce');
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageObject, {
                    type: Types.cart.payment,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for payment checkout (helper).
     * @alias ecommerce.paymentCheckout.shipping.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.paymentCheckout.shipping.set({
                    "delivery": "My carrier",
                    "costTaxIncluded": 8.4,
                    "costTaxFree": 7
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.paymentCheckout.shipping = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var paymentCheckout = {};
                paymentCheckout[Keys.shipping] = {};
                _setValueFromKey(tagObject, Properties.shipping.delivery, 'delivery', paymentCheckout[Keys.shipping]);
                _setValueFromKey(tagObject, Properties.shipping.costTaxIncluded, 'costTaxIncluded', paymentCheckout[Keys.shipping]);
                _setValueFromKey(tagObject, Properties.shipping.costTaxFree, 'costTaxFree', paymentCheckout[Keys.shipping]);
                parent.event.set(Types.cart.payment, paymentCheckout[Keys.shipping], Keys.shipping, 'ecommerce');
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageObject, {
                    type: Types.cart.payment,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /* ---------------------------------- Type transaction.confirmation ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction confirmation (helper).
     * @alias ecommerce.transactionConfirmation.cart.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.transactionConfirmation.cart.set({
                    "id": "34",
                    "currency": "EUR",
                    "turnoverTaxIncluded": 40.8,
                    "turnoverTaxFree": 34,
                    "creation_utc": 1514973161
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.transactionConfirmation.cart = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var transactionConfirmation = {};
                transactionConfirmation[Keys.cart] = {};
                _setValueFromKey(tagObject, Properties.cart.id, 'id', transactionConfirmation[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.currency, 'currency', transactionConfirmation[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.turnoverTaxIncluded, 'turnoverTaxIncluded', transactionConfirmation[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.turnoverTaxFree, 'turnoverTaxFree', transactionConfirmation[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.creation_utc, 'creation_utc', transactionConfirmation[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.quantity, 'quantity', transactionConfirmation[Keys.cart]);
                _setValueFromKey(tagObject, Properties.cart.nbDistinctProduct, 'nbDistinctProduct', transactionConfirmation[Keys.cart]);
                // Ecommerce
                parent.event.set(Types.transaction.confirmation, transactionConfirmation[Keys.cart], Keys.cart, 'ecommerce');
                _setCartConfirmation(transactionConfirmation[Keys.cart]);
                _updateProductPurchased(null, transactionConfirmation[Keys.cart][Properties.cart.id]);
                // SalesTracker
                if (_config.autoSalesTracker) {
                    _processCart(tagObject, false);
                    _processOrder(tagObject);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageObject, {
                    type: Types.transaction.confirmation,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction confirmation (helper).
     * @alias ecommerce.transactionConfirmation.discount.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.transactionConfirmation.discount.set(["DQQYRZSJ", "UN1ENE27"]);
     * </code></pre>
     * @public
     */
    parent.ecommerce.transactionConfirmation.discount = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {
                var transactionConfirmation = {};
                transactionConfirmation[Keys.promotionalCode] = tagObject;
                // Ecommerce
                parent.event.set(Types.transaction.confirmation, transactionConfirmation[Keys.promotionalCode], Keys.promotionalCode, 'ecommerce');
                // SalesTracker
                if (_config.autoSalesTracker) {
                    _processPromotionalCode(tagObject);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageArray, {
                    type: Types.transaction.confirmation,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction confirmation (helper).
     * @alias ecommerce.transactionConfirmation.transaction.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.transactionConfirmation.transaction.set({"id": "27"});
     * </code></pre>
     * @public
     */
    parent.ecommerce.transactionConfirmation.transaction = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var transactionConfirmation = {};
                transactionConfirmation[Keys.transaction] = {};
                _setValueFromKey(tagObject, Properties.transaction.id, 'id', transactionConfirmation[Keys.transaction]);
                // Ecommerce
                parent.event.set(Types.transaction.confirmation, transactionConfirmation[Keys.transaction], Keys.transaction, 'ecommerce');
                _updateCartConfirmation(transactionConfirmation[Keys.transaction][Properties.transaction.id], null);
                _updateProductPurchased(transactionConfirmation[Keys.transaction][Properties.transaction.id], null);
                // SalesTracker
                if (_config.autoSalesTracker) {
                    _processTransaction(tagObject);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageObject, {
                    type: Types.transaction.confirmation,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction confirmation (helper).
     * @alias ecommerce.transactionConfirmation.shipping.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.transactionConfirmation.shipping.set({
                    "delivery": "My carrier",
                    "costTaxIncluded": 8.4,
                    "costTaxFree": 7
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.transactionConfirmation.shipping = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var transactionConfirmation = {};
                transactionConfirmation[Keys.shipping] = {};
                _setValueFromKey(tagObject, Properties.shipping.delivery, 'delivery', transactionConfirmation[Keys.shipping]);
                _setValueFromKey(tagObject, Properties.shipping.costTaxIncluded, 'costTaxIncluded', transactionConfirmation[Keys.shipping]);
                _setValueFromKey(tagObject, Properties.shipping.costTaxFree, 'costTaxFree', transactionConfirmation[Keys.shipping]);
                // Ecommerce
                parent.event.set(Types.transaction.confirmation, transactionConfirmation[Keys.shipping], Keys.shipping, 'ecommerce');
                // SalesTracker
                if (_config.autoSalesTracker) {
                    _processShipping(tagObject);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageObject, {
                    type: Types.transaction.confirmation,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction confirmation (helper).
     * @alias ecommerce.transactionConfirmation.payment.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.transactionConfirmation.payment.set({"mode": "Chèque"});
     * </code></pre>
     * @public
     */
    parent.ecommerce.transactionConfirmation.payment = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var transactionConfirmation = {};
                transactionConfirmation[Keys.payment] = {};
                _setValueFromKey(tagObject, Properties.payment.mode, 'mode', transactionConfirmation[Keys.payment]);
                parent.event.set(Types.transaction.confirmation, transactionConfirmation[Keys.payment], Keys.payment, 'ecommerce');
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageObject, {
                    type: Types.transaction.confirmation,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction confirmation (helper).
     * @alias ecommerce.transactionConfirmation.customer.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {object} Tag object
     * <pre><code class="javascript">tag.ecommerce.transactionConfirmation.customer.set({
                    "new": 0
                });
     * </code></pre>
     * @public
     */
    parent.ecommerce.transactionConfirmation.customer = {
        set: function (tagObject) {
            if (_isObject(tagObject)) {
                var transactionConfirmation = {};
                transactionConfirmation[Keys.customer] = {};
                _setValueFromKey(tagObject, Properties.customer.new, 'new', transactionConfirmation[Keys.customer]);
                // Ecommerce
                parent.event.set(Types.transaction.confirmation, transactionConfirmation[Keys.customer], Keys.customer, 'ecommerce');
                // SalesTracker
                if (_config.autoSalesTracker) {
                    _processCustomer(tagObject);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageObject, {
                    type: Types.transaction.confirmation,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Tagging method for transaction confirmation (helper).
     * @alias ecommerce.transactionConfirmation.products.set
     * @memberof! ATInternet.Tracker.Tag#
     * @function
     * @param tagObject {Array} Tag object
     * <pre><code class="javascript">tag.ecommerce.transactionConfirmation.products.set([{
                    "id": "2",
                    "variant": "2",
                    "name": "Chemisier",
                    "brand": "Fashion Manufacturer",
                    "discount": 0,
                    "priceTaxIncluded": 32.4,
                    "priceTaxFree": 27,
                    "currency": "EUR",
                    "stock": 1,
                    "category1": "Accueil",
                    "category2": "Femmes",
                    "category3": "Tops",
                    "category4": "Chemisiers"
                }]);
     * </code></pre>
     * @public
     */
    parent.ecommerce.transactionConfirmation.products = {
        set: function (tagObject) {
            if (tagObject instanceof Array) {
                var product;
                var products = [];
                var idCart = _getCartFromType(Types.transaction.confirmation)[Properties.cart.id];
                var idTransaction = _getTransactionIdFromType(Types.transaction.confirmation);
                for (var i = 0; i < tagObject.length; i++) {
                    product = {};
                    _setValueFromKey(tagObject[i], Properties.product.id, 'id', product);
                    _setValueFromKey(tagObject[i], Properties.product.variant, 'variant', product);
                    _setValueFromKey(tagObject[i], Properties.product.name, 'name', product);
                    _setValueFromKey(tagObject[i], Properties.product.brand, 'brand', product);
                    _setValueFromKey(tagObject[i], Properties.product.discount, 'discount', product);
                    _setValueFromKey(tagObject[i], Properties.product.priceTaxIncluded, 'priceTaxIncluded', product);
                    _setValueFromKey(tagObject[i], Properties.product.priceTaxFree, 'priceTaxFree', product);
                    _setValueFromKey(tagObject[i], Properties.product.currency, 'currency', product);
                    _setValueFromKey(tagObject[i], Properties.product.stock, 'stock', product);
                    _setValueFromKey(tagObject[i], Properties.product.quantity, 'quantity', product);
                    _setValueFromKey(tagObject[i], Properties.product.category1, 'category1', product);
                    _setValueFromKey(tagObject[i], Properties.product.category2, 'category2', product);
                    _setValueFromKey(tagObject[i], Properties.product.category3, 'category3', product);
                    _setValueFromKey(tagObject[i], Properties.product.category4, 'category4', product);
                    _setValueFromKey(tagObject[i], Properties.product.category5, 'category5', product);
                    _setValueFromKey(tagObject[i], Properties.product.category6, 'category6', product);
                    products.push(product);
                }
                // Create 'product.purchased' events
                _setProductPurchased(idTransaction, idCart, products);
                // SalesTracker
                if (_config.autoSalesTracker) {
                    _processCartProducts(tagObject);
                }
            }
            else if (tagObject) {
                /* @if debug */
                parent.debug(debugError.trigger, debugError.level, debugError.messageArray, {
                    type: Types.transaction.confirmation,
                    data: tagObject,
                    origin: 'ecommerce'
                });
                /* @endif */
            }
        }
    };

    /**
     * Launch plugin when all dependencies are loaded.
     * @memberof ATInternet.Tracker.Plugins.Ecommerce#
     * @function
     * @private
     */
    var _init = function () {
        _domain = _config.defaultCollectSubdomain + _config.defaultCollectDomains[0];
        if (_config.collectDomain) {
            _domain = String(_config.collectDomain);
        }
        else {
            var collectDomain = '';
            var log = parent.getConfig('logSSL') || parent.getConfig('log');
            var domain = parent.getConfig('domain');
            if (log && domain) {
                collectDomain = log + '.' + domain;
            }
            else {
                collectDomain = parent.getConfig('collectDomainSSL') || parent.getConfig('collectDomain');
            }
            for (var i = 0; i < _config.defaultCollectDomains.length; i++) {
                if (collectDomain.indexOf(_config.defaultCollectDomains[i]) > -1) {
                    _domain = _config.defaultCollectSubdomain + _config.defaultCollectDomains[i];
                    break;
                }
            }
        }
    };

    _init();

    /* ---------------------------------- onDispatch ------------------------------------------------- */

    /**
     * [Helper added by plugin {@link ATInternet.Tracker.Plugins.Ecommerce Ecommerce}] Will be called by tracker.dispatch if any event has been set.
     * @alias ecommerce.onDispatch
     * @memberof! ATInternet.Tracker.Tag#
     * @param callback {function} Callback to execute
     * @function
     * @private
     */
    parent.ecommerce.onDispatch = function (callback) {
        parent.event.onDispatch(callback, 'ecommerce', _domain);
    };

    // For unit tests on private elements !!!
    /* @if test */
    var _this = this;
    _this._isObject = _isObject;
    _this._setValueFromKey = _setValueFromKey;
    _this._processCart = _processCart;
    _this._processOrder = _processOrder;
    _this._processPromotionalCode = _processPromotionalCode;
    _this._processTransaction = _processTransaction;
    _this._processShipping = _processShipping;
    _this._processCustomer = _processCustomer;
    _this._processProductCategories = _processProductCategories;
    _this._processCartProducts = _processCartProducts;
    _this._processViewedProducts = _processViewedProducts;
    _this._getCartFromType = _getCartFromType;
    _this._getTransactionIdFromType = _getTransactionIdFromType;
    _this._setEventFromProducts = _setEventFromProducts;
    _this._setProductDisplay = _setProductDisplay;
    _this._setProductClick = _setProductClick;
    _this._setProductPageDisplay = _setProductPageDisplay;
    _this._setProductAddToCart = _setProductAddToCart;
    _this._setProductRemoveFromCart = _setProductRemoveFromCart;
    _this._setCartCreation = _setCartCreation;
    _this._updateCartCreation = _updateCartCreation;
    _this._setCartConfirmation = _setCartConfirmation;
    _this._updateCartConfirmation = _updateCartConfirmation;
    _this._setProductPurchased = _setProductPurchased;
    _this._updateProductPurchased = _updateProductPurchased;
    _this._getFullName = _getFullName;
    _this._init = _init;
    _this._domain = _domain;
    /* @endif */

};
window['ATInternet']['Tracker']['addPlugin']('Ecommerce');