0 ? String(total) : '0';
});
}
// ===== SHOPIFY CHECKOUT HELPERS =====
window.goToShopifyCartCheckout = function(){
let shopifyDomain = '';
try {
const urlParams = new URLSearchParams(window.location.search);
shopifyDomain = (urlParams.get('shopify_domain_name') || '').trim();
} catch (e) {
shopifyDomain = '';
}
if (!shopifyDomain) {
const shopifyDomainEl = document.getElementById('shopifyDomainName');
if (shopifyDomainEl && shopifyDomainEl.value) {
shopifyDomain = String(shopifyDomainEl.value).trim();
}
}
if (!shopifyDomain && window.__shopifyDomainName) {
shopifyDomain = String(window.__shopifyDomainName).trim();
}
if (!shopifyDomain) {
const sellerEl = document.getElementById('sellerDomain');
if (sellerEl && sellerEl.value) {
shopifyDomain = String(sellerEl.value).trim();
}
}
if (!shopifyDomain) {
alert('Shopify domain is missing. Add shopify_domain_name to the page URL, or publish with a Shopify domain configured.');
return;
}
const lowerDomain = shopifyDomain.toLowerCase();
if (!lowerDomain.startsWith('http://') && !lowerDomain.startsWith('https://')) {
shopifyDomain = 'https://' + shopifyDomain;
}
while (shopifyDomain.endsWith('/')) {
shopifyDomain = shopifyDomain.slice(0, -1);
}
const cart = getCart();
if (!Array.isArray(cart) || cart.length === 0) {
alert('Your cart is empty. Please add items before checkout.');
return;
}
const lineItems = cart
.map(item => {
const variantId = item && item.variantId != null ? String(item.variantId).trim() : '';
const qty = parseInt(item && item.quantity != null ? item.quantity : 0, 10);
if (!variantId || !/^[0-9]+$/.test(variantId) || !Number.isFinite(qty) || qty <= 0) {
return '';
}
return variantId + ':' + qty;
})
.filter(Boolean);
if (lineItems.length === 0) {
alert('No valid Shopify variants found in cart.');
return;
}
window.location.href = shopifyDomain + '/cart/' + lineItems.join(',');
};
window.goToShopifyVariantCheckout = function(qty, variantId){
var q = parseInt(qty, 10);
if (!Number.isFinite(q) || q < 1) q = 1;
var vid = variantId != null ? String(variantId).trim() : '';
if (!vid && window.selectedVariantId != null) {
vid = String(window.selectedVariantId).trim();
}
if (!vid || !/^[0-9]+$/.test(vid)) {
alert('Please select a variant before checkout.');
return;
}
var shopifyDomain = '';
try {
var urlParams = new URLSearchParams(window.location.search);
shopifyDomain = (urlParams.get('shopify_domain_name') || '').trim();
} catch (e) {
shopifyDomain = '';
}
if (!shopifyDomain) {
var shopifyDomainEl = document.getElementById('shopifyDomainName');
if (shopifyDomainEl && shopifyDomainEl.value) shopifyDomain = String(shopifyDomainEl.value).trim();
}
if (!shopifyDomain && window.__shopifyDomainName) {
shopifyDomain = String(window.__shopifyDomainName).trim();
}
if (!shopifyDomain) {
var sellerEl = document.getElementById('sellerDomain');
if (sellerEl && sellerEl.value) shopifyDomain = String(sellerEl.value).trim();
}
if (!shopifyDomain) {
alert('Shopify domain is missing. Add shopify_domain_name to the page URL, or publish with a Shopify domain configured.');
return;
}
var lowerDomain = shopifyDomain.toLowerCase();
if (lowerDomain.indexOf('http://') !== 0 && lowerDomain.indexOf('https://') !== 0) {
shopifyDomain = 'https://' + shopifyDomain;
}
while (shopifyDomain.slice(-1) === '/') {
shopifyDomain = shopifyDomain.slice(0, -1);
}
window.location.href = shopifyDomain + '/cart/' + vid + ':' + q;
};
// ===== OPERATIONS =====
window.addToCart = function(product){
const quantityEl = document.querySelector('#quantity');
let quantity = 1;
if (quantityEl) {
const qtyValue = quantityEl.innerHTML || quantityEl.value || '1';
quantity = parseInt(qtyValue, 10) || 1;
}
let variantPrice = 0;
let variantImage = '';
let variantId = null;
let variantTitle = '';
let taxPerItem = 0;
let compareAtPrice = 0;
let shippingCost = 0;
let currency = '';
if (window.selectedVariantId && window.variantsData && Array.isArray(window.variantsData)) {
const selectedVariant = window.variantsData.find(v => v.variant_id == window.selectedVariantId);
if (selectedVariant) {
variantPrice = Number(selectedVariant.variant_price) || 0;
variantImage = selectedVariant.variant_image || '';
variantId = selectedVariant.variant_id;
variantTitle = selectedVariant.variant_title || '';
taxPerItem = Number(selectedVariant.tax_per_item) || 0;
compareAtPrice = Number(selectedVariant.compare_at_price) || 0;
shippingCost = Number(selectedVariant.shipping_cost) || 0;
currency = selectedVariant.currency || '';
} else {
console.warn('[addToCart] Selected variant not found in variantsData');
}
} else if (window.variantsData && Array.isArray(window.variantsData) && window.variantsData.length > 0) {
alert('Please select a variant before adding to cart');
return;
} else {
alert('Please select a product variant before adding to cart');
return;
}
const cart = getCart();
const cartItemId = product.id + '_' + variantId;
const existing = cart.find(p => p.id === cartItemId);
if(existing){
existing.quantity += quantity;
} else {
cart.push({
id: cartItemId,
productId: product.id,
name: product.name + (variantTitle ? ' (' + variantTitle + ')' : ''),
price: variantPrice,
image: variantImage,
variantId: variantId,
variantTitle: variantTitle,
quantity: quantity,
taxPerItem: taxPerItem,
compareAtPrice: compareAtPrice,
shippingCost: shippingCost,
currency: currency
});
}
saveCart(cart);
openCart();
};
window.removeFromCart = function(id){
const cart = getCart().filter(p => p.id !== id);
saveCart(cart);
};
window.updateCartQty = function(id, delta){
const cart = getCart();
const item = cart.find(p => p.id === id);
if(!item) return;
item.quantity += delta;
if(item.quantity <= 0){
window.removeFromCart(id);
return;
}
saveCart(cart);
};
// ===== RENDER =====
const CURRENCY_SYMBOLS = {
INR: '₹', USD: '$', EUR: '€', GBP: '£',
AUD: 'A$', CAD: 'C$', AED: 'د.إ', SGD: 'S$'
};
function getCurrencySymbol(cart) {
for (var i = 0; i < cart.length; i++) {
var code = (cart[i].currency || '').toUpperCase();
if (code && CURRENCY_SYMBOLS[code]) return CURRENCY_SYMBOLS[code];
}
return '₹';
}
function renderCart(){
const container = document.getElementById("cart-items-container");
if(!container) return;
const cart = getCart();
container.innerHTML = "";
if(cart.length === 0) {
container.innerHTML = [
'
',
'
Your cart is empty
'
].join('');
const emptySym = getCurrencySymbol([]);
const subtotalEl = document.getElementById("cart-subtotal");
const taxEl = document.getElementById("cart-tax");
const totalEl = document.getElementById("cart-total");
const shippingEl = document.getElementById("cart-shipping");
if(subtotalEl) subtotalEl.innerHTML = emptySym + "0.00";
if(taxEl) taxEl.innerHTML = emptySym + "0.00";
if(shippingEl) shippingEl.innerHTML = emptySym + "0.00";
if(totalEl) totalEl.innerHTML = emptySym + "0.00";
return;
}
let subtotal = 0;
let totalTax = 0;
let totalShipping = 0;
cart.forEach(item => {
subtotal += item.price * item.quantity;
const taxValue = Number(item.taxPerItem) || 0;
if (taxValue > 0) totalTax += taxValue * item.quantity;
const shippingValue = Number(item.shippingCost) || 0;
if (shippingValue > 0) totalShipping += shippingValue;
const itemDiv = document.createElement('div');
itemDiv.className = 'flex gap-3 pb-4 border-b border-gray-200';
const img = document.createElement('img');
img.src = item.image;
img.className = 'w-20 h-20 object-cover rounded-lg border border-gray-300 flex-shrink-0';
img.onerror = function() { this.src = 'data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%22100%22 height=%22100%22%3E%3Crect fill=%22%23f0f0f0%22 width=%22100%22 height=%22100%22/%3E%3C/svg%3E'; };
const contentDiv = document.createElement('div');
contentDiv.className = 'flex-1 flex flex-col gap-2';
const nameDiv = document.createElement('div');
nameDiv.className = 'text-base font-semibold text-gray-800';
nameDiv.innerHTML = item.name;
const priceDiv = document.createElement('div');
const sym = CURRENCY_SYMBOLS[(item.currency || '').toUpperCase()] || '₹';
if (item.compareAtPrice && item.compareAtPrice > 0 && item.compareAtPrice !== item.price) {
priceDiv.className = 'flex items-center gap-2';
priceDiv.innerHTML = '
' + sym + item.price.toFixed(2) + ''
+ '
' + sym + item.compareAtPrice.toFixed(2) + '';
} else {
priceDiv.className = 'text-sm text-gray-600';
priceDiv.innerHTML = sym + item.price.toFixed(2);
}
const qtyDiv = document.createElement('div');
qtyDiv.className = 'flex items-center gap-3 mt-auto';
const minusBtn = document.createElement('button');
minusBtn.className = 'w-7 h-7 border border-gray-300 bg-white cursor-pointer text-lg rounded flex items-center justify-center hover:bg-gray-100';
minusBtn.innerHTML = '−';
minusBtn.onclick = (function(id){ return function() { window.updateCartQty(id, -1); }; })(item.id);
const qtySpan = document.createElement('span');
qtySpan.className = 'text-sm text-gray-800 min-w-10 text-center';
qtySpan.innerHTML = 'Qty: ' + item.quantity;
const plusBtn = document.createElement('button');
plusBtn.className = 'w-7 h-7 border border-gray-300 bg-white cursor-pointer text-lg rounded flex items-center justify-center hover:bg-gray-100';
plusBtn.innerHTML = '+';
plusBtn.onclick = (function(id){ return function() { window.updateCartQty(id, 1); }; })(item.id);
qtyDiv.appendChild(minusBtn);
qtyDiv.appendChild(qtySpan);
qtyDiv.appendChild(plusBtn);
contentDiv.appendChild(nameDiv);
contentDiv.appendChild(priceDiv);
contentDiv.appendChild(qtyDiv);
const removeBtn = document.createElement('button');
removeBtn.className = 'flex h-7 w-7 cursor-pointer items-center justify-center self-start rounded border-none bg-red-500 text-lg leading-none text-white hover:bg-red-700';
removeBtn.innerHTML = '×';
removeBtn.onclick = (function(id){ return function() { window.removeFromCart(id); }; })(item.id);
itemDiv.appendChild(img);
itemDiv.appendChild(contentDiv);
itemDiv.appendChild(removeBtn);
container.appendChild(itemDiv);
});
const total = subtotal + totalTax + totalShipping;
const subtotalEl = document.getElementById("cart-subtotal");
const taxEl = document.getElementById("cart-tax");
const shippingEl = document.getElementById("cart-shipping");
const totalEl = document.getElementById("cart-total");
const cartSym = getCurrencySymbol(cart);
if(subtotalEl) subtotalEl.innerHTML = cartSym + subtotal.toFixed(2);
const taxRow = document.getElementById("tax-price");
if (taxRow) {
taxRow.style.display = totalTax > 0 ? 'flex' : 'none';
if(taxEl && totalTax > 0) taxEl.innerHTML = cartSym + totalTax.toFixed(2);
}
const shippingRow = document.getElementById("shipping-price");
if (shippingRow) {
shippingRow.style.display = totalShipping > 0 ? 'flex' : 'none';
if(shippingEl && totalShipping > 0) shippingEl.innerHTML = cartSym + totalShipping.toFixed(2);
}
if(totalEl) totalEl.innerHTML = cartSym + total.toFixed(2);
}
// ===== UI CONTROL =====
window.openCart = function(){
document.querySelector(".cart-drawer")?.classList.add("active");
document.querySelector(".drawer-overlay")?.classList.add("active");
};
window.closeCart = function(){
document.querySelector(".cart-drawer")?.classList.remove("active");
document.querySelector(".drawer-overlay")?.classList.remove("active");
};
// ===== SHIPROCKET CHECKOUT =====
function goToShipRocketCheckout(){
var cart = getCart();
if (!cart.length) { alert('Your cart is empty.'); return; }
var domain = (window.zedConfig && window.zedConfig.shiprocketDomain) || '';
if (!domain) {
try {
var urlParams = new URLSearchParams(window.location.search);
domain = (urlParams.get('shiprocket_domain_name') || '').trim();
} catch(e) {}
}
if (!domain) {
var sellerEl = document.getElementById('sellerDomain');
if (sellerEl && sellerEl.value) domain = String(sellerEl.value).trim();
}
if (!domain) return;
var products = cart.map(function(item){
var vid = String(item.variantId || '').trim();
var qty = parseInt(item.quantity, 10);
return (vid && qty > 0) ? { variantId: vid, quantity: qty } : null;
}).filter(Boolean);
if (!products.length) { alert('No valid variants found in cart.'); return; }
function _doCheckout(){
var inp = document.getElementById('sellerDomain');
if (!inp) {
inp = document.createElement('input');
inp.type = 'hidden';
inp.id = 'sellerDomain';
document.body.appendChild(inp);
}
inp.value = domain;
shiprocketCheckoutEvents.buyDirect({ type: 'cart', products: products });
}
if (typeof shiprocketCheckoutEvents !== 'undefined') {
_doCheckout();
return;
}
// Load SDK CSS if not already present
if (!document.querySelector('link[href*="fastrr-boost-ui.pickrr.com/assets/styles/shopify.css"]')) {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://fastrr-boost-ui.pickrr.com/assets/styles/shopify.css';
document.head.appendChild(link);
}
// Load SDK JS if not already present
if (!document.querySelector('script[src*="fastrr-boost-ui.pickrr.com/assets/js/channels/shopify.js"]')) {
var sdkScript = document.createElement('script');
sdkScript.src = 'https://fastrr-boost-ui.pickrr.com/assets/js/channels/shopify.js';
sdkScript.onload = _doCheckout;
sdkScript.onerror = function(){ alert('Failed to load Shiprocket checkout SDK.'); };
document.head.appendChild(sdkScript);
} else {
// SDK script tag exists but shiprocketCheckoutEvents not ready yet — poll
var _attempts = 0;
var _poll = setInterval(function(){
if (typeof shiprocketCheckoutEvents !== 'undefined') {
clearInterval(_poll);
_doCheckout();
} else if (++_attempts > 40) {
clearInterval(_poll);
alert('Shiprocket checkout SDK failed to initialise.');
}
}, 100);
}
}
// ===== INIT =====
document.addEventListener("DOMContentLoaded", function(){
renderCart();
_updateCartBadge();
// Wire Proceed to Checkout based on checkout mode detected from URL params.
// - shopify_domain_name → goToShopifyCartCheckout
// - shiprocket_domain_name → goToShipRocketCheckout
// - neither (native) → pre-built anchor with encrypted checkout href; no JS handler needed.
// Guard: skip if the button was already replaced with an
tag by the payment-gateway flow.
var checkoutBtn = document.getElementById('zed-proceed-checkout');
if (checkoutBtn && checkoutBtn.tagName !== 'A') {
var _urlP = new URLSearchParams(window.location.search);
// Check URL params first (editor mode), then embedded page values (published mode).
// Embedded values are injected at session/publish time so they survive on live pages
// where URL params are absent.
var _shopifyD = (_urlP.get('shopify_domain_name') || '').trim()
|| (typeof window.__shopifyDomainName === 'string' ? window.__shopifyDomainName.trim() : '')
|| ((document.getElementById('shopifyDomainName') || {}).value || '').trim();
var _shiprocketD = (_urlP.get('shiprocket_domain_name') || '').trim()
|| (window.zedConfig && window.zedConfig.shiprocketDomain ? String(window.zedConfig.shiprocketDomain).trim() : '')
|| ((document.getElementById('sellerDomain') || {}).value || '').trim();
if (_shopifyD) {
checkoutBtn.addEventListener('click', window.goToShopifyCartCheckout);
} else if (_shiprocketD) {
checkoutBtn.addEventListener('click', goToShipRocketCheckout);
}
}
});
window.addEventListener("storage", function(e){
if(e.key === CART_KEY){
renderCart();
_updateCartBadge();
}
});
})();