bathrooms


IMPORTANT! All customers must create and/or be logged into their DeVere web account to complete their order and checkout. Please LOGIN or CREATE a new account by going here: Login / Register.
If you experience any issues or have questions, please call us at (800) 833-8373. Thank You.

Showing the single result

/* ========================================================================== DeVere Chemical — Invoice Payment Portal -------------------------------------------------------------------------- ARCHITECTURE NOTE (read before deploying): This page is static (no server). Stripe requires a secret-key API call to create/confirm a real charge, which can never run safely in browser JS. So actual card entry happens on Stripe's own hosted payment page (a "Payment Link"), not on this page. This page collects the invoice number, amount, and contact info, shows the "Ready to pay?" confirmation, and then hands off to Stripe with the invoice number attached as a reference so it shows up on the payment record in the Stripe Dashboard. SETUP REQUIRED before going live: 1. In the Stripe Dashboard, create a Payment Link that allows the customer to enter a custom amount ("Customer chooses price"). 2. Paste that Payment Link URL into STRIPE_PAYMENT_LINK below. 3. Paste your Stripe publishable key into STRIPE_PUBLISHABLE_KEY if you later add Stripe.js elsewhere on the page (not required for the Payment Link redirect flow itself). ========================================================================== */ const CONFIG = { STRIPE_PUBLISHABLE_KEY: "pk_live_REPLACE_ME", STRIPE_PAYMENT_LINK: "https://buy.stripe.com/9B614ffBK2YiecJavK14400", DRAFT_STORAGE_KEY: "dv_payment_portal_draft", }; const form = document.getElementById("dv-payment-form"); const confirmSection = document.getElementById("dv-confirm"); const redirectingSection = document.getElementById("dv-redirecting"); const fields = { invoiceNumber: document.getElementById("invoiceNumber"), amount: document.getElementById("amount"), fullName: document.getElementById("fullName"), email: document.getElementById("email"), }; const confirmYesBtn = document.getElementById("dv-confirm-yes"); const confirmNoBtn = document.getElementById("dv-confirm-no"); function loadDraft() { try { const raw = localStorage.getItem(CONFIG.DRAFT_STORAGE_KEY); if (!raw) return; const draft = JSON.parse(raw); Object.keys(fields).forEach((key) => { if (draft[key] !== undefined) fields[key].value = draft[key]; }); } catch (e) { /* ignore corrupt/unavailable storage */ } } function saveDraft() { const draft = {}; Object.keys(fields).forEach((key) => { draft[key] = fields[key].value; }); try { localStorage.setItem(CONFIG.DRAFT_STORAGE_KEY, JSON.stringify(draft)); } catch (e) { /* storage unavailable (private browsing, quota) — non-fatal */ } } function clearDraft() { try { localStorage.removeItem(CONFIG.DRAFT_STORAGE_KEY); } catch (e) { /* ignore */ } } function setError(fieldName, message) { const errorEl = document.getElementById("err-" + fieldName); errorEl.textContent = message || ""; fields[fieldName].classList.toggle("dv-invalid", Boolean(message)); } function validate() { let valid = true; if (!fields.invoiceNumber.value.trim()) { setError("invoiceNumber", "Invoice number is required."); valid = false; } else { setError("invoiceNumber", ""); } const amountValue = parseFloat(fields.amount.value); if (!fields.amount.value || isNaN(amountValue) || amountValue <= 0) { setError("amount", "Enter a valid payment amount greater than $0."); valid = false; } else { setError("amount", ""); } if (!fields.fullName.value.trim()) { setError("fullName", "Name is required."); valid = false; } else { setError("fullName", ""); } const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailPattern.test(fields.email.value.trim())) { setError("email", "Enter a valid email address."); valid = false; } else { setError("email", ""); } return valid; } function formatCurrency(value) { return new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", }).format(value); } function showConfirmScreen() { document.getElementById("sum-invoice").textContent = fields.invoiceNumber.value.trim(); document.getElementById("sum-amount").textContent = formatCurrency(parseFloat(fields.amount.value)); document.getElementById("sum-name").textContent = fields.fullName.value.trim(); document.getElementById("sum-email").textContent = fields.email.value.trim(); form.hidden = true; confirmSection.hidden = false; confirmSection.scrollIntoView({ behavior: "smooth", block: "start" }); } function showForm() { confirmSection.hidden = true; form.hidden = false; } function buildStripeRedirectUrl() { const url = new URL(CONFIG.STRIPE_PAYMENT_LINK); url.searchParams.set("client_reference_id", fields.invoiceNumber.value.trim()); url.searchParams.set("prefilled_email", fields.email.value.trim()); return url.toString(); } function handlePayNow() { confirmSection.hidden = true; redirectingSection.hidden = false; clearDraft(); window.location.href = buildStripeRedirectUrl(); } form.addEventListener("submit", (event) => { event.preventDefault(); if (validate()) { saveDraft(); showConfirmScreen(); } }); confirmNoBtn.addEventListener("click", () => { showForm(); }); confirmYesBtn.addEventListener("click", () => { handlePayNow(); }); Object.values(fields).forEach((input) => { input.addEventListener("input", saveDraft); }); loadDraft();