improve checkout
This commit is contained in:
parent
f1363a4f55
commit
4bb8e394ef
|
|
@ -359,6 +359,19 @@ export const dashboard = new Elysia()
|
||||||
return html("checkout", { nav: "settings", account: acc, payApi, invoiceId: params.id, coins, invoice });
|
return html("checkout", { nav: "settings", account: acc, payApi, invoiceId: params.id, coins, invoice });
|
||||||
})
|
})
|
||||||
|
|
||||||
|
.get("/dashboard/checkout/:id/status", async ({ cookie, headers, params, set }) => {
|
||||||
|
const resolved = await getAccountId(cookie, headers);
|
||||||
|
if (!resolved?.accountId) { set.status = 401; return { error: "Unauthorized" }; }
|
||||||
|
const payApi = process.env.PAY_API || "https://pay.pingql.com";
|
||||||
|
const key = cookie?.pingql_key?.value;
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${payApi}/checkout/${params.id}`, { headers: { "Authorization": `Bearer ${key}` } });
|
||||||
|
if (!res.ok) { set.status = res.status; return { error: "Not found" }; }
|
||||||
|
const data = await res.json();
|
||||||
|
return { status: data.status, amount_received: data.amount_received, amount_crypto: data.amount_crypto };
|
||||||
|
} catch { set.status = 500; return { error: "Could not fetch status" }; }
|
||||||
|
})
|
||||||
|
|
||||||
.get("/dashboard/checkout/:id/receipt", async ({ cookie, headers, params, set }) => {
|
.get("/dashboard/checkout/:id/receipt", async ({ cookie, headers, params, set }) => {
|
||||||
const resolved = await getAccountId(cookie, headers);
|
const resolved = await getAccountId(cookie, headers);
|
||||||
if (!resolved?.accountId) return redirect("/dashboard");
|
if (!resolved?.accountId) return redirect("/dashboard");
|
||||||
|
|
|
||||||
|
|
@ -186,10 +186,10 @@
|
||||||
%>
|
%>
|
||||||
|
|
||||||
<% if (isPending) { %>
|
<% if (isPending) { %>
|
||||||
<meta http-equiv="refresh" content="5">
|
<noscript><meta http-equiv="refresh" content="5"></noscript>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
<div class="card-static overflow-hidden">
|
<div class="card-static overflow-hidden" data-pay-status="<%= inv.status %>">
|
||||||
|
|
||||||
<!-- Header bar -->
|
<!-- Header bar -->
|
||||||
<div class="px-6 py-4 border-b divider flex items-center justify-between">
|
<div class="px-6 py-4 border-b divider flex items-center justify-between">
|
||||||
|
|
@ -229,7 +229,7 @@
|
||||||
<!-- Progress bar -->
|
<!-- Progress bar -->
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<div class="w-full h-1.5 rounded-full bg-gray-800 overflow-hidden">
|
<div class="w-full h-1.5 rounded-full bg-gray-800 overflow-hidden">
|
||||||
<div class="h-full rounded-full bg-green-500 transition-all" style="width: <%= pct %>%"></div>
|
<div class="h-full rounded-full bg-green-500 transition-all" data-progress-bar style="width: <%= pct %>%"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between mt-2 text-sm">
|
<div class="flex justify-between mt-2 text-sm">
|
||||||
<span class="text-green-400 font-mono"><%= received.toFixed(8) %> received</span>
|
<span class="text-green-400 font-mono"><%= received.toFixed(8) %> received</span>
|
||||||
|
|
@ -323,6 +323,32 @@
|
||||||
if (btn) { btn.textContent = 'Copied'; setTimeout(() => btn.textContent = 'Copy', 1500); }
|
if (btn) { btn.textContent = 'Copied'; setTimeout(() => btn.textContent = 'Copy', 1500); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Poll payment status instead of meta refresh
|
||||||
|
(function() {
|
||||||
|
const m = location.pathname.match(/\/dashboard\/checkout\/([^/]+)$/);
|
||||||
|
if (!m) return;
|
||||||
|
const id = m[1];
|
||||||
|
let lastStatus = document.querySelector('[data-pay-status]')?.dataset.payStatus;
|
||||||
|
if (!lastStatus || lastStatus === 'paid' || lastStatus === 'expired') return;
|
||||||
|
|
||||||
|
async function poll() {
|
||||||
|
try {
|
||||||
|
const res = await fetch('/dashboard/checkout/' + id + '/status', { credentials: 'same-origin' });
|
||||||
|
if (!res.ok) return;
|
||||||
|
const data = await res.json();
|
||||||
|
if (data.status !== lastStatus) { location.reload(); return; }
|
||||||
|
// Update progress bar in-place for partial payments
|
||||||
|
const received = parseFloat(data.amount_received || '0');
|
||||||
|
const total = parseFloat(data.amount_crypto || '1');
|
||||||
|
const pct = Math.min(100, Math.round((received / total) * 100));
|
||||||
|
const bar = document.querySelector('[data-progress-bar]');
|
||||||
|
if (bar) bar.style.width = pct + '%';
|
||||||
|
} catch {}
|
||||||
|
setTimeout(poll, 1500);
|
||||||
|
}
|
||||||
|
setTimeout(poll, 1500);
|
||||||
|
})();
|
||||||
|
|
||||||
const multipliers = { pro: 1, pro2x: 2, pro4x: 4 };
|
const multipliers = { pro: 1, pro2x: 2, pro4x: 4 };
|
||||||
const lifetimePlans = { lifetime: 'lifetime', lifetime2x: 'lifetime2x', lifetime4x: 'lifetime4x' };
|
const lifetimePlans = { lifetime: 'lifetime', lifetime2x: 'lifetime2x', lifetime4x: 'lifetime4x' };
|
||||||
const planValue = document.getElementById('plan-value');
|
const planValue = document.getElementById('plan-value');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue