/* Copyright Nexi Payments Thu Mar 20 02:54:53 CET 2025*/
/**
 * Libreria SDK Javascript
 */
var XPay = (function() {
    // private properties
    var APIKey = "";
    var codTrans = "";
    var fullRedirect = true;

    var currentEnvironment;
    var currentBaseDomain = undefined;
    var errors = {};
    var isTest = false;
    var config = {};
    var jsToken = "d8b79525-4c9b-47b6-b9bc-3a9ac53676af";
    var buildToken = "";
    var buildBToken = "";
    var inSending = false;
    
    var currentOpenIFrame = undefined;
    
    var applePaySession;

    const MSG_VALID_ORDER = ["pan","cvv","scadenza"];
    
    const MSG_TYPES = {
        VALIDAZIONE : "validazione",
        CREANONCE: "creaNonce",
        CREANONCE3DS: "creaNonce3DS",
        GRAPHICS: "graphics",
        PAYMENTRESULT: "paymentResult",
        CLOSEIFRAME: "closeIframe",
        BLOCKPARENTPAGE: "blockParentPage",
        APPLEPAY: "ApplePay",
        SPLITBUILD: "SplitBuild",
        FASTCHECKOUT: "Fastcheckout"
    };
    
    const FASTCHECKOUT_PHASES = {
        "STARTING": function(e, payload){
            createEvent(e, "XPay_Payment_Started", {"paymentMethod" : "fastCheckout" });
            
            if(currentOpenIFrame != undefined){
                logNexi("<"+ APIKey +"> Esiste un iframe gia' aperto");
                return;
            }
            
            var attr = {};
            var stile = {};
            attr.scrolling = "no";
            attr.id = "__xpay_fc_frame";
            attr.name = attr.id;
            currentOpenIFrame = attr.id;
            attr.frameborder = "0";
            attr.allowtransparency = "true";
            attr.height = "100%";
            attr.width = "100%";
            attr.src = "#";

            stile.width = "100%";
            stile.height = "100%";
            stile.border = "none";
            stile.margin = "0px";
            stile.padding = "0px";
            stile.overflow = "auto";
            stile.zIndex = "2147483647";
            stile.display = "block";
            stile.visibility = "visible";
            stile.position = "fixed";
            stile.left = "0";
            stile.top = "0";
            stile.backgroundColor = 'rgba(' + [0,0,0,0.7].join(',') + ')';
            stile.backgroundImage = BASE_DOMAIN[currentEnvironment]+'/ecomm/payment/img/loader.png';
            var options = { "style": stile, attributes : attr};
            createElement("IFRAME", options, document.body);

            var attrFrm = {};
            attrFrm.method = "post";
            attrFrm.action = currentBaseDomain +"/ecomm/ecomm/DispatcherBuild";
            attrFrm.target = attr.id;
            attrFrm.acceptCharset = "iso-8859-1";
            var form = createElement("FORM", { attributes : attrFrm }, document.body);
            for (var key in payload)
                addInputParam(form, key, payload[key]);
            
            form.submit();
            document.body.removeChild(form);
            
            var ifrmFc = document.getElementById("__xpay_fastcheckout");
            ifrmFc && ifrmFc.parentNode.removeChild(ifrmFc);
        }
    };
    
    const APPLEPAY_PHASES = {
        "STARTING": function(e, appleInfos){
            !this["PARAM"].hostedpage && createEvent(e, "XPay_Payment_Started", {"paymentMethod" : "ApplePay" });
            
            applePaySession = new ApplePaySession(2, appleInfos);

            applePaySession.onvalidatemerchant = function(event){
                var f = APPLEPAY_PHASES["PARAM"].ifrName === undefined ? document.getElementsByTagName('IFRAME') : document.getElementsByName(APPLEPAY_PHASES["PARAM"].ifrName);
                APPLEPAY_PHASES.notificaIfr(f, { type : "ApplePayValid", payload : event.validationURL});
            };
            
            applePaySession.onshippingmethodselected = function(event) {
                total = {};
                lineItems = [];
                applePaySession.completeShippingMethodSelection(ApplePaySession.STATUS_SUCCESS, total, lineItems);
            };
            
            applePaySession.onpaymentauthorized = function(event) {
                paymentCredentials = event.payment;
                var f = APPLEPAY_PHASES["PARAM"].ifrName === undefined ? document.getElementsByTagName('IFRAME') : document.getElementsByName(APPLEPAY_PHASES["PARAM"].ifrName);
                APPLEPAY_PHASES.notificaIfr(f, { type : "ApplePayEPC", payload: paymentCredentials});
            };
            
            applePaySession.oncancel = function(event){
                if(APPLEPAY_PHASES["PARAM"].hostedpage){
                    var f = APPLEPAY_PHASES["PARAM"].ifrName === undefined ? document.getElementsByTagName('IFRAME') : document.getElementsByName(APPLEPAY_PHASES["PARAM"].ifrName);
                    APPLEPAY_PHASES.notificaIfr(f, { type : "ApplePayAbort", payload: {}});
                } else 
                gestioneBack();
            }
            
            applePaySession.abort = function(event){
                if(APPLEPAY_PHASES["PARAM"].hostedpage){
                    var f = APPLEPAY_PHASES["PARAM"].ifrName === undefined ? document.getElementsByTagName('IFRAME') : document.getElementsByName(APPLEPAY_PHASES["PARAM"].ifrName);
                    APPLEPAY_PHASES.notificaIfr(f, { type : "ApplePayAbort", payload: {}});
                } else 
                gestioneBack();
            }

            applePaySession.begin();
        },
        "VALIDATION": function(e, appleInfos){
            if(appleInfos === {})
                gestioneBack();
            else
                applePaySession.completeMerchantValidation(appleInfos);
        },
        "RESULT": function(e, appleInfos){
            if(appleInfos.esito == "OK")
                applePaySession.completePayment(ApplePaySession.STATUS_SUCCESS);
            else
                applePaySession.completePayment(ApplePaySession.STATUS_FAILURE);

            if(!this["PARAM"].hostedpage){
            var frame = document.getElementsByName("__xpay_btn_frame");
            for(var x=0; x < frame.length; x++)
                frame[x].parentNode.removeChild(frame[x]);
            p_enableMerchantPage();

            createEvent(undefined, "XPay_Payment_Result", appleInfos);
        }
        },
        "INITAPPLEPAY": function(e, appleInfos){
            this["PARAM"].hostedpage = true;
            var tmpIfrName = appleInfos.ifrName;
            if(tmpIfrName){
                this["PARAM"].ifrName = tmpIfrName;
                APPLEPAY_PHASES.notificaIfr(document.getElementsByName(tmpIfrName), { type : "ApplePayInitialized", payload: {}});
                return;
            }

            this["PARAM"].ifrName = undefined;
            APPLEPAY_PHASES.notificaIfr(document.getElementsByTagName('IFRAME'), { type : "ApplePayInitialized", payload: {}});
        },
        "PARAM": {
            hostedpage: false,
            ifrName: "__xpay_btn_frame"
        },
        notificaIfr: function(iframeEl, msg){
            for(var x=0; x < iframeEl.length; x++)
                iframeEl[x].contentWindow.postMessage(JSON.stringify(msg), currentBaseDomain);
        }
    };
    
    const OVERLAY_PHASES = {
        "popup": function(){
            var overlay = document.getElementById("__xpay_overlay_popup");
            if(overlay){
                return true;
            }

            var attr = {};
            var stile = {};
            attr.scrolling = "no";
            attr.id = OVERLAY_PHASES["ID"][0];
            attr.frameborder = "1";
            attr.allowtransparency = "true";
            attr.height = "100%";
            attr.width = "100%";
            attr.src = BASE_DOMAIN[currentEnvironment]+"/ecomm/XPayBuild/Overlay";

            stile.width = "100%";
            stile.height = "100%";
            stile.border = "none";
            stile.margin = "0px";
            stile.padding = "0px";
            stile.overflow = "hidden";
            stile.zIndex = "2147483647";
            stile.position = "fixed";
            stile.left = "0";
            stile.top = "0";
            var options = { "style": stile, attributes : attr};

            createElement("IFRAME", options, document.body);
        },
        "none": function(){
            for(var name in OVERLAY_PHASES["NAME"]){
                var ele= document.getElementsByName(OVERLAY_PHASES["NAME"][name]);
                for(var i=0; i<ele.length; i++)
                    ele[i].parentElement.style.display="none";
            }

            var overlay = document.getElementById(OVERLAY_PHASES["ID"][0]);
            if(overlay){
                document.body.removeChild(overlay);
            }
        },
        "NAME": ["__xpay_btn_frame", "__xpay_card_frame"],
        "ID": ["__xpay_overlay_popup"]
    };

    const CONFIG_PRM = {
        BASECONFIG : "baseConfig",
        PAYMENTPARAMS : "paymentParams",
        LANGUAGE : "language",
        AMBIENTE : "enviroment",
        CONTESTO : "environment",
        TIPOSERVIZIO : "serviceType",
        TIPORICHIESTA : "requestType",
        CUSTOMPARAMS : "customParams",
        INFOSICUREZZA: "informazioniSicurezza"
    };
    

    const SI_FIELDS = {
        payTokenIndicator: "payTokenIndicator",
        challengeIndicator: "challengeIndicator",
        transType: "transType",
        recurringFrequency: "recurringFrequency",
        recurringExpiryDate: "recurringExpiryDate",

        buyer: {
            email: "Buyer_email",
            account: "Buyer_account",
            homePhone: "Buyer_homePhone",
            workPhone: "Buyer_workPhone",
            msisdn: "Buyer_msisdn"
        },

        destinationAddress: {
            city: "Dest_city",
            countryCode: "Dest_country",
            street: "Dest_street",
            street2: "Dest_street2",
            street3: "Dest_street3",
            postalCode: "Dest_cap",
            state: "Dest_state",
            name: "Dest_name",
            surname: "Dest_surname"
        },

        billingAddress: {
            city: "Bill_city",
            countryCode: "Bill_country",
            street: "Bill_street",
            street2: "Bill_street2",
            street3: "Bill_street3",
            postalCode: "Bill_cap",
            state: "Bill_state",
            name: "Bill_name",
            surname: "Bill_surname"
        },

        merchantRiskIndicator: {
            deliveryEmail: "deliveryEmail",
            deliveryTimeframe: "deliveryTimeframe",
            giftCardAmount: {
                value: "gca_value",
                currency: "gca_curr"
            },
            giftCardCount: "giftCardCount",
            preOrderDate: "preOrderDate",
            preOrderPurchaseIndicator: "preOrderPurchaseIndicator",
            reorderItemsIndicator: "reorderItemsIndicator",
            shipIndicator: "shipIndicator"
        },

        cardHolderAcctInfo: {
            chAccDate: "chAccDate",
            chAccAgeIndicator: "chAccAgeIndicator",
            chAccChangeDate: "chAccChangeDate",
            chAccChangeIndicator: "chAccChangeIndicator",
            chAccPwChangeDate: "chAccPwChangeDate",
            chAccPwChangeIndicator: "chAccPwChangeIndicator",
            nbPurchaseAccount: "nbPurchaseAccount",
            destinationAddressUsageDate: "destinationAddressUsageDate",
            destinationAddressUsageIndicator: "destinationAddressUsageIndicator",
            destinationNameIndicator: "destinationNameIndicator",
            txnActivityDay: "txnActivityDay",
            txnActivityYear: "txnActivityYear",
            provisionAttemptsDay: "provisionAttemptsDay",
            suspiciousAccActivity: "suspiciousAccActivity",
            paymentAccAgeDate: "paymentAccAgeDate",
            paymentAccIndicator: "paymentAccIndicator"
        }
    };
    

    const TIPO_SERV_MSG = {
            PAGA_NORM : "paga_norm",
            PAGA_MULTI : "paga_multi",
            PAGA_RICO : "paga_rico",
            PAGA_OC3D : "paga_oc3d"
    };

    const BASE_DOMAIN = {
            TEST : "https://localhost:8443",
            COLL : "https://coll-ecommerce.nexi.it",
            INTEG : "https://int-ecommerce.nexi.it",
            PROD : "https://ecommerce.nexi.it"
        };
    
    const ENVIRONMENT_LIST = {
        TEST : "TEST",
        COLL : "COLL",
        INTEG : "INTEG",
        PROD : "PROD"
    };
    
    const LANGUAGE_LIST = {
        ITA : "ITA",
        JPN : "JPN", 
        SPA : "SPA", 
        RUS : "RUS", 
        FRA : "FRA", 
        ARA : "ARA", 
        ENG : "ENG", 
        GER : "GER", 
        CHI : "CHI", 
        POR : "POR"
    };

    // private methods
    logNexi = function(message, doPost) {
        if (console && console.log && isTest)
            console.log(message);

//        var url = window.location.href;
//        if(url.indexOf("https") === 0 || url.indexOf("http") === 0)
//            if(doPost !== false){
//                var obj = "?jsToken="+ jsToken +"&fileName=xpay.js&msg="+ encodeURI(message);
//                this.doPost(BASE_DOMAIN[currentEnvironment]+"/ecomm/XPayBuild/log", obj, true);
//            }
    };

    doPost = function(postUrl, obj, async){
        var xhr = new XMLHttpRequest();
        xhr.open("POST", postUrl+obj, async);
        xhr.onerror = function () {
            console.log("Eccezione in chiamata ad XPay");
        };
        xhr.send();
        
        if(!async && xhr.status === 200){
            var res = JSON.parse(xhr.response);
            buildToken = res.buildToken;
            buildBToken = res.buildBtnToken;
        }
        
        if(!async && xhr.status !== 200)
            throw ("ERRORE: Impossibile inizializzare SKD");
    };

    createElement = function(tag, options, container) {
        tag = tag.toLowerCase();
        var element = document.createElement(tag);

        if (options.style) {
            var source = options.style;
            var obj = element.style;
            for(var _key in source)
                source.hasOwnProperty(_key) && (obj[_key] = source[_key]);
        }

        if (options.attributes) {
            for (var key in options.attributes) {
                element.setAttribute(key, options.attributes[key]);
            }
        }
        if (container) {
            container.appendChild(element);
        }
        return element;
    };
    
    serializeForm = function(arrayOfInputs) {
        arrayOfInputs["parametriAggiuntivi"] = {};
        arrayOfInputs["apiKey"] = APIKey;
        arrayOfInputs["clientType"] = "da46d661-4e29-383c-b680-4ac701ca5b9a"; // JS// 3.0
        if(config[CONFIG_PRM.TIPOSERVIZIO] != undefined)
            arrayOfInputs["parametriAggiuntivi"].serviceType = config[CONFIG_PRM.TIPOSERVIZIO];

        if(config[CONFIG_PRM.TIPORICHIESTA] != undefined)
            arrayOfInputs["parametriAggiuntivi"].requestType = config[CONFIG_PRM.TIPORICHIESTA];
        
        if(config.hasOwnProperty(CONFIG_PRM.INFOSICUREZZA)){
            delete config[CONFIG_PRM.INFOSICUREZZA].threeDSRequestorChallengeIndicator;
            arrayOfInputs[CONFIG_PRM.INFOSICUREZZA] = config[CONFIG_PRM.INFOSICUREZZA];
        }

        return arrayOfInputs;
    };

    trim = function(stringToTrim) {
        return stringToTrim.replace(/^\s+|\s+$/g,"");
    };

    isEmpty = function(value){
        if (value == undefined || value == null) {
            return true;
        }

        var trimmed = trim(value);
        if (value == "") {
            return true;
            
        }
        return false;
    };

    isEmptyObject = function(obj) {
        for(var prop in obj) {
            if(obj.hasOwnProperty(prop))
                return false;
        }
        return true;
    };

    setAPIKey = function(key) {
        var key = trim(key);
        if(key == undefined || key == ""){
            logNexi("<"+ jsToken +"> ERRORE: json di configurazione non valido");
            throw ("ERRORE: APIKey non valido");
        }

        APIKey = key;
    };
    
    setFullRedirect = function(value) {
        if(value === undefined) return;
        if(value === true || value === false){
            fullRedirect = value;
            return;
        }

        logNexi("<"+ jsToken +"> ERRORE: parametro fullRedirect non valido");
    };

    createEvent = function(e, eventName, msg){
        if ( typeof window.CustomEvent === "function" ){
            //NON ie
            var event = new CustomEvent(eventName, {
                detail: msg,
                cancelable: true,
            });
            if(e && e.currentTarget != null)
                e.currentTarget.dispatchEvent(event);
            else
                window.dispatchEvent(event);
        } else {
            //IE
            var evt = document.createEvent("CustomEvent");
            evt.initCustomEvent(eventName, false, true, msg);
            if(e && e.currentTarget)
                e.currentTarget.dispatchEvent(evt);
            else
                window.parent.dispatchEvent(evt);
        }
    };
    
    p_closeLightbox = function(){
        if(currentOpenIFrame != undefined){
            var ifr = document.getElementById(currentOpenIFrame);
            document.body.removeChild(ifr);
            currentOpenIFrame = undefined;
        }
    }
    
    closeOverlay = function(idOverlay){
        var overlay = document.getElementById(idOverlay);
        overlay.style.display = 'none';
        while (overlay.firstChild) {
            overlay.removeChild(overlay.firstChild);
        }
    };
    
    creaBtnChiudiIframe = function(idFather){
        var btn = document.createElement("BUTTON");
        btn.id = '__xpay_close_overlay';
        btn.style.position = "absolute";
        btn.style.zIndex = "9999";
        btn.style.right = "0";
        btn.style.lineHeight = "25px";
        btn.style.width = "25px";
        btn.style.cursor = "pointer";
        btn.style.background = "#fff";
        btn.style.background = "rgba(255,255,255,.3)";
        btn.style.color = "#000";
        btn.style.border = "0";
        btn.style.padding = "0";
        btn.style.display = "none";
        btn.innerHTML = "&#10005";
        
        document.getElementById(idFather).appendChild(btn);
        return btn;
    };
    
    p_blockMerchantPage = function(){
        if(document.getElementById("__xpay_block"))
            return;
        
        var ifrm = document.createElement("iframe");

        ifrm.setAttribute("src", "about:blank");
        ifrm.setAttribute("id", "__xpay_block");
        ifrm.setAttribute("frameborder", "0");
        ifrm.setAttribute("allowtransparency", "true");
        ifrm.setAttribute("scrolling", "no");

        ifrm.style.width = "100%";
        ifrm.style.height = "100%";
        ifrm.style.zIndex = "1";
        ifrm.style.display = "block";
        ifrm.style.border = "none";
        ifrm.style.visibility = "visible";
        ifrm.style.margin = "0px";
        ifrm.style.padding = "0px";
        ifrm.style.position = "fixed";
        ifrm.style.left = "0";
        ifrm.style.top = "0";
        ifrm.style.overflow = "hidden";
        ifrm.style.backgroundColor = 'transparent';

        document.body.appendChild(ifrm);
    };
    
    p_enableMerchantPage = function(){
        var child = document.getElementById("__xpay_block");
        if(child){
            var parent = document.body;
            parent.removeChild(child);
        }
    };

    gestioneBack = function(){
        var response = {};
        response.alias=APIKey;
        response.codTrans=codTrans;
        response.importo=config.paymentParams.amount;
        response.divisa=config.paymentParams.currency;
        response.esito='ANNULLO';
        
        createEvent(undefined, "XPay_Payment_Result", response);
    };
    
    checkOrigin = function(origin){
        if(currentBaseDomain === undefined){
            for(var base in BASE_DOMAIN){
                if(origin === BASE_DOMAIN[base]){ 
                    currentBaseDomain = origin;
                    return true;
                }
            }
            return false;
        }
        return origin == currentBaseDomain;
    }

    managePostMessage = function(e){
        if(checkOrigin(e.origin)){
            var postData = "";

            try{
                postData = JSON.parse(e.data);
            } catch (ex){
                logNexi("JSON nel formato non valido, chiamata non XPay", false);
                return;
            }
            //logNexi(postData, false);

            if(postData.type == MSG_TYPES.VALIDAZIONE){
                inSending = false;
                var resp = {};
                if(postData.message.payload.errore){
                    errors[postData.message.payload.campo] = postData.message.payload.errore;
                } else {
                    delete errors[postData.message.payload.ok];
                    if(postData.message.payload.ok === 'pan' && postData.message.payload.cobrand){
                        resp = { cobrand : postData.message.payload.cobrand};
                    }
                }

                var msg = "";
                for(var i = 0; i < MSG_VALID_ORDER.length && msg == ""; i++) {
                    if(errors[MSG_VALID_ORDER[i]])
                        msg = errors[MSG_VALID_ORDER[i]];
                }

                this.createEvent(e, postData.message.event, msg != "" ? {errorMessage : msg } : resp);
            } else if (postData.type == MSG_TYPES.SPLITBUILD){
                var frames = document.getElementsByTagName("iframe");
                for (var i = 0; i < frames.length; ++i)
                    if(frames[i].name.indexOf('__xpay_s_') == 0)
                        frames[i].contentWindow.postMessage(e.data,BASE_DOMAIN[currentEnvironment]);
                return;
            }else if (postData.type == MSG_TYPES.PAYMENTRESULT){
                inSending = false;
                var payload = postData.message.payload;
                if(payload.tipo && payload.tipo === "popup"){
                    this.createEvent(e, postData.message.event, payload.esito);
                    var phase = payload.showOverlay;
                    phase && OVERLAY_PHASES[phase]();
                    return;
                }
                p_enableMerchantPage();
                this.createEvent(e, postData.message.event, postData.message.payload);
            } else if(postData.type == MSG_TYPES.CREANONCE) {
                inSending = false;
                var nonceMsg = postData.message.payload;
                var is3DSecure = nonceMsg["3DSecure"];

                if (is3DSecure == true) {
                    var divContent = document.getElementById("__xpay_overlay_content");
                    if(!divContent){
                        var div = document.getElementById("__xpay_overlay");
                        if(div == null){
                            div = document.createElement("div");
                            div.id = '__xpay_overlay';
                            div.style.display = "none";
                            div.style.position = "fixed";
                            div.style.top = "0";
                            div.style.right = "0";
                            div.style.bottom = "0";
                            div.style.left = "0";
                            div.style.zIndex = "2147483647";
                            div.style.textAlign = "center";
                            div.style.background = "rgba(0,0,0,0.5)";
                            document.body.appendChild(div);
                        }
                        divContent = document.createElement("div");
                        divContent.id = '__xpay_overlay_content';
                        divContent.style.position = "relative";
                        divContent.style.display = "inline-block";
                        divContent.style.overflowX = "auto";
                        divContent.style.overflowY = "auto";
                        divContent.style.height = "500px";
                        divContent.style.padding = "0";
                        divContent.style.margin = "0";
                        divContent.style.maxHeight = "99%";
                        divContent.style.background = "#fff";
                        divContent.style["-webkit-overflow-scrolling"] = "touch";
                        divContent.style.backgroundImage = "url('https://ecommerce.nexi.it/ecomm/build/img/loader.gif')";
                        divContent.style.backgroundRepeat = "no-repeat";
                        divContent.style.backgroundPosition = "center";
                        div.appendChild(divContent);
                    }
                    
                    var btnChiudi = creaBtnChiudiIframe("__xpay_overlay_content");
                    btnChiudi.onclick = setLightboxClosed;
                    function setLightboxClosed() {
                        var data = { esito : "KO", errore : { codice : "600", messaggio : "Pagamento annullato dall'utente" } };
                        closeOverlay("__xpay_overlay");
                        createEvent(e, postData.message.event, data);
                    }

                    var ifrm = document.createElement("iframe");
                    var tipoRichiesta = "PA";
                    if(!isEmpty(config[CONFIG_PRM.TIPORICHIESTA])) 
                        tipoRichiesta = config[CONFIG_PRM.TIPORICHIESTA];
                    else if(config[CONFIG_PRM.CUSTOMPARAMS] && !isEmpty(config[CONFIG_PRM.CUSTOMPARAMS]["tipo_richiesta"])){
                        tipoRichiesta = config[CONFIG_PRM.CUSTOMPARAMS]["tipo_richiesta"];
                    }

                    var tdsDinamico = "";
                    if(config[CONFIG_PRM.CUSTOMPARAMS] && !isEmpty(config[CONFIG_PRM.CUSTOMPARAMS]["3dsDinamico"])){
                        tdsDinamico = config[CONFIG_PRM.CUSTOMPARAMS]["3dsDinamico"];
                    }

                    ifrm.setAttribute("src", currentBaseDomain+"/ecomm/hostedPayments/3DSDecoder?ElemLike=Y&ID=" + nonceMsg["xpayNonce"] + "&Alias=" + APIKey +"&tipo_richiesta="+tipoRichiesta+"&3dsDinamico="+tdsDinamico);
                    ifrm.setAttribute("scrolling", "auto");
                    ifrm.setAttribute("name", "__xpay_3Ds_frame");
                    ifrm.setAttribute("id", "__xpay_3Ds_frame");
                    ifrm.setAttribute("frameborder", "0");

                    ifrm.style.maxHeight = "99%";
                    ifrm.style.overflowX = "auto";
                    ifrm.style.overflowY = "auto";
                    ifrm.style.height = "500px";

                    var mq = window.matchMedia('all and (max-width: 700px)');
                    if(mq.matches) {
                        ifrm.style.minWidth = "363px";
                        btnChiudi.style.marginLeft = "0";
                        btnChiudi.style.marginTop = "0";
                        btnChiudi.style.right = "0";
                    } else {
                        ifrm.style.width = "500px";
                    }

                    ifrm.onload = function() {
                        divContent.style.background = "#fff";
                        btnChiudi.style.display = "block";
                    };

                    mq.addListener(function(changed) {
                        if(changed.matches) {
                            if(ifrm != undefined){
                                ifrm.style.marginTop = "0px";
                                ifrm.style.minWidth = "363px";
                                ifrm.style.width = "100%";
                            }

                            if(btnChiudi != undefined){
                                btnChiudi.style.marginLeft = "0";
                                btnChiudi.style.right = "0";
                            }
                        } else {
                            if(ifrm != undefined){
                                ifrm.style.width = "500px";
                                ifrm.style.minWidth = "0px";
                            }

                            if(btnChiudi != undefined){
                                btnChiudi.style.marginLeft = "475px";
                            }
                        }
                    });

                    document.getElementById("__xpay_overlay_content").appendChild(btnChiudi);
                    document.getElementById("__xpay_overlay_content").appendChild(ifrm);
                    document.getElementById("__xpay_overlay").style.display = 'block';
                    e.stopPropagation();
                } else {
                    this.createEvent(e, postData.message.event, postData.message.payload);
                }
            } else if(postData.type == MSG_TYPES.CREANONCE3DS) {
                inSending = false;
                closeOverlay("__xpay_overlay");
                this.createEvent(e, postData.message.event, postData.message.payload);
            } else if(postData.type == MSG_TYPES.CLOSEIFRAME){
                p_closeLightbox();
            } else if(postData.type == MSG_TYPES.BLOCKPARENTPAGE){
                p_blockMerchantPage();
            } else if(postData.type == MSG_TYPES.GRAPHICS){
                var evento = postData.message.event;
                if(evento == "XPay_Ready"){
                    var br = postData.message.payload.buildReady;
                    if(br == "paymentButton" ){
                        if(postData.message.payload.height){
                            if(postData.message.payload.idfrm)
                                document.getElementById(postData.message.payload.idfrm).style.height = postData.message.payload.height.toString()+"px";
                        }
                    }

                    this.createEvent(e, evento, br);
                } else if (evento == "XPay_Graphics"){
                    if(postData.message.payload.height){
                        if(postData.message.payload.idfrm)
                            document.getElementById(postData.message.payload.idfrm).style.height = postData.message.payload.height.toString()+"px";
                    }
                    if(postData.message.payload.enableParent)
                        p_enableMerchantPage();
                } else {
                    var phase = postData.message.payload.showOverlay;
                    phase && OVERLAY_PHASES[phase]();
                    this.createEvent(e, evento, postData.message.payload.paymentMethod);
                }
            } else if(postData.type == MSG_TYPES.APPLEPAY){
                var phase = postData.message.payload.fase;
                APPLEPAY_PHASES[phase](e,postData.message.payload.appleInfos);
            } else if(postData.type == MSG_TYPES.FASTCHECKOUT) {
                var phase = postData.message.payload.fase;
                FASTCHECKOUT_PHASES[phase](e,postData.message.payload.fc);
            }
        } else {
            logNexi("Post message non valida " + e.data, false); 
        }
    };
    window.addEventListener("message", managePostMessage);
    
    savePaymentParam = function(mConfig){
        try{
            JSON.stringify(mConfig);
        } catch (e) {
            logNexi("<"+ jsToken +"> ERRORE: json di configurazione non valido");
            throw ("ERRORE: json di configurazione non valido");
        }

        if(mConfig[CONFIG_PRM.BASECONFIG] == undefined){
            logNexi("<"+ jsToken +"> ERRORE: parametro BaseConfig non presente");
            throw ("ERRORE: parametro obbligatorio "+ CONFIG_PRM.BASECONFIG +" non presente");
        }

        setAPIKey(mConfig[CONFIG_PRM.BASECONFIG]["apiKey"]);

        if(mConfig[CONFIG_PRM.PAYMENTPARAMS] == undefined){
            logNexi("<"+ APIKey +"> ERRORE: parametro paymentparams non presente");
            throw ("ERRORE: parametro obbligatorio "+ CONFIG_PRM.PAYMENTPARAMS +" non presente");
        }

        setEnvironment(mConfig[CONFIG_PRM.BASECONFIG][CONFIG_PRM.AMBIENTE] || mConfig[CONFIG_PRM.BASECONFIG][CONFIG_PRM.CONTESTO]);
        setFullRedirect(mConfig[CONFIG_PRM.BASECONFIG]["fullRedirect"]);

        if(mConfig[CONFIG_PRM.LANGUAGE] != undefined){
            if(LANGUAGE_LIST[mConfig[CONFIG_PRM.LANGUAGE]] == undefined){
                logNexi("WARNING: "+ CONFIG_PRM[LANGUAGE] +" non valido, verra' usato ITA", false);
                mConfig[CONFIG_PRM[LANGUAGE]] = this.LANGUAGE.ITA;
            }
        }

        var target = mConfig[CONFIG_PRM.TIPORICHIESTA];
        if(isEmpty(target) && mConfig[CONFIG_PRM.CUSTOMPARAMS] && !isEmpty(mConfig[CONFIG_PRM.CUSTOMPARAMS]["tipo_richiesta"])){
            target = mConfig[CONFIG_PRM.CUSTOMPARAMS]["tipo_richiesta"];
        }
        
        if(target != undefined){
            if(target != 'PP' && target != 'PA' && target != 'PO' && target != 'PR' && target != 'VC' && target != 'AC'){
                logNexi("WARNING: "+ CONFIG_PRM.TIPORICHIESTA +" non valido, verra' usato PA", false);
                mConfig[CONFIG_PRM.TIPORICHIESTA] = 'PA';
            }
        }
        
        if(target == 'VC' && mConfig[CONFIG_PRM.PAYMENTPARAMS]["amount"] != "0"){
            logNexi("<"+ APIKey +"> ERRORE: amount diverso da 0 non valido per "+ CONFIG_PRM.TIPORICHIESTA +" VC");
            throw ("ERRORE: amount diverso da 0 non valido");
        }
        
        var contrEmpty = !mConfig["customParams"] || isEmpty(mConfig["customParams"]['num_contratto']);
        var gruppoEmpty = false; //!mConfig["customParams"] || isEmpty(mConfig["customParams"]['gruppo']);
        
        if(mConfig[CONFIG_PRM.TIPOSERVIZIO] != undefined){
            if(TIPO_SERV_MSG [mConfig[CONFIG_PRM.TIPOSERVIZIO].toUpperCase()] == undefined){
                logNexi("WARNING: "+ CONFIG_PRM.TIPOSERVIZIO +" non valido, verra' usato paga_norm", false);
                mConfig[CONFIG_PRM.TIPOSERVIZIO] = 'paga_norm';
            }
            if (mConfig[CONFIG_PRM.TIPOSERVIZIO] == 'paga_oc3d'){
                if (mConfig[CONFIG_PRM.TIPORICHIESTA] != "PP" && mConfig[CONFIG_PRM.TIPORICHIESTA] != "PR" && mConfig[CONFIG_PRM.TIPORICHIESTA] != "AC"){
                    logNexi("WARNING: "+ CONFIG_PRM.TIPORICHIESTA +" non valido, verrà usato PP");
                    mConfig[CONFIG_PRM.TIPORICHIESTA] = "PP";
                }
                if (mConfig[CONFIG_PRM.TIPORICHIESTA]=='PR' || mConfig[CONFIG_PRM.TIPORICHIESTA]=='AC'){
                    if (contrEmpty){
                        logNexi("ERRORE: parametro obbligatorio <num_contratto> non presente");
                        throw ("ERRORE: parametro obbligatorio <num_contratto> non presente");
                    }
                    if (gruppoEmpty){
                        logNexi("ERRORE: parametro obbligatorio <gruppo> non presente");
                        throw ("ERRORE: parametro obbligatorio <gruppo> non presente");
                    }
                }
            }

            if (mConfig[CONFIG_PRM.TIPOSERVIZIO] == 'paga_norm'){                
                if (mConfig[CONFIG_PRM.TIPORICHIESTA] != 'PA' || !contrEmpty /*|| !gruppoEmpty*/ ){
                    logNexi("ERRORE: per un pagamento normale non devono esserci parametri ricorrenti");
                    throw ("ERRORE: per un pagamento normale non devono esserci parametri ricorrenti");
                }
            }
        }

        var tipoServizio = mConfig["customParams"] && mConfig["customParams"]['tipo_servizio'];
        var serviceType  = mConfig[CONFIG_PRM.TIPOSERVIZIO];
        if (!isEmpty(serviceType) && !isEmpty(tipoServizio) && serviceType !== tipoServizio){
            var gruppo = mConfig["customParams"] && mConfig["customParams"]['gruppo'];
            if(!isEmpty(gruppo)){
                if(tipoServizio !== 'paga_rico' && serviceType === 'paga_rico')
                    mConfig[CONFIG_PRM.TIPOSERVIZIO] = tipoServizio;
            }
        }        

        if(target === 'PP' && mConfig[CONFIG_PRM.TIPOSERVIZIO] === 'paga_oc3d' && APIKey === 'payment_3439138'){
            mConfig[CONFIG_PRM.TIPOSERVIZIO] = 'paga_multi';
        }

        if(target === 'PP' && (APIKey === 'payment_3479134' || APIKey === 'payment_2135925' || APIKey === 'payment_doctorshop' || APIKey === 'payment_3492782')){
                mConfig[CONFIG_PRM.TIPOSERVIZIO] = '';
                mConfig[CONFIG_PRM.TIPORICHIESTA] = '';
        }

        delete mConfig[CONFIG_PRM.BASECONFIG];
        config = mConfig;
    };
    
    hideConfigKeys = function(key, value){
        if(key !== CONFIG_PRM.INFOSICUREZZA) {
            return value;
        }
    }
    
    setSecurityInfo = function(infoSicurezza){
        if (config === null || config === undefined || isEmptyObject(config)) {
            logNexi("ERROR: serve invocare prima la funzione setConfig o initLightbox", false);
            return false;
        }

        if (infoSicurezza === null || infoSicurezza === undefined) {
            logNexi("INFO:"+ CONFIG_PRM.INFOSICUREZZA +" non valorizzato o gia' valorizzato", false);
            return false;
        }

        if(config.hasOwnProperty(CONFIG_PRM.INFOSICUREZZA)){
            logNexi("WARNING: "+ CONFIG_PRM.INFOSICUREZZA +" gia' valorizzate", false);
            return false;
        }

        config[CONFIG_PRM.INFOSICUREZZA] = infoSicurezza;
        return true;
    }
    
    addInputParam = function(appendForm, inputName, inputValue){
        var i = document.createElement("input"); 
        i.setAttribute('type',"hidden");
        i.setAttribute('name', inputName);
        i.setAttribute('value', inputValue);
        
        appendForm.appendChild(i);
    }
    
    dispatchParam = function(appendForm){
        var pp = config[CONFIG_PRM.PAYMENTPARAMS];

        if(isEmpty(pp.amount) || isEmpty(pp.currency) || isEmpty(pp.transactionId) || isEmpty(pp.mac)){
            logNexi("<"+ APIKey +"> ERRORE: parametro importo/divisa/codtrans/mac non presente");
            throw ("ERRORE: parametro obbligatorio non presente");
        }
        
        addInputParam(appendForm, "importo", pp.amount);
        addInputParam(appendForm, "divisa", pp.currency);
        addInputParam(appendForm, "codTrans", pp.transactionId);
        addInputParam(appendForm, "mac", pp.mac);

        if(!isEmpty(pp.mail)){
            addInputParam(appendForm, "mail", pp.mail);
        }

        if(!isEmpty(pp.urlPost)){
            addInputParam(appendForm, "urlpost", pp.urlPost);
        }

        var cp = config[CONFIG_PRM.CUSTOMPARAMS];
        for (var key in cp) {
            if (cp.hasOwnProperty(key)) {
              var val = cp[key];
              addInputParam(appendForm, key, val);
            }
        }

        addInputParam(appendForm, "languageId", config[CONFIG_PRM.LANGUAGE]);
        addInputParam(appendForm, "alias", APIKey);

        if(config[CONFIG_PRM.TIPORICHIESTA]){
            addInputParam(appendForm, "tipo_richiesta", config[CONFIG_PRM.TIPORICHIESTA]);
        }
        
        if(config[CONFIG_PRM.TIPOSERVIZIO]){
            addInputParam(appendForm, "tipo_servizio", config[CONFIG_PRM.TIPOSERVIZIO]);
        }

        addInputParam(appendForm, "xpay__lb__token", buildToken);

        if(config[CONFIG_PRM.INFOSICUREZZA]){
            var jsonsi = config[CONFIG_PRM.INFOSICUREZZA];
            for (var prop in jsonsi) {
                var pn = SI_FIELDS[prop];
                scrivi(pn, jsonsi[prop], appendForm);
            }
        }
    }

    scrivi = function(pn, jsonsi, appendForm){
        if (typeof pn === 'object') {
            for(var propNested in pn) {
                if(jsonsi.hasOwnProperty(propNested)){
                    scrivi(pn[propNested], jsonsi[propNested], appendForm);
                }
            }
        } else {
            addInputParam(appendForm, pn, jsonsi);
        }
    }

    setEnvironment = function(env) {
        if(BASE_DOMAIN[env] == undefined)
            throw ("ERRORE: Utilizzare come ambiente uno di quelli specificati XPay.Environments");
        
        currentEnvironment = env;
        isTest = (env == ENVIRONMENT_LIST.TEST);
    };
    
    selectedcardClear = function(choosenBrands){
        if(!choosenBrands) return;

        if(choosenBrands.constructor !== Array){
            logNexi("<"+ APIKey +"|"+ codTrans +"> ERRORE: i brand devono essere in un array");
            throw ("ERRORE: selectedcard non in un array");
        }
        var selected  = new Array();
        for(var i=0; i<choosenBrands.length; i++)
            selected.push(choosenBrands[i].toUpperCase());
        return selected;
    };
    
    return {

        LANGUAGE : LANGUAGE_LIST,

        init : function() {
            this.Environments = ENVIRONMENT_LIST;

            this.PaymentMethods = {
                ALIPAY : "alipay",
                AMAZONPAY : "AmazonPay",
                APPLEPAY : "ApplePay",
                GOOGLEPAY : "GooglePay",
                MASTERPASS : "Masterpass",
                MYBANK : "MyBank",
                NEXIPAY : "NexiPay",
                PAGOBANCOMAT : "Pagobancomat",
                PAYPAL : "Paypal",
                PAYPAL_BNPL: "Paypal_BNPL",
                WECHATPAY: "wechatpay",
                GIROPAY: "giropay",
                IDEAL: "ideal",
                EPS: "eps",
                BCMC: "bcmc",
                P24: "p24",
                BANCOMATPAY: "BancomatPay",
                PPRO_MYBANK: "PPro_Mybank",
                SKRILL: "skrill",
                SKRILL1TAP: "skrillonetap",
                SATISPAY: "satispay",
                MULTIBANCO: "multibanco",
                PAGOINCONTO: "PagoInConto",
                HEYLIGHT: "Heylight"
            };
            
            this.CardBrand = {
                AMEX : "AMEX",
                DINERS : "DINERS",
                MAESTRO : "MAESTRO",
                MASTERCARD : "MASTERCARD",
                VISA : "VISA",
                UPI : "UPI",
                JCB : "JCB"
            }

            currentEnvironment = null;

            this.OPERATION_TYPES = {
                CARD : function (custom, choosenBrands){
                    logNexi("<"+ APIKey +"|"+ codTrans +"> INFO: inizializzazione carta");
                    var tmpConfig = config;
                    var sel = selectedcardClear(choosenBrands);
                    sel && (tmpConfig["displayedBrand"] = sel);
                    return new XpayCard(APIKey, currentBaseDomain, tmpConfig, custom, buildToken);
                },
                PAYMENT_BUTTON : function (custom){
                    logNexi("<"+ APIKey +"|"+ codTrans +"> INFO: mostro bottoniera");
                    var tmpConfig = JSON.parse(JSON.stringify(config));
                    
                    var target = config[CONFIG_PRM.TIPORICHIESTA];
                    if(isEmpty(target) && config[CONFIG_PRM.CUSTOMPARAMS] && !isEmpty(config[CONFIG_PRM.CUSTOMPARAMS]["tipo_richiesta"]))
                        target = config[CONFIG_PRM.CUSTOMPARAMS]["tipo_richiesta"];

                    if(target === "AC"){
                        logNexi("<"+ APIKey +"|"+ codTrans +"> WARN: Aggiorna Contratto non supportato");
                        return undefined;
                    }

                    if(tmpConfig[CONFIG_PRM.INFOSICUREZZA]){
                        var is = {};
                        for (var prop in tmpConfig[CONFIG_PRM.INFOSICUREZZA]) {
                            var pn = SI_FIELDS[prop];
                            var obj = tmpConfig[CONFIG_PRM.INFOSICUREZZA][prop];
                            if(obj.constructor == Object){
                                for(p in obj)
                                    if(obj[p].constructor != Object)
                                        is[pn[p]] = obj[p];
                            }
                        }
                    }
                    tmpConfig[CONFIG_PRM.INFOSICUREZZA] = is;

                    tmpConfig.fullRedirect = fullRedirect;
                    var sel = selectedcardClear(custom);
                    sel && (tmpConfig["displayedButtons"] = sel);
                    return new XpayPaymentButton(APIKey, currentBaseDomain, tmpConfig, buildBToken);
                },
                SPLIT_CARD : function (custom, choosenBrands) {
                    logNexi("<"+ APIKey +"|"+ codTrans +"> INFO: inizializzazione split card");
                    var target = config[CONFIG_PRM.TIPORICHIESTA];
                    if(isEmpty(target) && config[CONFIG_PRM.CUSTOMPARAMS] && !isEmpty(config[CONFIG_PRM.CUSTOMPARAMS]["tipo_richiesta"]))
                        target = config[CONFIG_PRM.CUSTOMPARAMS]["tipo_richiesta"];
                    var targetts = config[CONFIG_PRM.TIPOSERVIZIO];
                    if(isEmpty(targetts) && config[CONFIG_PRM.CUSTOMPARAMS] && !isEmpty(config[CONFIG_PRM.CUSTOMPARAMS]["tipo_servizio"]))
                        targetts = config[CONFIG_PRM.CUSTOMPARAMS]["tipo_servizio"];
                    if(target === "PR")
                        throw ("ERRORE: Ricorrenze non supportate");
                    var tmpConfig = config;
                    var sel = selectedcardClear(choosenBrands);
                    sel && (tmpConfig["displayedBrand"] = sel);
                    return new XpaySplitCard(APIKey, currentBaseDomain, tmpConfig, custom, buildToken);
                }
            };

            currentBaseDomain = BASE_DOMAIN.TEST;
            isTest = true
        },

        setEnvironment : function(env) {
            if(BASE_DOMAIN[env] == undefined)
                throw ("ERRORE: Utilizzare come ambiente uno di quelli specificati XPay.Environments");
            
            currentEnvironment = env;
            currentBaseDomain = BASE_DOMAIN[env];
            isTest = (env == this.Environments.TEST);
        },

        setConfig : function(mConfig){
            savePaymentParam(mConfig);
            
            currentBaseDomain = BASE_DOMAIN[currentEnvironment];
            
            codTrans = config[CONFIG_PRM.PAYMENTPARAMS]["transactionId"];
            doPost(currentBaseDomain+"/ecomm/XPayBuild/init", "?apiKey="+ APIKey +"&config="+ encodeURIComponent(JSON.stringify(config, hideConfigKeys)), false);
            
            logNexi("<"+ APIKey +"|"+ codTrans +"> INFO richiesta: "+ config);
        },
        
        initLightbox : function(mConfig){
            savePaymentParam(mConfig);

            currentBaseDomain = BASE_DOMAIN[currentEnvironment];
            codTrans = config[CONFIG_PRM.PAYMENTPARAMS]["transactionId"];

            doPost(currentBaseDomain+"/ecomm/XPayBuild/initLightBox", "?apiKey="+ APIKey +"&config="+ encodeURIComponent(JSON.stringify(config, hideConfigKeys)), false);

            logNexi("<"+ APIKey +"|"+ codTrans +"> INFO richiesta: "+ config);
        },

        mountFastCheckout : function(mountPoint, paymentConfig, choosenBrands){
            savePaymentParam(paymentConfig);
            codTrans = config[CONFIG_PRM.PAYMENTPARAMS]["transactionId"];
            logNexi("<"+ APIKey +"|"+ codTrans +"> INFO: inizializzazione fastcheckout");

            var target = config[CONFIG_PRM.TIPORICHIESTA];
            if(!isEmpty(target) && target !== "PA")
                throw ("ERRORE: Pagamenti ricorrenti non supportati");

            var elemMount = document.getElementById(mountPoint);
            if(elemMount == null)
                throw ("ERRORE: MountPoint \""+ mountPoint +"\" non presente nella pagina");

            if(elemMount.tagName != 'DIV')
                throw ("ERRORE: MountPoint \""+ mountPoint +"\" non e' un div");

            if(document.getElementById("__xpay_fastcheckout"))
                throw ("ERRORE: chiamata duplicata a mountFastCheckout");

            var sel = selectedcardClear(choosenBrands);
            sel && (tmpConfig["displayedBrand"] = sel);

            currentBaseDomain = BASE_DOMAIN[currentEnvironment];

            var attr = {};
            var stile = {};
            attr.scrolling = "no";
            attr.id = "__xpay_fastcheckout";
            attr.name = attr.id;
            attr.frameborder = "1";
            attr.allowtransparency = "true";
            attr.height = "57px";
            attr.width = "100%";
            attr.src = "#";

            stile.width = "100%";
            stile.height = "57px";
            stile.border = "none";
            stile.margin = "0px";
            stile.padding = "0px";
            stile.overflow = "auto";
            stile.zIndex = "2147483647";
            stile.display = "block";
            stile.visibility = "visible";
            var options = { "style": stile, attributes : attr};

            createElement("IFRAME", options, elemMount);
            
            var attrFrm = {};
            attrFrm.method = "post";
            attrFrm.action = currentBaseDomain +"/ecomm/XPayBuild/mountFastcheckout";
            attrFrm.target = attr.id;
            var form = createElement("FORM", { attributes : attrFrm }, elemMount);
            dispatchParam(form);
            addInputParam(form, "apiKey", APIKey);
            form.submit();
            elemMount.removeChild(form);
        },

        setInformazioniSicurezza : function(infoSicurezza){
            setSecurityInfo(infoSicurezza);
        },

        updateConfig : function(xpayElements, newConfig){
            var serviceType = newConfig[CONFIG_PRM.TIPOSERVIZIO];
            var requestType = newConfig[CONFIG_PRM.TIPORICHIESTA];
            
            if(isEmpty(serviceType))
                delete xpayElements.elemConfigJSON.serviceType;
            
            if(isEmpty(requestType)){
                xpayElements.elemConfigJSON.requestType = "PA";
                return;
            }
            
            if(requestType != 'PP' && requestType != 'PA'){
                logNexi("WARNING: "+ CONFIG_PRM.TIPORICHIESTA +" aggionramento non valido", false);
                return;
            }
            
            xpayElements.elemConfigJSON.serviceType = serviceType;
            xpayElements.elemConfigJSON.requestType = requestType;
        },

        createNonce : function(formId, xpayElements, infoSicurezza, isSoftDecline, cobrand) {
            if(currentEnvironment != null) {
                if(inSending) return;
                inSending = true;
                setSecurityInfo(infoSicurezza);
                
                var _formId = "#" + formId;
                //var pp = config[CONFIG_PRM.PAYMENTPARAMS];
                var pp = xpayElements["elemConfigJSON"].paymentParams;
                var mp = {};
                setAPIKey(xpayElements.APIKey);
                mp.codiceTransazione = pp["transactionId"];
                mp.importo = pp["amount"];
                mp.divisa = pp["currency"];
                mp.mac = pp["mac"];
                mp.timeStamp = pp["timeStamp"];
                if(isSoftDecline === true)
                    mp.softDecline = "S";

                var inputs = serializeForm(mp);
                inputs.parametriAggiuntivi.serviceType = xpayElements.elemConfigJSON.serviceType;
                inputs.parametriAggiuntivi.requestType = xpayElements.elemConfigJSON.requestType;
                if(cobrand === "UPI"){
                    inputs.parametriAggiuntivi.forceUPI="Y";
                }

                var iframeEl = xpayElements.constructor.name === "XpaySplitCard" ? xpayElements.getSnippet(2) : xpayElements.cardFrame;

                logNexi("<"+ APIKey +"|"+ codTrans +"> INFO: Chiamo creazione nonce");
                iframeEl.contentWindow.postMessage(JSON.stringify({ type : "creaNonce", payload : inputs}), '*');
            } else {
                logNexi("<"+ APIKey +"|"+ codTrans +"> ERRORE: Enviroment non specificato, utilizzare prima setConfig()");
                throw ("ERRORE: Enviroment non specificato, utilizzare prima setConfig()");
            }

            return false;
        },

        create : function(type, custom, choosenBrands) {
            if(APIKey == undefined || APIKey == ""){
                logNexi("<"+ jsToken +"> ERRORE: xpay.create() APIKey non impostato, utilizzare setAPIKey()");
                throw ("ERRORE: APIKey non impostato, utilizzare setAPIKey()");
            }

            if(typeof type === "function")
                return type(custom, choosenBrands);

            throw ("Operation types "+ type +" not allowed");
        },

        openLightbox : function(paymentParam) {
            openLightbox(paymentParam, false);
        },
        
        openLightbox : function(paymentParam, isPagoPa) {
            if(paymentParam == undefined || paymentParam == null || (Object.keys(paymentParam).length === 0 && paymentParam.constructor !== Object)){
                if(config == undefined || config == null || (Object.keys(config).length === 0 && config.constructor !== Object)){
                    throw ("ERRORE: Parametri pagamento non specificati");
                }
            } else {
                if(!(config == undefined || config == null || (Object.keys(config).length === 0 && config.constructor !== Object))){
                    this.initLightbox(paymentParam);
                }
            }
            
            if(currentOpenIFrame != undefined){
                logNexi("<"+ APIKey +"> Esiste un iframe gia' aperto");
                return;
            }

            var ifrm = document.createElement("iframe");
            var ifrmname = "__xpay_l_frame"+ config[CONFIG_PRM.PAYMENTPARAMS]["transactionId"];

            ifrm.setAttribute("src", "#");
            ifrm.setAttribute("name", ifrmname);
            ifrm.setAttribute("id", "__xpay_l_frame_"+ config[CONFIG_PRM.PAYMENTPARAMS]["transactionId"]);
            ifrm.setAttribute("frameborder", "0");
            ifrm.setAttribute("allowtransparency", "true");

            ifrm.style.width = "100%";
            ifrm.style.height = "100%";
            ifrm.style.zIndex = "2147483647";
            ifrm.style.display = "block";
            ifrm.style.border = "none";
            ifrm.style.visibility = "visible";
            ifrm.style.margin = "0px";
            ifrm.style.padding = "0px";
            ifrm.style.position = "fixed";
            ifrm.style.left = "0";
            ifrm.style.top = "0";
            ifrm.style.overflow = "auto";
            ifrm.style.backgroundColor = 'rgba(' + [0,0,0,0.7].join(',') + ')';
            ifrm.style.backgroundImage = BASE_DOMAIN[currentEnvironment]+'/ecomm/payment/img/loader.png';

            currentOpenIFrame = ifrm.id;

            document.body.appendChild(ifrm);

            var form = document.createElement("form");
            form.setAttribute('method', "post");
            if(isPagoPa)
                form.setAttribute('action', currentBaseDomain+"/ecomm/pagopa/DispatcherServlet");
            else
            form.setAttribute('action', currentBaseDomain+"/ecomm/ecomm/DispatcherServlet");
            form.setAttribute('target', ifrmname);
            form.acceptCharset = "iso-8859-1";
            
            dispatchParam(form);
            document.body.appendChild(form);
            form.submit();
            
            form.parentNode.removeChild(form);
        },
        
        closeLightbox: function() {
            p_closeLightbox();
        }
    };
})();


var XpayElements = function(apiKey, env, config, token){
    if(this.constructor === XpayElements){
        throw ("Can't instantiate XpayElements!"); 
    }

    this.APIKey = apiKey;
    this.currentEnvironment = env;
    this.token = token;
    this.elemConfig = "";
    this.elemConfigJSON = {};
    this.infoSicurezza = {};

    this.CONFIG_PRM = {
            BASECONFIG : "baseConfig",
            PAYMENTPARAMS : "paymentParams",
            LANGUAGE : "language",
            AMBIENTE : "enviroment",
            TIPOSERVIZIO : "serviceType",
            TIPORICHIESTA : "requestType",
            DISPLAYEDBTN : "displayedButtons",
            BRANDCARD : "displayedBrand",
            INFOSICUREZZA: "informazioniSicurezza"
        };

    if(config == undefined || config == null)
        return;

    try{
        config.tokenBuild = token;
        this.elemConfigJSON = {};
        for (var key in config) {
            if (key !== this.CONFIG_PRM.INFOSICUREZZA && config.hasOwnProperty(key)) {
                this.elemConfigJSON[key] = config[key];
            }
            
            if (key === this.CONFIG_PRM.INFOSICUREZZA && config.hasOwnProperty(key)) {
                this.infoSicurezza = config[key];
            }
        }
        this.elemConfig = JSON.stringify(this.elemConfigJSON);
    } catch (e) {
        throw ("ERRORE: style = "+ config +" non valido ");
    }
}

XpayElements.prototype.mount = function(mountPoint, mountOverlay){
    var elemMount = document.getElementById(mountPoint);
    if(elemMount == null)
        throw ("ERRORE: MountPoint \""+ mountPoint +"\" non presente nella pagina");
    
    if(elemMount.tagName != 'DIV')
        throw ("ERRORE: MountPoint \""+ mountPoint +"\" non e' un div");
    
    if(!mountOverlay)
        return;

    var div = document.getElementById("__xpay_overlay");
    if(div == null){
     div = document.createElement("div");
    div.id = '__xpay_overlay';
    div.style.display = "none";
    div.style.position = "fixed";
    div.style.top = "0";
    div.style.right = "0";
    div.style.bottom = "0";
    div.style.left = "0";
    div.style.zIndex = "2147483647";
    div.style.textAlign = "center";
    div.style.background = "rgba(0,0,0,0.5)";
    document.body.appendChild(div);
    }
    if(document.getElementById("__xpay_overlay_content") == null){
    var divContent = document.createElement("div");
    divContent.id = '__xpay_overlay_content';
    divContent.style.position = "relative";
    divContent.style.display = "inline-block";
    divContent.style.overflowX = "auto";
    divContent.style.overflowY = "auto";
    divContent.style.height = "500px";
    divContent.style.padding = "0";
    divContent.style.margin = "0";
    divContent.style.maxHeight = "99%";
    divContent.style.background = "#fff";
    divContent.style["-webkit-overflow-scrolling"] = "touch";
    divContent.style.backgroundImage = "url('https://ecommerce.nexi.it/ecomm/build/img/loader.gif')";
    divContent.style.backgroundRepeat = "no-repeat";
    divContent.style.backgroundPosition = "center";
    div.appendChild(divContent);
}
}

var XpayCard = function(apiKey, env, config, style, token){
    this.cardFrame = undefined;
    this.cardLanguage = "ITA";
    this.cardStyle = "";
    
    XpayElements.apply(this, new Array(apiKey, env, config, token));

    if(config[this.CONFIG_PRM.LANGUAGE] != undefined)
        this.cardLanguage = config[this.CONFIG_PRM.LANGUAGE];
    
    var paymentParams = config[this.CONFIG_PRM.PAYMENTPARAMS];
    if(paymentParams.currency == undefined)
        throw ("ERRORE: currency non presente in "+ this.CONFIG_PRM.PAYMENTPARAMS);
    
    if(paymentParams.transactionId == undefined)
        throw ("ERRORE: transactionId non presente in "+ this.CONFIG_PRM.PAYMENTPARAMS);
    
    if(paymentParams.mac == undefined)
        throw ("ERRORE: mac non presente in "+ this.CONFIG_PRM.PAYMENTPARAMS);
    
    if(paymentParams.timeStamp == undefined)
        throw ("ERRORE: timeStamp non presente in "+ this.CONFIG_PRM.PAYMENTPARAMS);
    
    try{
        this.cardStyle = JSON.stringify(style);
    } catch (e) {
        throw ("ERRORE: style = "+ style +" non valido ");
    }
};
XpayCard.prototype = Object.create(XpayElements.prototype);
XpayCard.prototype.constructor = XpayCard;

XpayCard.prototype.mount = function(mountPoint) {
    console.log("Create Xpay card");
    
    XpayElements.prototype.mount.call(this, mountPoint, true);

    var ifrm = document.createElement("iframe");

    ifrm.setAttribute("src", this.currentEnvironment+"/ecomm/XPayBuild/mountCard?apiKey="+ this.APIKey + "&config="+ encodeURIComponent(this.elemConfig) +"&stile="+ encodeURIComponent(this.cardStyle));
    ifrm.setAttribute("scrolling", "no");
    ifrm.setAttribute("name", "__xpay_card_frame");
    ifrm.setAttribute("id", "__xpay_card_frame");
    ifrm.setAttribute("frameborder", "0");
    ifrm.setAttribute("allowtransparency", "true");
    ifrm.setAttribute("scrolling", "no");

    ifrm.style.width = "100px";
    ifrm.style.height = "18px";
    ifrm.style.border = "none";
    ifrm.style.border = "none";
    ifrm.style.margin = "0px";
    ifrm.style.padding = "0px";
    ifrm.style.minWidth = "100%";
    ifrm.style.overflow = "hidden";
    
    document.getElementById(mountPoint).appendChild(ifrm);
    
    this.cardFrame = ifrm;
};

var XpaySplitCard = function(apiKey, env, config, style, token){
    this.list = ["PAN","EXPIRY","CVV"];
    var snippetFrames = [undefined, undefined, undefined];

    this.set = function(iframe, pos) {
        if(snippetFrames[pos] !== undefined)
            throw ("ERRORE: Frammento gia' impostato");
        snippetFrames[pos] = iframe;
    }
    
    this.getSnippet = function(i) {
        return snippetFrames[i];
    }
    
    XpayCard.apply(this, new Array(apiKey, env, config, style, token));
};
XpaySplitCard.prototype = Object.create(XpayCard.prototype);
XpaySplitCard.prototype.constructor = XpaySplitCard;

XpaySplitCard.prototype.mount = function(mountPanPoint, mountExpiryPoint, mountCvvPoint) {
    console.log("Create Xpay Card Snippet");

    for(var arg = 0; arg < arguments.length; ++ arg)
    {
        var arr = arguments[arg];
        if(arr === undefined || arr === null || arr === "")
            throw ("ERRORE: Specificare un mountPoint distinto per i tre elementi della carta");

        XpayElements.prototype.mount.call(this, arr, true); 
    }
    
    for(var arg = 0; arg < arguments.length; ++ arg)
    {
        var nameFrm = this.list[arg];
        var ifrm = document.createElement("iframe");
        ifrm.setAttribute("src", this.currentEnvironment+"/ecomm/XPayBuild/mountSnippet"+ nameFrm +"?apiKey="+ this.APIKey + "&config="+ encodeURIComponent(this.elemConfig) +"&stile="+ encodeURIComponent(this.cardStyle));
        ifrm.setAttribute("scrolling", "no");
        ifrm.setAttribute("name", "__xpay_s_"+ nameFrm +"_frame");
        ifrm.setAttribute("id", "__xpay_s_"+ nameFrm +"_frame");
        ifrm.setAttribute("frameborder", "0");
        ifrm.setAttribute("allowtransparency", "true");
        ifrm.setAttribute("scrolling", "no");

        ifrm.style.width = "100px";
        ifrm.style.height = "18px";
        ifrm.style.border = "none";
        ifrm.style.border = "none";
        ifrm.style.margin = "0px";
        ifrm.style.padding = "0px";
        ifrm.style.minWidth = "100%";
        ifrm.style.overflow = "hidden";

        document.getElementById(arguments[arg]).appendChild(ifrm);
        this.set(ifrm, arg);
    }
};

var XpayPaymentButton = function(apiKey, env, config, token){
    config.applePayAvailable = window.ApplePaySession && ApplePaySession.canMakePayments ? "S" : "N";

    XpayElements.apply(this, new Array(apiKey, env, config, token));

    var bottoni = config[this.CONFIG_PRM.DISPLAYEDBTN];
    if(bottoni == undefined || bottoni == [] || bottoni.indexOf("PAYPAL") >= 0){
        var importedPaypal = document.createElement('script');
        importedPaypal.src = 'https://www.paypalobjects.com/api/checkout.js';
        importedPaypal.type = 'text/javascript';
        importedPaypal.setAttribute("data-version-4", "");
        document.head.appendChild(importedPaypal);
    }

    var paymentParams = config[this.CONFIG_PRM.PAYMENTPARAMS];
    if(paymentParams.amount == undefined)
        throw ("ERRORE: amount non presente in "+ this.CONFIG_PRM.PAYMENTPARAMS);
        
    if(paymentParams.currency == undefined)
        throw ("ERRORE: currency non presente in "+ this.CONFIG_PRM.PAYMENTPARAMS);
    
    if(paymentParams.transactionId == undefined)
        throw ("ERRORE: transactionId non presente in "+ this.CONFIG_PRM.PAYMENTPARAMS);
    
    if(paymentParams.mac == undefined)
        throw ("ERRORE: mac non presente in "+ this.CONFIG_PRM.PAYMENTPARAMS);
};
XpayPaymentButton.prototype = Object.create(XpayElements.prototype);
XpayPaymentButton.prototype.constructor = XpayPaymentButton;

XpayPaymentButton.prototype.mount = function(mountPoint) {
    console.log("Create payment button");

    XpayElements.prototype.mount.call(this, mountPoint, false);
    
    var paymentParams = this.elemConfigJSON[this.CONFIG_PRM.PAYMENTPARAMS];
    if(paymentParams.url == undefined)
        throw ("ERRORE: url non presente in "+ this.CONFIG_PRM.PAYMENTPARAMS);
    
    if(paymentParams.urlBack == undefined)
        throw ("ERRORE: urlBack non presente in "+ this.CONFIG_PRM.PAYMENTPARAMS);

    function getElementsByIdStartsWith(selectorTag, prefix) {
        var items = 0;
        if (document.getElementsByTagName(selectorTag)){
            var myPosts = document.getElementsByTagName(selectorTag);
            for (var i = 0; i < myPosts.length; i++) {
                if (myPosts[i].id.lastIndexOf(prefix, 0) === 0) {
                    items++;
                }
            }
        }
        return items;
    }

    var ifrm = document.createElement("iframe");

    var currBtn = getElementsByIdStartsWith("iframe", "__xpay_btn_frame");
    ifrm.setAttribute("src", this.currentEnvironment+"/ecomm/XPayBuild/mountButtons?apiKey="+ this.APIKey + "&id_frm=__xpay_btn_frame" + currBtn  + "&config="+ encodeURIComponent(this.elemConfig)+"&infoSicurezza="+ encodeURIComponent(JSON.stringify(this.infoSicurezza)));
    ifrm.setAttribute("scrolling", "no");
    ifrm.setAttribute("name", "__xpay_btn_frame");
    ifrm.setAttribute("id", "__xpay_btn_frame"+currBtn);
    ifrm.setAttribute("frameborder", "0");
    ifrm.setAttribute("allowpaymentrequest","true"); 

    ifrm.style.width = "100%";
    ifrm.style.height = "70px";
    ifrm.style.minHeight = "70px";
    
    document.getElementById(mountPoint).appendChild(ifrm);
    
};

/* Copyright Nexi Payments Thu Mar 20 02:54:53 CET 2025*/
