paivana

HTTP paywall reverse proxy
Log | Files | Refs | Submodules | README | LICENSE

commit 5ef237c75b7255ea1087a26321aa0aaa1dce7d66
parent c092a8709587eca93e1b0cfd462081c54d7c7133
Author: Sebastian <sebasjm@taler-systems.com>
Date:   Sun,  3 May 2026 19:45:26 -0300

use the right website from the location.hash

Diffstat:
Mcontrib/paywall.en.must | 39++++++++++++++++++++++-----------------
1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/contrib/paywall.en.must b/contrib/paywall.en.must @@ -85,11 +85,7 @@ </script> <script> async function main() { - const href = window.location.href; - // This is a policy decision: we include the query parameters - // in the website to support sites that need them, say if - // "?page=42" is being used instead of "/pages/42". - const website = href.split('#')[0]; + const website = atob(window.location.hash.substring(1)); const origin = window.location.origin; // cap at 100 years, we don't deal well with 'forever' otherwise @@ -103,7 +99,7 @@ const merchantHost = merchantUrl.host; const merchantPath = merchantUrl.path; - const expTime = Math.floor(Date.now() / 1000) + MAX_PICKUP_DELAY; + const expTime = Math.floor(Date.now() / 1000) + usePickupDelay; const nonceBuf = new Uint8Array(16); crypto.getRandomValues(nonceBuf); const nonce = encodeCrock(nonceBuf.buffer); @@ -117,9 +113,10 @@ `/`, MERCHANT_TEMPLATE_ID, `?session_id=${encodeURIComponent(paivanaId)}`, - `&fulfillment_url=${encodeURIComponent(href)}` + `&fulfillment_url=${encodeURIComponent(website)}` ].join(''); + const errorMessage = document.getElementById('error-message'); const talerLink = document.getElementById('talerlink'); talerLink.href = talerUri; @@ -133,28 +130,25 @@ correctLevel: QRCode.CorrectLevel.M }); - async function confirmPayment(orderId) { + async function confirmPayment(order_id) { talerLink.textContent = I18N_PAYMENT_CONFIRMED_LOADING; talerLink.href = '#'; try { const res = await fetch(`${origin}/.well-known/paivana`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ order_id: orderId, nonce, cur_time: { t_s: expTime }, website }), + body: JSON.stringify({ order_id, nonce, cur_time: { t_s: expTime }, website }), }); if (res.status >= 400) { talerLink.textContent = I18N_PAYMENT_CONFIRMED_PROBLEM; - const preError = document.createElement("pre") - preError.style = "text-wrap-mode = wrap"; - preError.innerText = JSON.stringify(await res.json()) - talerLink.parentElement.appendChild(preError); + errorMessage.textContent = JSON.stringify(await res.json()); } const dest = res.redirected ? res.url : website; await waitMs(400); - location.href = dest; + // location.href = dest; } catch (e) { console.warn('[paivana] Error trying to confirm payment:', e); - talerLink.textContent = I18N_PAYMENT_CONFIRMED_ERROR; + errorMessage.textContent = I18N_PAYMENT_CONFIRMED_ERROR; } } @@ -181,7 +175,7 @@ } else { talerLink.textContent = I18N_PAYMENT_CONFIRMED_NO_ORDER; await waitMs(400); - location.href = website; + // location.href = website; } return; } @@ -419,6 +413,10 @@ .cta:active { transform: scale(0.98); } + .button-cta { + display: flex; + margin: auto; + } /* footer note */ .footer-note { @@ -450,6 +448,10 @@ background-color: white; border: 1px black solid; z-index: 2; + flex-direction: column; + } + .footer p { + text-wrap-mode: wrap; } body { margin-bottom: 60px; @@ -568,7 +570,10 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this </div> <div class="footer"> - <a id="talerlink" href="" class="cta">Pay now</a> + <p id="error-message"> </p> + <div class="button-cta"> + <a target="_blank" id="talerlink" href="" class="cta">Pay now</a> + </div> </div> <script>