bank landing: pay popup script (shared shop-pay)

This commit is contained in:
Hernâni Marques 2026-07-10 19:59:26 +02:00
parent 8f9484ec16
commit 39dfbbd6d7
No known key found for this signature in database

View file

@ -0,0 +1,158 @@
/**
* GOA shop pay popup public pay-template + payto (no merchant secrets).
* QR: white modules, centered official qr-logo (DD 90).
*/
(function () {
var MERCHANT_HOST = "taler.hacktivism.ch";
var INSTANCE = "goa-demo-cp4zqk";
var SHOP_PAYTO =
"payto://x-taler-bank/bank.hacktivism.ch/goa-demo-cp4zqk?receiver-name=GOA%20Demo%20Shop%20cp4zqk";
var SHOP_PAYTO_HTTPS =
"https://bank.hacktivism.ch/webui/";
function payTemplateUri(productId) {
return (
"taler://pay-template/" +
MERCHANT_HOST +
"/instances/" +
INSTANCE +
"/" +
encodeURIComponent(productId)
);
}
function payTemplateHttps(productId) {
return (
"https://" +
MERCHANT_HOST +
"/instances/" +
INSTANCE +
"/templates/" +
encodeURIComponent(productId)
);
}
function introBase() {
var b = document.querySelector("base");
return b && b.href ? b.href : "/intro/";
}
function ensureModal() {
var m = document.getElementById("goa-pay-modal");
if (m) return m;
m = document.createElement("div");
m.id = "goa-pay-modal";
m.className = "goa-pay-modal";
m.setAttribute("role", "dialog");
m.setAttribute("aria-modal", "true");
m.setAttribute("aria-labelledby", "goa-pay-title");
m.hidden = true;
m.innerHTML =
'<div class="goa-pay-card">' +
' <button type="button" class="goa-pay-x" id="goa-pay-x" aria-label="Close">×</button>' +
' <h3 id="goa-pay-title">Pay with Taler</h3>' +
' <p class="goa-pay-amount" id="goa-pay-amount"></p>' +
' <div class="goa-pay-frame">' +
' <div class="goa-pay-qr" id="goa-pay-qr"></div>' +
' <img class="goa-pay-logo" id="goa-pay-logo" alt="" />' +
" </div>" +
' <p class="goa-pay-hint">Scan with GNU Taler Wallet</p>' +
' <a class="goa-pay-cta" id="goa-pay-open" href="#">Open payment link →</a>' +
' <p class="goa-pay-label">Payment URI (wallet)</p>' +
' <p class="goa-pay-line"><code class="goa-pay-uri" id="goa-pay-uri"></code> ' +
' <a class="goa-pay-https" id="goa-pay-uri-https" href="#" target="_blank" rel="noopener">(https)</a></p>' +
' <p class="goa-pay-label">Merchant payto (settlement)</p>' +
' <p class="goa-pay-line"><code class="goa-pay-uri" id="goa-pay-payto"></code> ' +
' <a class="goa-pay-https" id="goa-pay-payto-https" href="#" target="_blank" rel="noopener">(https)</a></p>' +
' <a class="goa-pay-payto-link" id="goa-pay-payto-link" href="#">Open payto:// link</a>' +
' <button type="button" class="goa-pay-close" id="goa-pay-close">Close</button>' +
"</div>";
document.body.appendChild(m);
function close() {
m.classList.remove("open");
m.hidden = true;
}
m.addEventListener("click", function (e) {
if (e.target === m) close();
});
document.getElementById("goa-pay-x").onclick = close;
document.getElementById("goa-pay-close").onclick = close;
document.addEventListener("keydown", function (e) {
if (e.key === "Escape" && m.classList.contains("open")) close();
});
return m;
}
function showPay(productId, name, amount) {
var m = ensureModal();
if (document.body && document.body.getAttribute("data-shop-theme") === "bank") {
m.classList.add("bank-theme");
} else {
m.classList.remove("bank-theme");
}
var uri = payTemplateUri(productId);
var httpsUri = payTemplateHttps(productId);
document.getElementById("goa-pay-title").textContent = name || productId;
document.getElementById("goa-pay-amount").textContent = amount || "";
var open = document.getElementById("goa-pay-open");
open.href = uri;
document.getElementById("goa-pay-uri").textContent = uri;
var uriHttps = document.getElementById("goa-pay-uri-https");
uriHttps.href = httpsUri;
uriHttps.textContent = "(https)";
document.getElementById("goa-pay-payto").textContent = SHOP_PAYTO;
var paytoHttps = document.getElementById("goa-pay-payto-https");
paytoHttps.href = SHOP_PAYTO_HTTPS;
paytoHttps.textContent = "(https)";
document.getElementById("goa-pay-payto-link").href = SHOP_PAYTO;
var qrHost = document.getElementById("goa-pay-qr");
qrHost.innerHTML = "";
var logo = document.getElementById("goa-pay-logo");
logo.src = introBase() + "qr-logo.svg";
logo.onerror = function () {
logo.style.display = "none";
};
logo.style.display = "";
if (typeof QRCode === "undefined") {
qrHost.innerHTML = '<p class="goa-pay-hint">QR library missing</p>';
} else {
new QRCode(qrHost, {
text: uri,
width: 220,
height: 220,
colorDark: "#000000",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.M,
});
}
m.hidden = false;
m.classList.add("open");
}
function bind() {
document.querySelectorAll("[data-product]").forEach(function (el) {
el.addEventListener("click", function (e) {
e.preventDefault();
var id = el.getAttribute("data-product");
var nameEl = el.querySelector(".name");
var priceEl = el.querySelector(".price");
showPay(
id,
nameEl ? nameEl.textContent.trim() : id,
priceEl ? priceEl.textContent.trim() : ""
);
});
});
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", bind);
} else {
bind();
}
})();