UNPKG

tap-payment-popupjs

Version:
355 lines (354 loc) 11.7 kB
const c = { // checkoutURL: "https://tap-checkout.netlify.app/", checkoutURL: "https://checkout.touchandpay.me/" // checkoutURL: "http://localhost:3050/", }; class u { /** * Constructor for the InlinePayment class. * @param {object} transactionDefaults - Default transaction parameters. */ constructor(t) { this.iframe = null, this.background = null, this.isIframeOpen = !1, this.transactionDefaults = t, this.checkoutRemoved = !1, this.fallback = h(), this.messageHandler = null, this.initializeCheckout(), this.listenForEvents(); } /** * Sets new transaction parameters and updates the iframe. * If a transaction already exists, it resets the checkout before setting the new one. * @param {object} transactionDefaults - The new transaction parameters. */ setTransaction(t) { this.transactionDefaults && this.resetCheckout(), this.transactionDefaults = t, this.updateIframe(); } /** * Initializes the checkout by creating the popup background. */ initializeCheckout() { this.createPopupBackground(); } /** * Prepares and returns the transaction parameters to be sent to the iframe. * It excludes internal fields and formats metadata and split fields. * @returns {object|null} The transaction parameters or null if not set. */ getTransactionParameters() { if (!this.transactionDefaults) return null; const t = ["onClose", "callback"]; return f(this.transactionDefaults, t); } /** * Sends a message to the iframe to update its content with new transaction details. */ updateIframe() { const t = this.getTransactionParameters(); setTimeout(() => { this.iframe.contentWindow.postMessage( { params: t }, "*" ); }, 3e3); } /** * Sets up a window event listener to handle messages from the checkout iframe. */ listenForEvents() { this.messageHandler = (t) => { this.checkoutRemoved || this.handleCheckoutEvents(t); }, window.addEventListener("message", this.messageHandler, !1); } /** * Opens the iframe to start a new checkout process. */ openIframe() { this.showCheckout(); } /** * Creates the background and checkout iframes and appends them to the document body. * The background iframe contains a loading spinner. */ createPopupBackground() { const t = document.createElement("iframe"); t.setAttribute("frameBorder", "0"), t.setAttribute("allowtransparency", "true"), t.id = d(), t.name = "checkout-background-" + t.id, t.style.cssText = ` z-index: 999999999999999; background: rgba(0, 0, 0, 0.75); border: none; overflow-x: hidden; overflow-y: hidden; position: fixed; left: 0; top: 0; width: 100%; height: 100%; visibility: hidden; display: none; transition: opacity 0.3s; `, this.background = t, document.body.appendChild(t); const n = this.background.contentWindow.document; n.open(), n.write(v()), n.close(); const i = document.createElement("iframe"); i.setAttribute("frameBorder", "0"), i.setAttribute("allowtransparency", "true"), i.setAttribute("allowpaymentrequest", "true"), i.id = d(), i.name = "checkout-" + i.id, i.style.cssText = ` z-index: 999999999999999; background: transparent; border: none; overflow-x: hidden; overflow-y: hidden; position: fixed; left: 0; top: 0; width: 100%; height: 100%; visibility: hidden; display: none; `, i.src = c.checkoutURL + "popup", this.iframe = i, document.body.appendChild(i); } /** * Displays the checkout iframe and the background overlay. */ showCheckout() { !this.iframe || this.isIframeOpen || (this.background.style.display = "", this.background.style.visibility = "visible", this.iframe.style.display = "", this.iframe.contentWindow.postMessage("render", "*"), this.isIframeOpen = !0); } /** * Hides the loading spinner in the background iframe once the transaction is loaded. */ removeLoader() { this.iframe.style.visibility = "visible"; const t = this.background.contentWindow.document.getElementById("app-loader"); t && (t.style.display = "none"); } /** * Handles events received from the checkout iframe, such as success or close events. * @param {MessageEvent} event - The event object from the message listener. */ handleCheckoutEvents(t) { if (t.origin + "/" === c.checkoutURL && this.iframe.contentWindow === t.source) { const n = t.data || t.message; try { n && n.response.success.status === 1 && (this.closeCheckout(!0), this.handleSuccess(n)); } catch { } switch (n) { case "loaded:transaction": this.removeLoader(); break; case "close": this.closeCheckout(); break; } } } /** * Closes the checkout iframe and hides the background. * @param {boolean} [success=false] - Indicates if the checkout was closed due to a successful transaction. */ closeCheckout(t = !1) { this.background.style.opacity = 0, this.iframe.style.display = "none", this.iframe.contentWindow.postMessage("close", "*"), this.isIframeOpen = !1, !t && this.transactionDefaults.onClose && this.transactionDefaults.onClose.call(this), setTimeout(() => { this.resetBackground(); }, 300); } /** * Resets the iframe and background to their initial states. */ resetCheckout() { this.resetIframe(), this.resetBackground(); } /** * Resets the main checkout iframe's visibility and clears transaction data. */ resetIframe() { this.iframe.style.visibility = "hidden", this.transactionDefaults = null, this.updateIframe(); } /** * Resets the background iframe to its initial state, showing the loader. */ resetBackground() { this.background.style.display = "none", this.background.style.opacity = 1, this.background.contentWindow.document.getElementById( "app-loader" ).style.display = "block"; } /** * Handles the callback for a successful transaction. * @param {object} response - The success response from the checkout iframe. */ handleSuccess(t) { this.transactionDefaults.callback && this.transactionDefaults.callback.call(this, t); } /** * Cleans up all resources, removing event listeners and DOM elements. */ destroy() { this.messageHandler && (window.removeEventListener("message", this.messageHandler), this.messageHandler = null), this.iframe && (this.iframe.remove(), this.iframe = null), this.background && (this.background.remove(), this.background = null), this.isIframeOpen = !1, this.checkoutRemoved = !0; } } let a; const r = { isInitialized: !1, /** * Initializes the inline payment system with default transaction parameters. * @param {object} transactionDefaults - Default transaction parameters. */ initialize(e) { a = new u(e), console.log("TAPPaymentPop initialized"), this.isInitialized = !0; }, /** * Sets up a new transaction. If not initialized, it will initialize first. * @param {object} transactionDetails - The details for the transaction. * @returns {InlinePayment|undefined} The instance of InlinePayment or undefined. */ setup(e) { const t = { apiKey: e.apiKey || "", // required transID: e.transID || "", // required amount: e.amount || "", // required email: e.email || "", // required env: e.env || "", phone: e.phone || "", superAgentFee: e.superAgentFee || "", savePaymentDetails: e.savePaymentDetails || !1, customerReference: e.customerReference || "", onClose: e.onClose || "", callback: e.callback || "", customPayload: { email: e.email, ...e.customPayload || {} // Ensure customPayload is an object } }; if (m(t)) return this.isInitialized ? (console.log("Setting transaction parameters"), a.setTransaction(t)) : (console.log("Initializing inline payment with parameters"), this.initialize(t)), a; }, /** * Destroys the current inline payment instance and cleans up resources. */ destroy() { a && (a.destroy(), a = null), this.isInitialized = !1; } }; function l() { return typeof window < "u" ? window : {}; } if (typeof l() < "u") { const e = l(); e.TAPPaymentPop = r, e.onload = () => { r.isInitialized || r.initialize(); }; } function d() { let e = ""; const t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (let n = 0; n < 5; n++) e += t.charAt(Math.floor(Math.random() * t.length)); return e; } function h() { const e = "onload" in document.createElement("iframe"); return e || console.warn( "This browser does not support iframes. Please redirect to standard" ), !e; } function f(e, t) { const n = JSON.parse(JSON.stringify(e)); return t.forEach((i) => { delete n[i]; }), Object.keys(n).forEach((i) => { (n[i] === null || n[i] === void 0 || n[i].length === 0) && delete n[i]; }), n; } function m(e) { if (p(e), !e.apiKey) throw new Error("Please provide your public key via the key attribute"); if (!e.amount) throw new Error("Please provide transaction amount via the amount"); if (!e.email) throw new Error( "Please provide customer email via the email or customerCode attribute" ); if (e.savePaymentDetails) { if (!e.customerReference) throw new Error( "Please provide customerReference when savePaymentDetails is true." ); if (!e.phone) throw new Error("Please provide phone when savePaymentDetails is true."); } return !0; } function p(e) { const t = { email: "email", amount: "number", superAgentFee: "number", onClose: "function", callback: "function" }; for (const s in e) e.hasOwnProperty(s) && n(s, e[s]); function n(s, o) { if (t[s] && o) switch (t[s]) { case "email": y(o) || i(s); break; case "number": b(o) || i(s); break; case "function": g(o) || i(s); break; case "object": w(o) || i(s); break; case "array": k(o) || i(s); } } function i(s) { const o = t[s]; throw alert(`Attribute ${s} must be a valid ${o}`), new Error(`Attribute ${s} must be a valid ${o}`); } } function y(e) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e); } function b(e) { const t = typeof e == "string" ? parseFloat(e) : e; return !isNaN(t) && isFinite(t) && t > 0; } function g(e) { return typeof e == "function"; } function w(e) { return e !== null && typeof e == "object"; } function k(e) { return Array.isArray(e); } function v() { return ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Loading...</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { display: flex; justify-content: center; align-items: center; height: 100vh; background: rgba(0, 0, 0, 0.50); } .loader { width: 50px; height: 50px; border: 5px solid white; border-top-color: transparent; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } </style> </head> <body> <div class="loader" id="app-loader"></div> </body> </html>`; } export { r as TAPPaymentPop }; //# sourceMappingURL=index.js.map