diff --git a/README.md b/README.md index 38b919d..5aea9df 100644 --- a/README.md +++ b/README.md @@ -4,17 +4,30 @@ You can sign up for a Realex account at https://developer.realexpayments.com ## Hosted Payment Page (HPP) JS Library ### Usage -The Javascript required to initialise the library is below. This code must only be executed when the DOM is fully loaded. +The Javascript required to initialise the library is below. This code must only be executed when the DOM is fully loaded. (default method: lightbox) ```javascript -RealexHpp.init(payButtonId, merchantUrl, jsonFromServerSdk); +RealexHpp.init(payButtonId, merchantUrl, jsonFromServerSdk[, options]); ``` -* payButtonId - The ID of the button used to launch the lightbox. -* merchantUrl - The URL to which the JSON response from Realex will be posted. +* payButtonId - The ID of the button used to launch the lightbox. Set to "autoload" if you want to load without having to press a button +* merchantUrl - could be one of 2 types: + - string - The URL to which the JSON response from Realex will be posted. + - function - the callback function * jsonFromServerSdk - The JSON output from the Realex HPP Server SDK. +* options/events + - onResize (iframe embed) Send resize iframe events so the parent frame can be adjusted ### Consuming the resulting POST Once the payment has completed the Realex JSON response will be posted within to the supplied merchantUrl. The name of the field containing the JSON response is hppResponse. +If you prefer to handle response manually, provide your own callback function in "merchantUrl". The answer will be pre-parsed to an object ready to be used. + +## Examples + +* [embedded iFrame](examples/hpp/process-a-payment-embedded.html) +* [embedded iFrame autoload](examples/hpp/process-a-payment-embedded-autoload.html) +* [embedded iFrame autoload, callback](examples/hpp/process-a-payment-embedded-autoload-callback.html) +* [lightbox/modal](examples/hpp/process-a-payment-lightbox.html) + ## Remote JS Library ### Validation functions diff --git a/dist/rxp-js.js b/dist/rxp-js.js index f9efc4f..54f0f1e 100644 --- a/dist/rxp-js.js +++ b/dist/rxp-js.js @@ -1,8 +1,18 @@ -/*! rxp-js - v1.3.1 - 2018-08-30 +/*! rxp-js - v1.4.0 - 2021-03-29 * The official Realex Payments JS Library * https://github.com/realexpayments/rxp-js * Licensed MIT */ +Element.prototype.remove = function() { + this.parentElement.removeChild(this); +}; +NodeList.prototype.remove = HTMLCollection.prototype.remove = function() { + for(var i = this.length - 1; i >= 0; i--) { + if(this[i] && this[i].parentElement) { + this[i].parentElement.removeChild(this[i]); + } + } +}; var RealexHpp = (function () { 'use strict'; @@ -15,20 +25,141 @@ var RealexHpp = (function () { hppUrl = url; }; + var mobileXSLowerBound = 360; + var setMobileXSLowerBound = function (lowerBound) { + mobileXSLowerBound = lowerBound; + }; + var isWindowsMobileOs = /Windows Phone|IEMobile/.test(navigator.userAgent); var isAndroidOrIOs = /Android|iPad|iPhone|iPod/.test(navigator.userAgent); - var isMobileXS = ( (((window.innerWidth > 0) ? window.innerWidth : screen.width) <= 360 ? true : false) || (((window.innerHeight > 0) ? window.innerHeight : screen.Height) <= 360 ? true : false)) ; + var isMobileXS = function () { + return (((window.innerWidth > 0) ? window.innerWidth : screen.width) <= mobileXSLowerBound ? true : false) || + (((window.innerHeight > 0) ? window.innerHeight : screen.Height) <= mobileXSLowerBound ? true : false); + }; // Display IFrame on WIndows Phone OS mobile devices var isMobileIFrame = isWindowsMobileOs; // For IOs/Android and small screen devices always open in new tab/window - var isMobileNewTab = !isWindowsMobileOs && (isAndroidOrIOs || isMobileXS); + var isMobileNewTab = function () { + return !isWindowsMobileOs && (isAndroidOrIOs || isMobileXS()); + }; + var tabWindow; var redirectUrl; var internal = { + + base64:{ + encode:function(input) { + var keyStr = "ABCDEFGHIJKLMNOP" + + "QRSTUVWXYZabcdef" + + "ghijklmnopqrstuv" + + "wxyz0123456789+/" + + "="; + input = escape(input); + var output = ""; + var chr1, chr2, chr3 = ""; + var enc1, enc2, enc3, enc4 = ""; + var i = 0; + + do { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + + keyStr.charAt(enc1) + + keyStr.charAt(enc2) + + keyStr.charAt(enc3) + + keyStr.charAt(enc4); + chr1 = chr2 = chr3 = ""; + enc1 = enc2 = enc3 = enc4 = ""; + } while (i < input.length); + + return output; + }, + decode:function(input) { + if(typeof input === 'undefined') { + return input; + } + var keyStr = "ABCDEFGHIJKLMNOP" + + "QRSTUVWXYZabcdef" + + "ghijklmnopqrstuv" + + "wxyz0123456789+/" + + "="; + var output = ""; + var chr1, chr2, chr3 = ""; + var enc1, enc2, enc3, enc4 = ""; + var i = 0; + + // remove all characters that are not A-Z, a-z, 0-9, +, /, or = + var base64test = /[^A-Za-z0-9\+\/\=]/g; + if (base64test.exec(input)) { + throw new Error("There were invalid base64 characters in the input text.\n" + + "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" + + "Expect errors in decoding."); + } + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + do { + enc1 = keyStr.indexOf(input.charAt(i++)); + enc2 = keyStr.indexOf(input.charAt(i++)); + enc3 = keyStr.indexOf(input.charAt(i++)); + enc4 = keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 !== 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 !== 64) { + output = output + String.fromCharCode(chr3); + } + + chr1 = chr2 = chr3 = ""; + enc1 = enc2 = enc3 = enc4 = ""; + + } while (i < input.length); + + return unescape(output); + } + }, + decodeAnswer:function(answer){ //internal.decodeAnswer + + var _r; + + try { + _r=JSON.parse(answer); + } catch (e) { + _r = { error: true, message: answer }; + } + + try { + for(var r in _r){ + if(_r[r]) { + _r[r]=internal.base64.decode(_r[r]); + } + } + } catch (e) { /** */ } + return _r; + }, createFormHiddenInput: function (name, value) { var el = document.createElement("input"); el.setAttribute("type", "hidden"); @@ -127,20 +258,20 @@ var RealexHpp = (function () { var form = document.createElement("form"); form.setAttribute("method", "POST"); form.setAttribute("action", hppUrl); - + var versionSet = false; - + for (var key in token) { if (key === "HPP_VERSION"){ versionSet = true; } form.appendChild(internal.createFormHiddenInput(key, token[key])); } - + if (versionSet === false){ form.appendChild(internal.createFormHiddenInput("HPP_VERSION", "2")); } - + if (ignorePostMessage) { form.appendChild(internal.createFormHiddenInput("MERCHANT_RESPONSE_URL", redirectUrl)); } else { @@ -295,12 +426,12 @@ var RealexHpp = (function () { if (!internal.isMessageFromHpp(event.origin, hppUrl)) { return; } - // check for iframe resize values - if (event.data && JSON.parse(event.data).iframe) { - if (!isMobileNewTab) { - var iframeWidth = JSON.parse(event.data).iframe.width; - var iframeHeight = JSON.parse(event.data).iframe.height; + var evtdata; + if (event.data && (evtdata=internal.decodeAnswer(event.data)).iframe) { + if (!isMobileNewTab()) { + var iframeWidth = evtdata.iframe.width; + var iframeHeight = evtdata.iframe.height; var iFrame; var resized = false; @@ -310,6 +441,9 @@ var RealexHpp = (function () { } else { iFrame = document.getElementById("rxp-frame-" + randomId); } + if(lightboxInstance.events && lightboxInstance.events.onResize) { + lightboxInstance.events.onResize(evtdata.iframe); + } if (iframeWidth === "390px" && iframeHeight === "440px") { iFrame.setAttribute("width", iframeWidth); @@ -344,25 +478,34 @@ var RealexHpp = (function () { } } } else { - if (isMobileNewTab && tabWindow) { - //Close the new window - tabWindow.close(); - } else { - //Close the lightbox - lightboxInstance.close(); - } + var _close=function(){ + if (isMobileNewTab() && tabWindow) { + //Close the new window + tabWindow.close(); + } else { + //Close the lightbox + lightboxInstance.close(); + } + var overlay=document.getElementById("rxp-overlay-" + randomId); + if(overlay) { + overlay.remove(); + } + }; var response = event.data; - + //allow the script to intercept the answer, instead of redirecting to another page. (which is really a 90s thing) + if(typeof merchantUrl==='function'){ + var answer=internal.decodeAnswer(response); + merchantUrl(answer,_close); + return; + } + _close(); //Create a form and submit the hpp response to the merchant's response url var form = document.createElement("form"); form.setAttribute("method", "POST"); form.setAttribute("action", merchantUrl); - form.appendChild(internal.createFormHiddenInput("hppResponse", response)); - document.body.appendChild(form); - form.submit(); } }; @@ -391,7 +534,7 @@ var RealexHpp = (function () { return { lightbox: function () { - if (isMobileNewTab) { + if (isMobileNewTab()) { tabWindow = internal.openWindow(token); } else { overlayElement = internal.createOverlay(); @@ -427,8 +570,12 @@ var RealexHpp = (function () { //Get the lightbox instance (it's a singleton) and set the sdk json var lightboxInstance = RxpLightbox.getInstance(serverSdkJson); + //if you want the form to load on function call, set to autoload + if(idOfLightboxButton==='autoload'){ + lightboxInstance.lightbox(); + } // Sets the event listener on the PAY button. The click will invoke the lightbox method - if (document.getElementById(idOfLightboxButton).addEventListener) { + else if (document.getElementById(idOfLightboxButton).addEventListener) { document.getElementById(idOfLightboxButton).addEventListener("click", lightboxInstance.lightbox, true); } else { document.getElementById(idOfLightboxButton).attachEvent('onclick', lightboxInstance.lightbox); @@ -492,17 +639,20 @@ var RealexHpp = (function () { //Set the hpp token instance.setToken(hppToken); - return instance; }, - init: function (idOfEmbeddedButton, idOfTargetIframe, merchantUrl, serverSdkJson) { + init: function (idOfEmbeddedButton, idOfTargetIframe, merchantUrl, serverSdkJson,events) { //Get the embedded instance (it's a singleton) and set the sdk json var embeddedInstance = RxpEmbedded.getInstance(serverSdkJson); + embeddedInstance.events=events; embeddedInstance.setIframe(idOfTargetIframe); - + //if you want the form to load on function call, set to autoload + if(idOfEmbeddedButton==='autoload'){ + embeddedInstance.embedded(); + } // Sets the event listener on the PAY button. The click will invoke the embedded method - if (document.getElementById(idOfEmbeddedButton).addEventListener) { + else if (document.getElementById(idOfEmbeddedButton).addEventListener) { document.getElementById(idOfEmbeddedButton).addEventListener("click", embeddedInstance.embedded, true); } else { document.getElementById(idOfEmbeddedButton).attachEvent('onclick', embeddedInstance.embedded); @@ -594,11 +744,11 @@ var RealexHpp = (function () { init: RxpRedirect.init }, setHppUrl: setHppUrl, + setMobileXSLowerBound: setMobileXSLowerBound, _internal: internal }; }()); - var RealexRemote = (function() { 'use strict'; diff --git a/dist/rxp-js.min.js b/dist/rxp-js.min.js index b623ad5..c048d82 100644 --- a/dist/rxp-js.min.js +++ b/dist/rxp-js.min.js @@ -1,7 +1,7 @@ -/*! rxp-js - v1.3.1 - 2018-08-30 +/*! rxp-js - v1.4.0 - 2021-03-29 * The official Realex Payments JS Library * https://github.com/realexpayments/rxp-js * Licensed MIT */ -var RealexHpp=function(){"use strict";var g,d,i,n,A,l="https://pay.realexpayments.com/pay",I=I||Math.random().toString(16).substr(2,8),e=/Windows Phone|IEMobile/.test(navigator.userAgent),t=/Android|iPad|iPhone|iPod/.test(navigator.userAgent),o=(0>2,o=(3&A)<<4|(n=e.charCodeAt(c++))>>4,r=(15&n)<<2|(d=e.charCodeAt(c++))>>6,s=63&d,isNaN(n)?r=s=64:isNaN(d)&&(s=64),a=a+t.charAt(i)+t.charAt(o)+t.charAt(r)+t.charAt(s),A=n=d="",i=o=r=s="",cAll set!'); + //success + success(answer); + } + else{ + //error + $('.paymentResult').html('
'+answer.MESSAGE+'
'); + //would you retry? This part should be handled at the rxp side, stay in the modal/iframe... TODO + } + }, + jsonFromServerSdk, + { + onResize:function(data){ + $('#targetIframe').css(data) + } + } + ); + $('body').addClass('loaded'); + }); + }); + + + +
+ + + diff --git a/examples/hpp/process-a-payment-embedded-autoload.html b/examples/hpp/process-a-payment-embedded-autoload.html new file mode 100644 index 0000000..d695c7d --- /dev/null +++ b/examples/hpp/process-a-payment-embedded-autoload.html @@ -0,0 +1,32 @@ + + + + HPP embed Demo + + + + + + + + + diff --git a/examples/hpp/process-a-payment-embedded.html b/examples/hpp/process-a-payment-embedded.html index 09d2f1c..a82e96a 100644 --- a/examples/hpp/process-a-payment-embedded.html +++ b/examples/hpp/process-a-payment-embedded.html @@ -1,7 +1,7 @@ - HPP Lightbox Demo + HPP embed Demo @@ -13,8 +13,13 @@ RealexHpp.embedded.init( "payButtonId", "targetIframe", - "https://dev.rlxcarts.com/mobileSDKsV2/response.php", - jsonFromServerSdk + "https://dev.rlxcarts.com/mobileSDKsV2/response.php", // merchant url + jsonFromServerSdk, // form data + { // options + onResize:function(data){ + $('#targetIframe').css(data) + } + } ); $('body').addClass('loaded'); }); diff --git a/examples/hpp/process-a-payment-lightbox-callback.html b/examples/hpp/process-a-payment-lightbox-callback.html new file mode 100644 index 0000000..a40f5a4 --- /dev/null +++ b/examples/hpp/process-a-payment-lightbox-callback.html @@ -0,0 +1,40 @@ + + + + HPP Lightbox Demo + + + + + + + + + diff --git a/examples/hpp/process-a-payment-lightbox.html b/examples/hpp/process-a-payment-lightbox.html index dad1621..90fe77b 100644 --- a/examples/hpp/process-a-payment-lightbox.html +++ b/examples/hpp/process-a-payment-lightbox.html @@ -10,7 +10,11 @@ // get the HPP JSON from the server-side SDK $(document).ready(function () { $.getJSON("/examples/hpp/proxy-request.php?slug=process-a-payment", function (jsonFromServerSdk) { - RealexHpp.lightbox.init("payButtonId", "https://dev.rlxcarts.com/mobileSDKsV2/response.php", jsonFromServerSdk); + RealexHpp.lightbox.init( + "payButtonId", + "https://dev.rlxcarts.com/mobileSDKsV2/response.php", // merchant url + jsonFromServerSdk //form data + ); $('body').addClass('loaded'); }); }); diff --git a/lib/.jshintrc b/lib/.jshintrc index 9ed4773..7f14099 100644 --- a/lib/.jshintrc +++ b/lib/.jshintrc @@ -9,5 +9,5 @@ "undef": true, "boss": true, "eqnull": true, - "predef": ["exports"] + "predef": ["exports", "alert", "escape", "unescape"] } diff --git a/lib/rxp-hpp.js b/lib/rxp-hpp.js index 13f8d4d..c569764 100644 --- a/lib/rxp-hpp.js +++ b/lib/rxp-hpp.js @@ -1,4 +1,14 @@ /*jslint browser:true */ +Element.prototype.remove = function() { + this.parentElement.removeChild(this); +}; +NodeList.prototype.remove = HTMLCollection.prototype.remove = function() { + for(var i = this.length - 1; i >= 0; i--) { + if(this[i] && this[i].parentElement) { + this[i].parentElement.removeChild(this[i]); + } + } +}; var RealexHpp = (function () { 'use strict'; @@ -11,20 +21,141 @@ var RealexHpp = (function () { hppUrl = url; }; + var mobileXSLowerBound = 360; + var setMobileXSLowerBound = function (lowerBound) { + mobileXSLowerBound = lowerBound; + }; + var isWindowsMobileOs = /Windows Phone|IEMobile/.test(navigator.userAgent); var isAndroidOrIOs = /Android|iPad|iPhone|iPod/.test(navigator.userAgent); - var isMobileXS = ( (((window.innerWidth > 0) ? window.innerWidth : screen.width) <= 360 ? true : false) || (((window.innerHeight > 0) ? window.innerHeight : screen.Height) <= 360 ? true : false)) ; + var isMobileXS = function () { + return (((window.innerWidth > 0) ? window.innerWidth : screen.width) <= mobileXSLowerBound ? true : false) || + (((window.innerHeight > 0) ? window.innerHeight : screen.Height) <= mobileXSLowerBound ? true : false); + }; // Display IFrame on WIndows Phone OS mobile devices var isMobileIFrame = isWindowsMobileOs; // For IOs/Android and small screen devices always open in new tab/window - var isMobileNewTab = !isWindowsMobileOs && (isAndroidOrIOs || isMobileXS); + var isMobileNewTab = function () { + return !isWindowsMobileOs && (isAndroidOrIOs || isMobileXS()); + }; + var tabWindow; var redirectUrl; var internal = { + + base64:{ + encode:function(input) { + var keyStr = "ABCDEFGHIJKLMNOP" + + "QRSTUVWXYZabcdef" + + "ghijklmnopqrstuv" + + "wxyz0123456789+/" + + "="; + input = escape(input); + var output = ""; + var chr1, chr2, chr3 = ""; + var enc1, enc2, enc3, enc4 = ""; + var i = 0; + + do { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + + keyStr.charAt(enc1) + + keyStr.charAt(enc2) + + keyStr.charAt(enc3) + + keyStr.charAt(enc4); + chr1 = chr2 = chr3 = ""; + enc1 = enc2 = enc3 = enc4 = ""; + } while (i < input.length); + + return output; + }, + decode:function(input) { + if(typeof input === 'undefined') { + return input; + } + var keyStr = "ABCDEFGHIJKLMNOP" + + "QRSTUVWXYZabcdef" + + "ghijklmnopqrstuv" + + "wxyz0123456789+/" + + "="; + var output = ""; + var chr1, chr2, chr3 = ""; + var enc1, enc2, enc3, enc4 = ""; + var i = 0; + + // remove all characters that are not A-Z, a-z, 0-9, +, /, or = + var base64test = /[^A-Za-z0-9\+\/\=]/g; + if (base64test.exec(input)) { + throw new Error("There were invalid base64 characters in the input text.\n" + + "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" + + "Expect errors in decoding."); + } + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + do { + enc1 = keyStr.indexOf(input.charAt(i++)); + enc2 = keyStr.indexOf(input.charAt(i++)); + enc3 = keyStr.indexOf(input.charAt(i++)); + enc4 = keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 !== 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 !== 64) { + output = output + String.fromCharCode(chr3); + } + + chr1 = chr2 = chr3 = ""; + enc1 = enc2 = enc3 = enc4 = ""; + + } while (i < input.length); + + return unescape(output); + } + }, + decodeAnswer:function(answer){ //internal.decodeAnswer + + var _r; + + try { + _r=JSON.parse(answer); + } catch (e) { + _r = { error: true, message: answer }; + } + + try { + for(var r in _r){ + if(_r[r]) { + _r[r]=internal.base64.decode(_r[r]); + } + } + } catch (e) { /** */ } + return _r; + }, createFormHiddenInput: function (name, value) { var el = document.createElement("input"); el.setAttribute("type", "hidden"); @@ -123,20 +254,20 @@ var RealexHpp = (function () { var form = document.createElement("form"); form.setAttribute("method", "POST"); form.setAttribute("action", hppUrl); - + var versionSet = false; - + for (var key in token) { if (key === "HPP_VERSION"){ versionSet = true; } form.appendChild(internal.createFormHiddenInput(key, token[key])); } - + if (versionSet === false){ form.appendChild(internal.createFormHiddenInput("HPP_VERSION", "2")); } - + if (ignorePostMessage) { form.appendChild(internal.createFormHiddenInput("MERCHANT_RESPONSE_URL", redirectUrl)); } else { @@ -291,12 +422,12 @@ var RealexHpp = (function () { if (!internal.isMessageFromHpp(event.origin, hppUrl)) { return; } - // check for iframe resize values - if (event.data && JSON.parse(event.data).iframe) { - if (!isMobileNewTab) { - var iframeWidth = JSON.parse(event.data).iframe.width; - var iframeHeight = JSON.parse(event.data).iframe.height; + var evtdata; + if (event.data && (evtdata=internal.decodeAnswer(event.data)).iframe) { + if (!isMobileNewTab()) { + var iframeWidth = evtdata.iframe.width; + var iframeHeight = evtdata.iframe.height; var iFrame; var resized = false; @@ -306,6 +437,9 @@ var RealexHpp = (function () { } else { iFrame = document.getElementById("rxp-frame-" + randomId); } + if(lightboxInstance.events && lightboxInstance.events.onResize) { + lightboxInstance.events.onResize(evtdata.iframe); + } if (iframeWidth === "390px" && iframeHeight === "440px") { iFrame.setAttribute("width", iframeWidth); @@ -340,25 +474,34 @@ var RealexHpp = (function () { } } } else { - if (isMobileNewTab && tabWindow) { - //Close the new window - tabWindow.close(); - } else { - //Close the lightbox - lightboxInstance.close(); - } + var _close=function(){ + if (isMobileNewTab() && tabWindow) { + //Close the new window + tabWindow.close(); + } else { + //Close the lightbox + lightboxInstance.close(); + } + var overlay=document.getElementById("rxp-overlay-" + randomId); + if(overlay) { + overlay.remove(); + } + }; var response = event.data; - + //allow the script to intercept the answer, instead of redirecting to another page. (which is really a 90s thing) + if(typeof merchantUrl==='function'){ + var answer=internal.decodeAnswer(response); + merchantUrl(answer,_close); + return; + } + _close(); //Create a form and submit the hpp response to the merchant's response url var form = document.createElement("form"); form.setAttribute("method", "POST"); form.setAttribute("action", merchantUrl); - form.appendChild(internal.createFormHiddenInput("hppResponse", response)); - document.body.appendChild(form); - form.submit(); } }; @@ -387,7 +530,7 @@ var RealexHpp = (function () { return { lightbox: function () { - if (isMobileNewTab) { + if (isMobileNewTab()) { tabWindow = internal.openWindow(token); } else { overlayElement = internal.createOverlay(); @@ -423,8 +566,12 @@ var RealexHpp = (function () { //Get the lightbox instance (it's a singleton) and set the sdk json var lightboxInstance = RxpLightbox.getInstance(serverSdkJson); + //if you want the form to load on function call, set to autoload + if(idOfLightboxButton==='autoload'){ + lightboxInstance.lightbox(); + } // Sets the event listener on the PAY button. The click will invoke the lightbox method - if (document.getElementById(idOfLightboxButton).addEventListener) { + else if (document.getElementById(idOfLightboxButton).addEventListener) { document.getElementById(idOfLightboxButton).addEventListener("click", lightboxInstance.lightbox, true); } else { document.getElementById(idOfLightboxButton).attachEvent('onclick', lightboxInstance.lightbox); @@ -488,17 +635,20 @@ var RealexHpp = (function () { //Set the hpp token instance.setToken(hppToken); - return instance; }, - init: function (idOfEmbeddedButton, idOfTargetIframe, merchantUrl, serverSdkJson) { + init: function (idOfEmbeddedButton, idOfTargetIframe, merchantUrl, serverSdkJson,events) { //Get the embedded instance (it's a singleton) and set the sdk json var embeddedInstance = RxpEmbedded.getInstance(serverSdkJson); + embeddedInstance.events=events; embeddedInstance.setIframe(idOfTargetIframe); - + //if you want the form to load on function call, set to autoload + if(idOfEmbeddedButton==='autoload'){ + embeddedInstance.embedded(); + } // Sets the event listener on the PAY button. The click will invoke the embedded method - if (document.getElementById(idOfEmbeddedButton).addEventListener) { + else if (document.getElementById(idOfEmbeddedButton).addEventListener) { document.getElementById(idOfEmbeddedButton).addEventListener("click", embeddedInstance.embedded, true); } else { document.getElementById(idOfEmbeddedButton).attachEvent('onclick', embeddedInstance.embedded); @@ -590,7 +740,8 @@ var RealexHpp = (function () { init: RxpRedirect.init }, setHppUrl: setHppUrl, + setMobileXSLowerBound: setMobileXSLowerBound, _internal: internal }; -}()); +}()); \ No newline at end of file diff --git a/package.json b/package.json index 632392a..010f20b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "rxp-js", "description": "The official Realex Payments JS Library", - "version": "1.3.1", + "version": "1.4.0", "homepage": "https://github.com/realexpayments/rxp-js", "author": { "name": "Realex Developer",