From Scanty Pheasant, 3 Weeks ago, written in Text.
Embed
  1. !function () {
  2.     function Inline(defaults, form) {
  3.         this.iframeLoaded = false, this.iframeOpen = false, this.defaults = defaults, this.isEmbed = null != defaults.container, this.loadButtonCSS(), this.setupIframe(), noBrowserIframeSupport() && (this.fallback = true), form && (this.form = form, this.createButton()), this.listenForCloseEvent()
  4.     }
  5.  
  6.     function parseObject(string) {
  7.         try {
  8.             return JSON.parse(string)
  9.         } catch (err) {
  10.             return string
  11.         }
  12.     }
  13.  
  14.     function parseFunction(string) {
  15.         try {
  16.             return eval(string)
  17.         } catch (err) {
  18.             return string
  19.         }
  20.     }
  21.  
  22.     function randomId() {
  23.         for (var text = "", possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", i = 0; i < 5; i++) text += possible.charAt(Math.floor(Math.random() * possible.length));
  24.         return text
  25.     }
  26.  
  27.     function isValid(defaults) {
  28.         if (validateInputTypes(defaults), void 0 == defaults.key) throw new Error("Please provide your public key via the key attribute");
  29.         if (void 0 == defaults.amount && void 0 == defaults.plan) throw new Error("Please provide transaction amount via the amount or plan attribute");
  30.         if (void 0 == defaults.email && void 0 == defaults.customer_code) throw new Error("Please provide customer email via the email or customerCode attribute");
  31.         if (defaults.transaction_charge && defaults.transaction_charge >= defaults.amount) throw new Error("Transaction charge must be less than the transaction amount");
  32.         if (defaults.bearer && "account" != defaults.bearer && "subaccount" != defaults.bearer) throw new Error("Bearer should be either account or subaccount");
  33.         if (defaults.channels && !defaults.channels.length) throw new Error("Channels should be an array of [card, bank] values");
  34.         var buttonNotFound = defaults.customButton && void 0 != defaults.customButton && void 0 == document.getElementById(defaults.customButton);
  35.         if (buttonNotFound) throw new Error("Please ensure a button with id " + defaults.customButton + " is defined");
  36.         var containerNotFound = defaults.container && void 0 != defaults.container && void 0 == document.getElementById(defaults.container);
  37.         if (containerNotFound) throw new Error("Please ensure an element with id " + defaults.container + " is defined");
  38.         return true
  39.     }
  40.  
  41.     function validateInputTypes(defaults) {
  42.         function validate(key, value) {
  43.             if (validation[key] && value) switch (validation[key]) {
  44.                 case"email":
  45.                     isValidEmail(value) || throwInvalid(key);
  46.                     break;
  47.                 case"integer":
  48.                     isNormalInteger(value) || throwInvalid(key);
  49.                     break;
  50.                 case"function":
  51.                     isFunction(value) || throwInvalid(key);
  52.                     break;
  53.                 case"object":
  54.                     isObject(value) || throwInvalid(key);
  55.                     break;
  56.                 case"array":
  57.                     isArray(value) || throwInvalid(key)
  58.             }
  59.         }
  60.  
  61.         function throwInvalid(key) {
  62.             throw new Error("Attribute " + key + " must be a valid " + validation[key])
  63.         }
  64.  
  65.         var validation = {
  66.             email: "email",
  67.             amount: "integer",
  68.             transaction_charge: "integer",
  69.             invoice_limit: "integer",
  70.             onClose: "function",
  71.             callback: "function",
  72.             metadata: "object",
  73.             channels: "array"
  74.         };
  75.         for (var key in defaults) {
  76.             var value = defaults[key];
  77.             validate(key, value)
  78.         }
  79.     }
  80.  
  81.     function validateChannels(params) {
  82.         if (void 0 !== params.bank || void 0 !== params.card) {
  83.             var _channels = ["card", "bank"],
  84.                 shouldIgnoreBankAndCardParams = "false" === params.card && "false" === params.bank;
  85.             return shouldIgnoreBankAndCardParams || ("false" === params.card ? _channels.splice(0, 1) : "false" === params.bank && _channels.splice(1, 1)), params.channels = _channels, omitKeys(params, ["card", "bank"])
  86.         }
  87.         return params
  88.     }
  89.  
  90.     function checkForParentForm(script) {
  91.         if ("FORM" == script.parentElement.tagName) return true;
  92.         throw new Error("Please put your Remita Inline javascript file inside of a form element")
  93.     }
  94.  
  95.     function getParentForm(script) {
  96.         return form = script.parentElement
  97.     }
  98.  
  99.     function hasDataAttribute(script) {
  100.         var result = false, list = script.attributes;
  101.         list = Array.prototype.slice.call(list);
  102.         for (key in list) {
  103.             var element = list[key].nodeName;
  104.             element && element.indexOf("data") > -1 && (result = true)
  105.         }
  106.         return result
  107.     }
  108.  
  109.     function noBrowserIframeSupport() {
  110.         var testIframe = document.createElement("iframe"), browserSupportsIframe = "onload" in testIframe;
  111.         return browserSupportsIframe || console.warn("This browser does not support iframes. Please redirect to standard"), !browserSupportsIframe
  112.     }
  113.  
  114.     function parseResponse(message, defaults) {
  115.         var action, split, iframeId, data, isThisIframe;
  116.         return "string" == typeof message && (action = message.split(" ")[0]), action && (split = message.split(" "), iframeId = split[1], data = split.slice(2).join(" "), isThisIframe = defaults.id == iframeId), {
  117.             action: action,
  118.             isThisIframe: isThisIframe,
  119.             data: data
  120.         }
  121.     }
  122.  
  123.     function omitKeys(object, keys) {
  124.         for (var _object = JSON.parse(JSON.stringify(object)), i = 0; i < keys.length; i++) delete _object[keys[i]];
  125.         for (var key in _object) _object.hasOwnProperty(key) && !_object[key] && delete _object[key];
  126.         return _object
  127.     }
  128.  
  129.     function serialize(obj) {
  130.         return Object.keys(obj).map(function (k) {
  131.             return encodeURIComponent(k) + "=" + encodeURIComponent(obj[k])
  132.         }).join("&")
  133.     }
  134.  
  135.     function isObject(obj) {
  136.         return obj === Object(obj) && "[object Array]" !== Object.prototype.toString.call(obj)
  137.     }
  138.  
  139.     function isArray(value) {
  140.         return value.constructor === Array
  141.     }
  142.  
  143.     function isNormalInteger(number) {
  144.         var int = parseInt(number);
  145.         return int == number && number >= 0
  146.     }
  147.  
  148.     function isFunction(functionToCheck) {
  149.         if (!functionToCheck) return false;
  150.         var getType = {};
  151.         return functionToCheck && "[object Function]" === getType.toString.call(functionToCheck)
  152.     }
  153.  
  154.     function isValidEmail(email) {
  155.         var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  156.         return re.test(email)
  157.     }
  158.  
  159.     function getHref() {
  160.         var href = window.location.href;
  161.         return href && href.length > 500 && (href = href.split("?")[0]), href
  162.     }
  163.  
  164.     function findHighestZIndex(elem) {
  165.         for (var elems = document.getElementsByTagName(elem), highest = 0, i = 0; i < elems.length; i++) {
  166.             var zindex = document.defaultView.getComputedStyle(elems[i], null).getPropertyValue("z-index");
  167.             zindex > highest && "auto" != zindex && (highest = zindex)
  168.         }
  169.         return parseInt(highest)
  170.     }
  171.  
  172.     function cssLoad(url, callback) {
  173.         function resolve() {
  174.             resolved = true;
  175.             for (var i = 0, len = resolutions.length; i < len; i++) resolutions[i]()
  176.         }
  177.  
  178.         function reject() {
  179.             rejected = true;
  180.             for (var i = 0, len = rejections.length; i < len; i++) rejections[i]()
  181.         }
  182.  
  183.         var promise, count, id, urlString, resolutions = [], rejections = [], resolved = false, rejected = false;
  184.         this.count = this.count ? ++this.count : 1, count = this.count, urlString = url.split("/"), id = "load-css-" + urlString[urlString.length - 1], promise = {
  185.             done: function (callback) {
  186.                 return resolutions.push(callback), resolved && callback(), promise
  187.             }, fail: function (callback) {
  188.                 return rejections.push(callback), rejected && callback(), promise
  189.             }
  190.         };
  191.         var link = document.createElement("link");
  192.         return link.setAttribute("id", id), link.setAttribute("rel", "stylesheet"), link.setAttribute("type", "text/css"), "undefined" != typeof link.addEventListener ? (link.addEventListener("load", resolve, false), link.addEventListener("error", reject, false)) : "undefined" != typeof link.attachEvent && link.attachEvent("onload", function () {
  193.             var txt, cur, i = document.styleSheets.length;
  194.             try {
  195.                 for (; i--;) if (cur = document.styleSheets[i], cur.id === id) return txt = cur.cssText, void resolve()
  196.             } catch (e) {
  197.             }
  198.             resolved || reject()
  199.         }), RemitaPop.loadedScripts = RemitaPop.loadedScripts || {}, void 0 != RemitaPop.loadedScripts[id] || (RemitaPop.loadedScripts[id] = true, document.getElementsByTagName("head")[0].appendChild(link), link.setAttribute("href", url), promise)
  200.     }
  201.  
  202.     var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent", eventer = window[eventMethod],
  203.         messageEvent = "attachEvent" == eventMethod ? "onmessage" : "message",
  204.         config = {siteUrl: "http://localhost:8080/"};
  205.     Inline.prototype.loadButtonCSS = function () {
  206.         var buttonPath = config.siteUrl + "assets/css/button.min.css?ver=1";
  207.        // var buttonPath = config.siteUrl + "assets/css/button.min.css?ver=1";
  208.         cssLoad(buttonPath)
  209.     }, Inline.prototype.setupIframe = function () {
  210.         var instance = this;
  211.         instance.defaults.metadata.referrer = getHref(), instance.defaults.metadata = JSON.stringify(instance.defaults.metadata);
  212.         var htmlPath = config.siteUrl + "script-loader.html",
  213.             params = omitKeys(instance.defaults, ["customButton", "onClose", "callback", "tlsFallback"]);
  214.         params.hasTLSFallback = null !== instance.defaults.tlsFallback;
  215.         var source = htmlPath + "?" + serialize(validateChannels(params));
  216.         instance.isEmbed ? instance.setupEmbed(source) : instance.setupPopup(source)
  217.     }, Inline.prototype.setupPopup = function (source) {
  218.         var zIndex = 10 * findHighestZIndex("div"), cssText = "z-index: " + Math.max(zIndex, 999999);
  219.         cssText += ";\ndisplay: none;\nbackground: transparent;\nbackground: rgba(0,0,0,0.005);\nborder: 0px none transparent;\noverflow-x: hidden;\noverflow-y: hidden;\nvisibility: hidden;\nmargin: 0;\npadding: 0;\n-webkit-tap-highlight-color: transparent;\n-webkit-touch-callout: none; position: fixed;\nleft: 0;\ntop: 0;\nwidth: 100%;\nheight: 100%;", this.appendIframe({
  220.             src: source,
  221.             cssText: cssText,
  222.             className: "remita_pop",
  223.             parent: document.body
  224.         })
  225.     }, Inline.prototype.setupEmbed = function (source) {
  226.         var cssText = "background: transparent;\nbackground: rgba(0,0,0,0);\nborder: 0px none transparent;\noverflow-x: hidden;\noverflow-y: hidden;\nmargin: 0;\npadding: 0;\n-webkit-tap-highlight-color: transparent;\n-webkit-touch-callout: none;\nleft: 0;\ntop: 0;\nwidth: 100%;\nheight: 100%;",
  227.             container = document.getElementById(this.defaults.container);
  228.         container.innerHTML = "", container.removeAttribute("style"), container.className = "remita-embed-container", container.style.position = "relative", container.style.width = "100%", this.listenForResizeEvent(), this.appendIframe({
  229.             src: source,
  230.             cssText: cssText,
  231.             className: "remita_embed",
  232.             parent: container
  233.         }), this.openIframe()
  234.     }, Inline.prototype.appendIframe = function (options) {
  235.         var instance = this;
  236.         iframe = document.createElement("iframe"), iframe.setAttribute("frameBorder", "0"), iframe.setAttribute("allowtransparency", "true"), iframe.style.cssText = options.cssText, iframe.id = iframe.name = instance.defaults.id, iframe.src = options.src, iframe.className = options.className, options.parent.appendChild(iframe), iframe.onload = function () {
  237.             instance.iframeLoaded = true
  238.         }
  239.     }, Inline.prototype.createButton = function () {
  240.         var button, instance = this;
  241.         instance.defaults.customButton ? (button = document.getElementById(instance.defaults.customButton), button.setAttribute("data-remita", instance.defaults.id)) : (button = document.createElement("button"), button.innerHTML = "<span class='remita-top-blue'>Pay Securely with Remita</span><span class='remita-body-image'> </span>", button.setAttribute("class", "remita-trigger-btn"), button.setAttribute("data-remita", instance.defaults.id), sourceScript.parentNode.insertBefore(button, sourceScript.nextSibling)), button.addEventListener("click", function (e) {
  242.             e.preventDefault(), instance.openIframe()
  243.         }, false)
  244.     }, Inline.prototype.listenForCloseEvent = function () {
  245.         var instance = this;
  246.         eventer(messageEvent, function (e) {
  247.             var data = e.data || e.message;
  248.             if (data && ("string" == typeof data || data instanceof String)) {
  249.                 var response = parseResponse(data, instance.defaults);
  250.                 if (!response.isThisIframe) return;
  251.                 if ("RemitaClose" == response.action) {
  252.                     var chargeResponse = response.data;
  253.                     chargeResponse ? instance.handleSuccess(chargeResponse) : instance.defaults.onClose && instance.callCloseCallback(), instance.isEmbed || instance.closeIframe()
  254.                 }
  255.                 "RemitaTLSClose" == response.action && (instance.defaults.tlsFallback.call(this), instance.isEmbed || instance.closeIframe())
  256.             }
  257.         }, false)
  258.     }, Inline.prototype.listenForResizeEvent = function () {
  259.         var instance = this;
  260.         eventer(messageEvent, function (e) {
  261.             var data = e.data || e.message;
  262.             if (data && ("string" == typeof data || data instanceof String)) {
  263.                 var response = parseResponse(data, instance.defaults);
  264.                 if (!response.isThisIframe || "RemitaResize" != response.action) return;
  265.                 var container = document.getElementById(instance.defaults.container);
  266.                 container.style.height = response.data + "px"
  267.             }
  268.         }, false)
  269.     }, Inline.prototype.openIframe = function () {
  270.         var instance = this;
  271.         if (!this.iframeOpen) {
  272.             var open = function () {
  273.                 var iframe = document.getElementById(instance.defaults.id), receiver = iframe.contentWindow;
  274.                 receiver.postMessage("RemitaOpen " + instance.defaults.id, "*"), instance.isEmbed || (iframe.style.display = "block", iframe.style.visibility = "visible", document.body.style.overflow = "hidden"), instance.iframeOpen = true
  275.             };
  276.             instance.iframeLoaded ? open() : iframe.onload = function () {
  277.                 open(), instance.iframeLoaded = true
  278.             }
  279.         }
  280.     }, Inline.prototype.closeIframe = function () {
  281.         if (this.iframeOpen && !this.isEmbed) {
  282.             var iframe = document.getElementById(this.defaults.id);
  283.             iframe.style.display = "none", iframe.style.visibility = "hidden", this.iframeOpen = false, document.body.style.overflow = ""
  284.         }
  285.     }, Inline.prototype.handleSuccess = function (response) {
  286.         var chargeResponse = JSON.parse(response);
  287.         if (this.defaults.callback || this.form) {
  288.             if (this.form) {
  289.                 var input = document.createElement("input");
  290.                 input.type = "hidden", input.value = chargeResponse.reference, input.name = "reference", this.form.appendChild(input);
  291.                 var input = document.createElement("input");
  292.                 return input.type = "hidden", input.value = chargeResponse.reference, input.name = "remita-trxref", this.form.appendChild(input), void this.form.submit()
  293.             }
  294.             if (this.defaults.callback) {
  295.                 var inlineResponse = {reference: chargeResponse.reference, trxref: chargeResponse.reference};
  296.                 chargeResponse.page && (inlineResponse.page = chargeResponse.page), this.defaults.callback.call(this, inlineResponse)
  297.             }
  298.         }
  299.     }, Inline.prototype.callCloseCallback = function () {
  300.         this.defaults.onClose && this.defaults.onClose.call(this)
  301.     };
  302.     var RemitaPop = function () {
  303.         return {
  304.             setup: function (options, script) {
  305.                 var handler = "remita" + randomId(), defaults = {
  306.                     id: handler,
  307.                     key: options.key || "",
  308.                     ref: options.ref || "",
  309.                     bank: options.bank || "",
  310.                     label: options.label || "",
  311.                     email: options.email || "",
  312.                     amount: options.amount || "",
  313.                     currency: options.currency || "NGN",
  314.                     container: options.container,
  315.                     customButton: options.custom_button || options.customButton || "",
  316.                     firstname: options.firstName || "",
  317.                     lastname: options.lastName || "",
  318.                     customerId: options.customerId || "",
  319.                     phone: options.phone || "",
  320.                     remark: options.remark || "",
  321.                     payment_page: options.payment_page || options.paymentPage || "",
  322.                     payment_request: options.payment_request || options.paymentRequest || "",
  323.                     plan: options.plan || "",
  324.                     quantity: options.quantity || "",
  325.                     coupon: options.coupon || "",
  326.                     customer_code: options.customer_code || options.customerCode || "",
  327.                     invoice_limit: options.invoice_limit || options.invoiceLimit || "",
  328.                     start_date: options.start_date || options.startDate || "",
  329.                     interval: options.interval || options.interval || "",
  330.                     subaccount: options.subaccount || "",
  331.                     transaction_charge: options.transaction_charge || options.transactionCharge || "",
  332.                     bearer: options.bearer || "",
  333.                     metadata: options.metadata || {},
  334.                     onClose: options.on_close || options.onClose || "",
  335.                     callback: options.callback || "",
  336.                     tlsFallback: options.tlsFallback || "",
  337.                     channels: options.channels || "",
  338.                     card: options.card || "",
  339.                     bank: options.bank || ""
  340.                 };
  341.                 if (isValid(defaults)) return script ? (checkForParentForm(script), void(window[handler] = new Inline(defaults, getParentForm(script)))) : new Inline(defaults, (false))
  342.             }
  343.         }
  344.     }();
  345.     window.RemitaPop = RemitaPop;
  346.     var sourceScript = document.currentScript || function () {
  347.         var scripts = document.getElementsByTagName("script");
  348.         return scripts[scripts.length - 1]
  349.     }();
  350.     hasDataAttribute(sourceScript) && RemitaPop.setup({
  351.         key: sourceScript.getAttribute("data-key"),
  352.         ref: sourceScript.getAttribute("data-ref"),
  353.         bank: sourceScript.getAttribute("data-bank"),
  354.         label: sourceScript.getAttribute("data-label"),
  355.         email: sourceScript.getAttribute("data-email"),
  356.         amount: sourceScript.getAttribute("data-amount"),
  357.         currency: sourceScript.getAttribute("data-currency"),
  358.         container: sourceScript.getAttribute("data-container"),
  359.         customButton: sourceScript.getAttribute("data-custom-button"),
  360.         firstname: sourceScript.getAttribute("data-firstname"),
  361.         lastname: sourceScript.getAttribute("data-lastname"),
  362.         customerId: sourceScript.getAttribute("data-customerId"),
  363.         phone: sourceScript.getAttribute("data-phone"),
  364.         remark: sourceScript.getAttribute("data-remark"),
  365.         payment_page: sourceScript.getAttribute("data-payment-page"),
  366.         payment_request: sourceScript.getAttribute("data-payment-request"),
  367.         plan: sourceScript.getAttribute("data-plan"),
  368.         quantity: sourceScript.getAttribute("data-quantity"),
  369.         coupon: sourceScript.getAttribute("data-coupon"),
  370.         customer_code: sourceScript.getAttribute("data-customer-code"),
  371.         invoice_limit: sourceScript.getAttribute("data-invoice-limit"),
  372.         start_date: sourceScript.getAttribute("data-start-date"),
  373.         interval: sourceScript.getAttribute("data-interval"),
  374.         subaccount: sourceScript.getAttribute("data-subaccount"),
  375.         transaction_charge: sourceScript.getAttribute("data-transaction-charge"),
  376.         bearer: sourceScript.getAttribute("data-bearer"),
  377.         metadata: parseObject(sourceScript.getAttribute("data-metadata")),
  378.         onClose: parseFunction(sourceScript.getAttribute("data-on-close")),
  379.         callback: parseFunction(sourceScript.getAttribute("data-callback")),
  380.         tlsFallback: parseFunction(sourceScript.getAttribute("data-tls-callback")),
  381.         channels: sourceScript.getAttribute("data-channels"),
  382.         card: sourceScript.getAttribute("data-card"),
  383.         bank: sourceScript.getAttribute("data-bank")
  384.     }, sourceScript)
  385. }();