/* * Square "Pay" button embed loader. * ───────────────────────────────── * A school drops ONE script tag onto their own website: * * * * It injects a responsive (pay-frame.php) right where the script tag * sits, so the Square card form renders inline on their page. The card data is * tokenized by Square inside the iframe and never touches their site or ours. * * To place the button somewhere specific, give a target: * data-target="#pay-here" → renders into that element instead of inline. */ (function () { 'use strict'; // The currently executing script tag (so we can read its data-* and the base // URL it was served from). document.currentScript is reliable for sync loads; // for async we fall back to the last script that points at embed.js. var me = document.currentScript || (function () { var all = document.getElementsByTagName('script'); for (var i = all.length - 1; i >= 0; i--) { if ((all[i].src || '').indexOf('embed.js') !== -1) return all[i]; } return null; })(); if (!me) return; var key = me.getAttribute('data-square-key') || ''; if (!key) { console.error('[square-embed] missing data-square-key on the embed script tag.'); return; } // Derive the integration base URL (…/square/) from this script's own src so // the school never has to configure a second URL. var base = me.src.replace(/embed\.js(\?.*)?$/, ''); var amount = me.getAttribute('data-amount') || ''; var currency = me.getAttribute('data-currency') || ''; var email = me.getAttribute('data-email') || ''; var success = me.getAttribute('data-success') || ''; var qs = 'key=' + encodeURIComponent(key) + '&amount=' + encodeURIComponent(amount); if (currency) qs += '¤cy=' + encodeURIComponent(currency); if (email) qs += '&email=' + encodeURIComponent(email); if (success) qs += '&success=' + encodeURIComponent(success); var iframe = document.createElement('iframe'); iframe.src = base + 'pay-frame.php?' + qs; iframe.setAttribute('title', 'Pay with Square'); iframe.setAttribute('scrolling', 'no'); iframe.setAttribute('allow', 'payment'); iframe.style.cssText = 'width:100%;max-width:520px;border:0;overflow:hidden;display:block;height:280px;' + 'transition:height .15s ease;'; // A stable name lets us match height messages to THIS iframe if a page has // several embedded buttons. var frameName = 'sqpayframe_' + Math.random().toString(36).slice(2); iframe.name = frameName; // Resize the iframe to its content height as reported by pay-frame.php. window.addEventListener('message', function (ev) { var d = ev.data; if (!d || d.sqPayFrame !== true || d.type !== 'height') return; // Only react to messages from our own frame's content window. if (ev.source !== iframe.contentWindow) return; var h = parseInt(d.height, 10); if (h > 0) iframe.style.height = (h + 4) + 'px'; }); // Insert: into data-target if given, else right where the script tag is. var targetSel = me.getAttribute('data-target'); if (targetSel) { var target = document.querySelector(targetSel); if (target) { target.appendChild(iframe); return; } console.warn('[square-embed] data-target "' + targetSel + '" not found; inlining instead.'); } (me.parentNode || document.body).insertBefore(iframe, me); })();