Skip to content
  • iPhone
  • Macbook Air
  • MacBook Pro
  • Windows Laptops
Log in

Language

  • English
  • العربية
    Black Mint
    • iPhone
    • Macbook Air
    • MacBook Pro
    • Windows Laptops
    Trade-in your device
    Log in Cart

    Item added to your cart

    View cart

    Filter:

    Remove all
    Availability (0)
    Availability
    Price
    The highest price is 82,240.00 EGP
    ج.م
    Brand (0)
    Brand
    Filter Filter

    Filter

    Filter

    21 products

    Availability
    Clear
    Price

    The highest price is 82,240.00 EGP

    ج.م
    ج.م
    Clear
    Brand
    Clear
    Remove all
    Remove all

    21 products

    • iPhone 11

      iPhone 11

      -32% vs new

      iPhone 11

      Regular price From 12,959.00 EGP
      Regular price 19,000.00 EGP New Sale price From 12,959.00 EGP
      Unit price 12,959.00 EGP /  per  item
      -32% vs new
    • iPhone 13

      iPhone 13

      -20% vs new

      iPhone 13

      Regular price From 27,950.00 EGP
      Regular price 35,000.00 EGP New Sale price From 27,950.00 EGP
      Unit price 27,950.00 EGP /  per  item
      -20% vs new
    • iPhone 16 Pro Max

      iPhone 16 Pro Max

      -12% vs new

      iPhone 16 Pro Max

      Regular price From 74,405.00 EGP
      Regular price 85,000.00 EGP New Sale price From 74,405.00 EGP
      Unit price 74,405.00 EGP /  per  item
      -12% vs new
    • iPhone 12 Pro

      iPhone 12 Pro

      -22% vs new

      iPhone 12 Pro

      Regular price From 25,080.00 EGP
      Regular price 32,000.00 EGP New Sale price From 25,080.00 EGP
      Unit price /  per 
      -22% vs new
    • iPhone 13 Pro

      iPhone 13 Pro

      -18% vs new

      iPhone 13 Pro

      Regular price From 37,950.00 EGP
      Regular price 46,000.00 EGP New Sale price From 37,950.00 EGP
      Unit price /  per 
      -18% vs new
    • iPhone 13 Pro Max

      iPhone 13 Pro Max

      -17% vs new

      iPhone 13 Pro Max

      Regular price From 39,800.00 EGP
      Regular price 48,000.00 EGP New Sale price From 39,800.00 EGP
      Unit price /  per 
      -17% vs new
    • iPhone 14 Pro

      iPhone 14 Pro

      -31% vs new

      iPhone 14 Pro

      Regular price From 42,636.00 EGP
      Regular price 62,000.00 EGP New Sale price From 42,636.00 EGP
      Unit price /  per 
      -31% vs new
    • iPhone 11 Pro Max

      iPhone 11 Pro Max

      iPhone 11 Pro Max

      Regular price 26,400.00 EGP
      Regular price New Sale price 26,400.00 EGP
      Unit price /  per 
    • iPhone 12

      iPhone 12

      -25% vs new

      iPhone 12

      Regular price From 20,900.00 EGP
      Regular price 28,000.00 EGP New Sale price From 20,900.00 EGP
      Unit price /  per 
      -25% vs new
    • iPhone 15 Pro Max

      iPhone 15 Pro Max

      -23% vs new

      iPhone 15 Pro Max

      Regular price From 59,175.00 EGP
      Regular price 77,000.00 EGP New Sale price From 59,175.00 EGP
      Unit price 59,175.00 EGP /  per  item
      -23% vs new
    • iPhone 12 Pro Max

      iPhone 12 Pro Max

      -24% vs new

      iPhone 12 Pro Max

      Regular price From 31,900.00 EGP
      Regular price 42,000.00 EGP New Sale price From 31,900.00 EGP
      Unit price /  per 
      -24% vs new
    • iPhone 14 Pro Max

      iPhone 14 Pro Max

      -21% vs new

      iPhone 14 Pro Max

      Regular price From 49,049.00 EGP
      Regular price 62,000.00 EGP New Sale price From 49,049.00 EGP
      Unit price 49,049.00 EGP /  per  item
      -21% vs new
    • iPhone 11 Pro

      iPhone 11 Pro

      iPhone 11 Pro

      Regular price 22,440.00 EGP
      Regular price New Sale price 22,440.00 EGP
      Unit price /  per 
    • iPhone 15 Plus

      iPhone 15 Plus

      -5% vs new

      iPhone 15 Plus

      Regular price From 50,600.00 EGP
      Regular price 53,000.00 EGP New Sale price From 50,600.00 EGP
      Unit price 50,600.00 EGP /  per  item
      -5% vs new
    • iPhone 16 Pro

      iPhone 16 Pro

      -12% vs new

      iPhone 16 Pro

      Regular price From 61,740.00 EGP
      Regular price 70,000.00 EGP New Sale price From 61,740.00 EGP
      Unit price 61,740.00 EGP /  per  item
      -12% vs new
    • iPhone 15 Pro

      iPhone 15 Pro

      -14% vs new

      iPhone 15 Pro

      Regular price From 52,714.00 EGP
      Regular price 61,000.00 EGP New Sale price From 52,714.00 EGP
      Unit price /  per 
      -14% vs new
    • 1
    • 2
    Black Mint
    info@blackmint.me
    +2 01009925253
    7049 Building, 17th St., Mokattam, Cairo

    Tax Registration No: 623-360-896

    About

    • About us
    • Our Impact
    • Mint Tech Blog
    • Hiring

    Products

    • iPhone
    • MacBook
    • Windows laptops

    Support

    • Contact Us
    • Shipping
    • Refund Policy
    • Payment
    • 01009925253
    • info@blackmint.me

    © 2026 Black Mint. All rights reserved.

    Powered by Meza Tech
    • Choosing a selection results in a full page refresh.
    • Opens in a new window.
    🛒 ${CONFIG.orderSummaryLabel}
    - items
    -
    ${CONFIG.cartTotalLabel}
    ✓ -

    ${CONFIG.popupTitle}

    Enter your phone number to proceed
    +91
    or
    Secured by PenguinCOD
    Code sent to your phone
    Didn't receive the OTP?
    or
    Secured by PenguinCOD
    ${CONFIG.fullPaymentTitle}
    ${CONFIG.fullPaymentSubtitle}
    -
    ${CONFIG.partialPaymentTitle}
    ${CONFIG.partialPaymentSubtitle}
    -
    -
    ${CONFIG.fullCodTitle}
    ${CONFIG.fullCodSubtitle}
    -
    `; overlayElement.appendChild(modal); document.body.appendChild(overlayElement); popupElement = modal; overlayElement.style.setProperty('--cod-primary', CONFIG.primaryColor); overlayElement.style.setProperty('--cod-accent', CONFIG.accentColor); overlayElement.style.setProperty('--cod-selected-border', CONFIG.selectedBorderColor); overlayElement.style.setProperty('--cod-popup-bg', CONFIG.popupBackgroundColor || '#ffffff'); overlayElement.style.setProperty('--cod-title-color', CONFIG.titleColor || '#1a1a1a'); overlayElement.style.setProperty('--cod-option-title', CONFIG.optionTitleColor || '#1a1a1a'); overlayElement.style.setProperty('--cod-option-subtitle', CONFIG.optionSubtitleColor || '#666666'); overlayElement.style.setProperty('--cod-selected-bg', CONFIG.selectedBackgroundColor || '#f8f8f8'); overlayElement.style.setProperty('--cod-unselected-border', CONFIG.unselectedBorderColor || '#e0e0e0'); overlayElement.style.setProperty('--cod-radio-selected', CONFIG.radioSelectedColor || '#000000'); overlayElement.style.setProperty('--cod-radio-unselected', CONFIG.radioUnselectedColor || '#cccccc'); overlayElement.style.setProperty('--cod-cta-bg', CONFIG.ctaBackgroundColor || '#5c2d2d'); overlayElement.style.setProperty('--cod-cta-text', CONFIG.ctaTextColor || '#ffffff'); overlayElement.style.setProperty('--cod-header-bg', CONFIG.popupHeaderBackground || '#374151'); overlayElement.style.setProperty('--cod-header-text', CONFIG.popupHeaderTextColor || '#ffffff'); overlayElement.style.setProperty('--cod-otp-input-bg', CONFIG.otpInputBackground || '#f5f5f5'); overlayElement.style.setProperty('--cod-otp-input-border', CONFIG.otpInputBorder || '#e0e0e0'); overlayElement.style.setProperty('--cod-otp-input-focus', CONFIG.otpInputFocus || '#000000'); overlayElement.style.setProperty('--cod-otp-resend', CONFIG.otpResendColor || '#4a90d9'); overlayElement.style.setProperty('--cod-otp-error', CONFIG.otpErrorColor || '#d32f2f'); attachPopupListeners(); popupReady = true; } function attachPopupListeners() { const optionFull = document.getElementById('codOptionFull'); const optionPartial = document.getElementById('codOptionPartial'); const optionFullCod = document.getElementById('codOptionFullCod'); const proceedBtn = document.getElementById('codProceed'); overlayElement.addEventListener('click', (e) => { const rect = popupElement.getBoundingClientRect(); const isInModal = ( e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top && e.clientY <= rect.bottom ); if (!isInModal && !isRedirecting) { hidePopup(); } }); overlayElement.addEventListener('cancel', (e) => { e.preventDefault(); if (!isRedirecting) hidePopup(); }); optionFull.addEventListener('click', () => selectOption('full')); optionPartial.addEventListener('click', () => selectOption('partial')); optionFullCod.addEventListener('click', () => selectOption('full_cod')); proceedBtn.addEventListener('click', proceedToCheckout); document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && overlayElement.open) { e.preventDefault(); hidePopup(); } }); attachOtpListeners(); } function attachOtpListeners() { const sendOtpBtn = document.getElementById('codSendOtp'); const phoneInput = document.getElementById('codPhoneInput'); const skipOtpBtn = document.getElementById('codSkipOtp'); const skipOtpBtnVerify = document.getElementById('codSkipOtpVerify'); const verifyOtpBtn = document.getElementById('codVerifyOtp'); const resendOtpBtn = document.getElementById('codResendOtp'); const editPhoneBtn = document.getElementById('codEditPhone'); const otpInputs = [ document.getElementById('codOtp1'), document.getElementById('codOtp2'), document.getElementById('codOtp3'), document.getElementById('codOtp4') ]; if (sendOtpBtn) { sendOtpBtn.addEventListener('click', handleSendOtp); } if (phoneInput) { phoneInput.addEventListener('keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); handleSendOtp(); } }); } if (skipOtpBtn) { skipOtpBtn.addEventListener('click', handleSkipOtp); } if (skipOtpBtnVerify) { skipOtpBtnVerify.addEventListener('click', handleSkipOtp); } if (verifyOtpBtn) { verifyOtpBtn.addEventListener('click', handleVerifyOtp); } if (resendOtpBtn) { resendOtpBtn.addEventListener('click', handleResendOtp); } if (editPhoneBtn) { editPhoneBtn.addEventListener('click', () => { showOtpScreen('phone'); }); } otpInputs.forEach((input, index) => { if (!input) return; input.addEventListener('input', (e) => { const value = e.target.value.replace(/[^0-9]/g, ''); e.target.value = value; if (value.length === 1 && index < 3) { otpInputs[index + 1].focus(); } if (index === 3 && value.length === 1) { const fullOtp = otpInputs.map(i => i.value).join(''); if (fullOtp.length === 4) { handleVerifyOtp(); } } }); input.addEventListener('keydown', (e) => { if (e.key === 'Backspace' && !e.target.value && index > 0) { otpInputs[index - 1].focus(); } }); input.addEventListener('paste', (e) => { e.preventDefault(); const pastedData = (e.clipboardData || window.clipboardData).getData('text'); const digits = pastedData.replace(/[^0-9]/g, '').slice(0, 4); digits.split('').forEach((digit, i) => { if (otpInputs[i]) { otpInputs[i].value = digit; } }); const lastFilledIndex = Math.min(digits.length - 1, 3); if (lastFilledIndex >= 0) { otpInputs[lastFilledIndex].focus(); } if (digits.length === 4) { handleVerifyOtp(); } }); }); } function validatePhone(phone) { const digitsOnly = phone.replace(/[^0-9]/g, ''); return digitsOnly.length >= CONFIG.minPhoneLength && digitsOnly.length <= CONFIG.maxPhoneLength; } function showOtpScreen(screen) { otpState.screen = screen; otpState.error = null; const phoneScreen = document.getElementById('codOtpPhoneScreen'); const verifyScreen = document.getElementById('codOtpVerifyScreen'); const paymentScreen = document.getElementById('codPaymentScreen'); const titleEl = document.getElementById('codTitle'); const proceedBtn = document.getElementById('codProceed'); const footerEl = document.querySelector('.cod-footer'); phoneScreen.classList.remove('cod-active'); verifyScreen.classList.remove('cod-active'); paymentScreen.classList.remove('cod-active'); document.getElementById('codPhoneError').style.display = 'none'; document.getElementById('codOtpError').style.display = 'none'; switch (screen) { case 'phone': titleEl.textContent = 'Verify Mobile Number'; phoneScreen.classList.add('cod-active'); footerEl.style.display = 'none'; const skipBtn = document.getElementById('codSkipOtp'); const divider = document.getElementById('codOtpDivider'); if (CONFIG.otpAllowSkip) { skipBtn.style.display = 'block'; skipBtn.textContent = CONFIG.otpSkipButtonText; divider.style.display = 'flex'; } else { skipBtn.style.display = 'none'; divider.style.display = 'none'; } setTimeout(() => { document.getElementById('codPhoneInput').focus(); }, 100); break; case 'otp': titleEl.textContent = 'Enter OTP'; verifyScreen.classList.add('cod-active'); footerEl.style.display = 'none'; const subtitle = document.getElementById('codOtpVerifySubtitle'); subtitle.textContent = `Code sent to ${otpState.maskedPhone}`; ['codOtp1', 'codOtp2', 'codOtp3', 'codOtp4'].forEach(id => { document.getElementById(id).value = ''; }); const skipBtnVerify = document.getElementById('codSkipOtpVerify'); const dividerVerify = document.getElementById('codOtpDividerVerify'); if (CONFIG.otpAllowSkip) { skipBtnVerify.style.display = 'block'; skipBtnVerify.textContent = CONFIG.otpSkipButtonText; dividerVerify.style.display = 'flex'; } else { skipBtnVerify.style.display = 'none'; dividerVerify.style.display = 'none'; } setTimeout(() => { document.getElementById('codOtp1').focus(); }, 100); break; case 'payment': titleEl.textContent = CONFIG.popupTitle; paymentScreen.classList.add('cod-active'); footerEl.style.display = 'block'; proceedBtn.disabled = true; selectedOption = null; break; } } async function handleSendOtp() { const phoneInput = document.getElementById('codPhoneInput'); const sendBtn = document.getElementById('codSendOtp'); const errorEl = document.getElementById('codPhoneError'); const phone = phoneInput.value.replace(/[^0-9]/g, ''); const countryCode = '91'; if (!validatePhone(phone)) { errorEl.textContent = 'Please enter a valid phone number'; errorEl.style.display = 'block'; return; } otpState.countryCode = countryCode; otpState.phone = phone; otpState.loading = true; sendBtn.dataset.originalText = sendBtn.textContent; sendBtn.textContent = 'Sending OTP...'; sendBtn.disabled = true; errorEl.style.display = 'none'; try { const response = await fetch(CONFIG.otpSendUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ phone: phone, countryCode: otpState.countryCode, shop: 'blackminteg.myshopify.com', cartTotal: CONFIG.cartTotal || null }) }); const data = await response.json(); if (data.success) { otpState.sessionId = data.sessionId; otpState.maskedPhone = data.maskedPhone || `+${otpState.countryCode}****${phone.slice(-4)}`; startResendCooldown(60); showOtpScreen('otp'); } else { if (data.error === 'RATE_LIMITED') { errorEl.textContent = `Too many attempts. Please try again in ${data.retryAfter || 60} seconds.`; errorEl.style.display = 'block'; } else { errorEl.textContent = data.message || 'Could not send verification code. Please try again.'; errorEl.style.display = 'block'; } } } catch (e) { errorEl.textContent = 'Network error. Please check your connection and try again.'; errorEl.style.display = 'block'; } finally { otpState.loading = false; sendBtn.textContent = sendBtn.dataset.originalText || 'Send Code'; sendBtn.disabled = false; } } async function handleVerifyOtp() { const verifyBtn = document.getElementById('codVerifyOtp'); const errorEl = document.getElementById('codOtpError'); const otp = ['codOtp1', 'codOtp2', 'codOtp3', 'codOtp4'] .map(id => document.getElementById(id).value) .join(''); if (otp.length !== 4) { errorEl.textContent = 'Please enter the 4-digit code.'; errorEl.style.display = 'block'; return; } otpState.loading = true; verifyBtn.dataset.originalText = verifyBtn.textContent; verifyBtn.textContent = 'Verifying...'; verifyBtn.disabled = true; errorEl.style.display = 'none'; try { const response = await fetch(CONFIG.otpVerifyUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ sessionId: otpState.sessionId, otp: otp, shop: 'blackminteg.myshopify.com' }) }); const data = await response.json(); if (data.success && data.verified) { otpState.verifiedPhone = data.phone; storeVerifiedPhone(data.phone, data.maskedPhone || otpState.maskedPhone); showVerifiedPhoneInHeader(data.phone); await setOtpVerifiedAttributes(data.phone); if (otpState.resendTimer) { clearInterval(otpState.resendTimer); } if (CONFIG.codEnabled || CONFIG.fullCodEnabled) { showOtpScreen('payment'); updatePopupUI(); } else { if (pendingFormContext?.isBuyNow && pendingFormContext?.form) { await buyNowOtpOnlyCheckout(pendingFormContext.form); } else { await redirectToCheckoutAfterOtp(); } } } else { if (data.error === 'OTP_EXPIRED') { errorEl.textContent = 'Code expired. Please request a new code.'; } else if (data.error === 'OTP_MISMATCH') { errorEl.textContent = 'Incorrect code. Please try again.'; } else if (data.error === 'MAX_ATTEMPTS') { errorEl.textContent = 'Too many incorrect attempts. Please request a new code.'; } else { errorEl.textContent = data.message || 'Verification failed. Please try again.'; } errorEl.style.display = 'block'; } } catch (e) { errorEl.textContent = 'Network error. Please try again.'; errorEl.style.display = 'block'; } finally { otpState.loading = false; verifyBtn.textContent = verifyBtn.dataset.originalText || 'Verify Code'; verifyBtn.disabled = false; } } async function handleResendOtp() { showOtpScreen('phone'); const phoneInput = document.getElementById('codPhoneInput'); if (phoneInput && otpState.phone) { phoneInput.value = otpState.phone; } const countrySelect = document.getElementById('codCountrySelect'); if (countrySelect && otpState.countryCode) { countrySelect.value = otpState.countryCode; } } async function handleSkipOtp() { await setOtpSkippedAttribute(); const savedContext = pendingFormContext; hidePopup(); if (savedContext?.isBuyNow && savedContext?.form) { try { const form = savedContext.form; const variantInput = form.querySelector('input[name="id"], select[name="id"]'); const variantId = variantInput ? variantInput.value : null; const quantity = savedContext.quantity || getFormQuantity(form); if (!variantId) { form.submit(); return; } await fetch('/cart/clear.js', { method: 'POST', headers: { 'Content-Type': 'application/json' } }); const response = await fetch('/cart/add.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ items: [{ id: parseInt(variantId), quantity: quantity }] }) }); if (!response.ok) { throw new Error('Failed to add item to cart'); } await fetch('/cart/update.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ attributes: { '_cod_payment_type': 'full' } }) }); window.location.href = '/checkout'; } catch (e) { savedContext.form.submit(); } } else { window.location.href = '/checkout'; } } function startResendCooldown(seconds) { otpState.resendCooldown = seconds; const resendBtn = document.getElementById('codResendOtp'); const cooldownEl = document.getElementById('codResendCooldown'); resendBtn.disabled = true; function updateCooldown() { if (otpState.resendCooldown > 0) { cooldownEl.textContent = ` (${otpState.resendCooldown}s)`; otpState.resendCooldown--; } else { cooldownEl.textContent = ''; resendBtn.disabled = false; clearInterval(otpState.resendTimer); } } updateCooldown(); otpState.resendTimer = setInterval(updateCooldown, 1000); } async function setOtpVerifiedAttributes(phone) { try { const response = await fetch('/cart/update.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ attributes: { '_otp_verified': 'true', '_otp_skipped': 'false', '_otp_verified_phone': phone, '_otp_verified_at': new Date().toISOString(), '_otp_status': 'verified' } }) }); const result = await response.json(); await new Promise(r => setTimeout(r, 150)); } catch (e) { } } async function setOtpSkippedAttribute() { try { await fetch('/cart/update.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ attributes: { '_otp_verified': 'false', '_otp_status': 'skipped' } }) }); } catch (e) { } } async function setOrderLimitExceededAttribute() { try { await fetch('/cart/update.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ attributes: { '_order_limit_exceeded': 'true' } }) }); } catch (e) { } } function redirectToCheckoutWithoutOtp() { hidePopup(); window.location.href = '/checkout'; } async function redirectToCheckoutAfterOtp() { hidePopup(); await new Promise(r => setTimeout(r, 300)); window.location.href = '/checkout'; } function closeThemeOverlays() { try { if (document.activeElement && document.activeElement !== document.body) { document.activeElement.blur(); } document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', code: 'Escape', keyCode: 27, which: 27, bubbles: true })); ['close', 'hide', 'hidden'].forEach(evt => { document.dispatchEvent(new CustomEvent(`cart:${evt}`)); document.dispatchEvent(new CustomEvent(`drawer:${evt}`)); }); } catch (e) { } } async function waitForPopupReady(maxWait = 3000) { if (popupReady) return true; const startTime = Date.now(); while (!popupReady && (Date.now() - startTime) < maxWait) { await new Promise(resolve => setTimeout(resolve, 50)); } return popupReady; } async function redirectToPrepaidCheckout() { try { const applicableRule = findApplicableRule(); const tierNumber = applicableRule ? (CONFIG.rules.indexOf(applicableRule) + 1) : 1; await fetch('/cart/update.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ attributes: { '_cod_payment_type': 'full', '_cod_tier': String(tierNumber) } }) }); } catch (e) { console.warn('[COD] Failed to set prepaid attributes, redirecting anyway:', e); } window.location.href = '/checkout'; } async function buyNowPrepaidCheckout(form) { try { const variantInput = form.querySelector('input[name="id"], select[name="id"]'); const variantId = variantInput ? variantInput.value : null; const quantity = pendingFormContext?.quantity || getFormQuantity(form); if (!variantId) { form.submit(); return; } await fetch('/cart/clear.js', { method: 'POST', headers: { 'Content-Type': 'application/json' } }); const response = await fetch('/cart/add.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ items: [{ id: parseInt(variantId), quantity: quantity }] }) }); if (!response.ok) { throw new Error('Failed to add item to cart'); } const applicableRule = findApplicableRule(); const tierNumber = applicableRule ? (CONFIG.rules.indexOf(applicableRule) + 1) : 1; await fetch('/cart/update.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ attributes: { '_cod_payment_type': 'full', '_cod_tier': String(tierNumber) } }) }); pendingFormContext = null; window.location.href = '/checkout'; } catch (e) { form.submit(); } } async function buyNowOtpOnlyCheckout(form) { try { const variantInput = form.querySelector('input[name="id"], select[name="id"]'); const variantId = variantInput ? variantInput.value : null; const quantity = pendingFormContext?.quantity || getFormQuantity(form); if (!variantId) { form.submit(); return; } await fetch('/cart/clear.js', { method: 'POST', headers: { 'Content-Type': 'application/json' } }); const response = await fetch('/cart/add.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ items: [{ id: parseInt(variantId), quantity: quantity }] }) }); if (!response.ok) { throw new Error('Failed to add item to cart'); } await new Promise(r => setTimeout(r, 200)); pendingFormContext = null; window.location.href = '/checkout'; } catch (e) { form.submit(); } } function wouldAnyCodOptionBeAvailable(cart) { let partialAvailable = false; if (CONFIG.codEnabled) { const applicableRule = findApplicableRule(); if (applicableRule) { if (eligibilityResult.partialPrepaidEligible) { partialAvailable = true; } } } let fullCodOptionAvailable = false; const applicableRule = findApplicableRule(); const fullCodRuleAvailable = isFullCodAvailableForRule(applicableRule); if (fullCodRuleAvailable) { if (eligibilityResult.fullCodEligible) { fullCodOptionAvailable = true; } } return partialAvailable || fullCodOptionAvailable; } async function showPopup() { const ready = await waitForPopupReady(); if (!ready) { console.warn('[COD] Popup not ready after waiting, proceeding to checkout'); window.location.href = '/checkout'; return; } closeThemeOverlays(); const cart = await fetchCartData(); if (!cart) { window.location.href = '/checkout'; return; } if (CONFIG.itemCount === 0) { window.location.href = '/cart'; return; } const hasCollectionRestrictions = CONFIG.partialPrepaidApplyTo === 'collections' || CONFIG.fullCodApplyTo === 'collections'; if (hasCollectionRestrictions) { const productIds = (cart.items || []).map(item => item.product_id); try { const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error('Eligibility check timeout')), 3000) ); await Promise.race([ checkCollectionEligibilityViaAPI(productIds), timeoutPromise ]); } catch (e) { console.warn('[COD] Eligibility check failed/timed out, showing popup anyway:', e.message); eligibilityResult = { partialPrepaidEligible: true, fullCodEligible: true, partialPrepaidReason: null, fullCodReason: null, checked: true }; } } else { eligibilityResult = { partialPrepaidEligible: true, fullCodEligible: true, partialPrepaidReason: null, fullCodReason: null, checked: true }; } if (CONFIG.orderLimitWarning === true || CONFIG.orderLimitExceeded === true) { if (CONFIG.orderLimitExceeded === true) { await setOrderLimitExceededAttribute(); } hidePopup(); await redirectToPrepaidCheckout(); return; } if (CONFIG.otpEnabled && !CONFIG.otpLimitExceeded) { const verifiedData = isPhoneVerified(); if (verifiedData) { otpState.verifiedPhone = verifiedData.phone; showVerifiedPhoneInHeader(verifiedData.phone); await setOtpVerifiedAttributes(verifiedData.phone); if (wouldAnyCodOptionBeAvailable(cart)) { updatePopupUI(); checkCodAvailability(cart); resetPaymentOptions(); overlayElement.showModal(); document.body.style.overflow = 'hidden'; popupElement.focus(); showOtpScreen('payment'); } else { await redirectToPrepaidCheckout(); return; } } else { if (!wouldAnyCodOptionBeAvailable(cart)) { await redirectToPrepaidCheckout(); return; } updatePopupUI(); checkCodAvailability(cart); resetPaymentOptions(); overlayElement.showModal(); document.body.style.overflow = 'hidden'; popupElement.focus(); hideVerifiedPhoneInHeader(); showOtpScreen('phone'); } } else { if (!wouldAnyCodOptionBeAvailable(cart)) { await redirectToPrepaidCheckout(); return; } updatePopupUI(); checkCodAvailability(cart); resetPaymentOptions(); overlayElement.showModal(); document.body.style.overflow = 'hidden'; popupElement.focus(); showOtpScreen('payment'); } function resetPaymentOptions() { selectedOption = null; document.getElementById('codOptionFull').classList.remove('cod-selected'); document.getElementById('codOptionPartial').classList.remove('cod-selected'); document.getElementById('codOptionFullCod').classList.remove('cod-selected'); document.getElementById('codProceed').disabled = true; } } async function showPopupForBuyNow(totalPrice, productData) { const ready = await waitForPopupReady(); if (!ready) { console.warn('[COD] Popup not ready after waiting, proceeding to checkout'); window.location.href = '/checkout'; return; } closeThemeOverlays(); CONFIG.cartTotal = totalPrice; CONFIG.itemCount = pendingFormContext?.quantity || 1; const productId = productData?.productId || null; const buyNowCart = { items: productId ? [{ product_id: productId }] : [] }; const hasCollectionRestrictions = CONFIG.partialPrepaidApplyTo === 'collections' || CONFIG.fullCodApplyTo === 'collections'; if (productId && hasCollectionRestrictions) { try { const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error('Eligibility check timeout')), 3000) ); await Promise.race([ checkCollectionEligibilityViaAPI([productId]), timeoutPromise ]); } catch (e) { console.warn('[COD] Buy Now: Eligibility check failed/timed out, showing popup anyway:', e.message); eligibilityResult = { partialPrepaidEligible: true, fullCodEligible: true, partialPrepaidReason: null, fullCodReason: null, checked: true }; } } else { eligibilityResult = { partialPrepaidEligible: true, fullCodEligible: true, partialPrepaidReason: null, fullCodReason: null, checked: true }; } function resetBuyNowPaymentOptions() { selectedOption = null; document.getElementById('codOptionFull').classList.remove('cod-selected'); document.getElementById('codOptionPartial').classList.remove('cod-selected'); document.getElementById('codOptionFullCod').classList.remove('cod-selected'); document.getElementById('codProceed').disabled = true; } if (CONFIG.orderLimitWarning === true || CONFIG.orderLimitExceeded === true) { if (CONFIG.orderLimitExceeded === true) { await setOrderLimitExceededAttribute(); } const buyNowForm = pendingFormContext?.form; // Save before hidePopup clears pendingFormContext hidePopup(); if (buyNowForm) { await buyNowPrepaidCheckout(buyNowForm); } else { await redirectToPrepaidCheckout(); } return; } if (CONFIG.otpEnabled && !CONFIG.otpLimitExceeded) { const verifiedData = isPhoneVerified(); if (verifiedData) { otpState.verifiedPhone = verifiedData.phone; await setOtpVerifiedAttributes(verifiedData.phone); if (wouldAnyCodOptionBeAvailable(buyNowCart)) { updatePopupUI(); checkCodAvailability(buyNowCart); resetBuyNowPaymentOptions(); overlayElement.showModal(); document.body.style.overflow = 'hidden'; popupElement.focus(); showOtpScreen('payment'); } else { if (pendingFormContext?.form) { await buyNowPrepaidCheckout(pendingFormContext.form); } else { await redirectToPrepaidCheckout(); } return; } } else { if (!wouldAnyCodOptionBeAvailable(buyNowCart)) { if (pendingFormContext?.form) { await buyNowPrepaidCheckout(pendingFormContext.form); } else { await redirectToPrepaidCheckout(); } return; } updatePopupUI(); checkCodAvailability(buyNowCart); resetBuyNowPaymentOptions(); overlayElement.showModal(); document.body.style.overflow = 'hidden'; popupElement.focus(); showOtpScreen('phone'); } } else { if (!wouldAnyCodOptionBeAvailable(buyNowCart)) { if (pendingFormContext?.form) { await buyNowPrepaidCheckout(pendingFormContext.form); } else { await redirectToPrepaidCheckout(); } return; } updatePopupUI(); checkCodAvailability(buyNowCart); resetBuyNowPaymentOptions(); overlayElement.showModal(); document.body.style.overflow = 'hidden'; popupElement.focus(); showOtpScreen('payment'); } } function hidePopup() { if (overlayElement.open) { overlayElement.close(); } document.body.style.overflow = ''; selectedOption = null; pendingFormContext = null; otpState.screen = 'phone'; otpState.phone = ''; otpState.sessionId = null; otpState.error = null; otpState.loading = false; if (otpState.resendTimer) { clearInterval(otpState.resendTimer); otpState.resendTimer = null; } otpState.resendCooldown = 0; } function showEligibilityLoading(show) { const optionPartial = document.getElementById('codOptionPartial'); const optionFullCod = document.getElementById('codOptionFullCod'); if (show) { if (CONFIG.partialPrepaidApplyTo === 'collections' && optionPartial) { optionPartial.classList.add('cod-checking'); } if (CONFIG.fullCodApplyTo === 'collections' && optionFullCod) { optionFullCod.classList.add('cod-checking'); } } else { if (optionPartial) { optionPartial.classList.remove('cod-checking'); } if (optionFullCod) { optionFullCod.classList.remove('cod-checking'); } } } function updatePopupUI() { document.getElementById('codTitle').textContent = CONFIG.popupTitle; document.getElementById('codFullTitle').textContent = CONFIG.fullPaymentTitle; document.getElementById('codFullDesc').textContent = CONFIG.fullPaymentSubtitle; document.getElementById('codPartialTitle').textContent = CONFIG.partialPaymentTitle; document.getElementById('codPartialDesc').textContent = CONFIG.partialPaymentSubtitle; document.getElementById('codFullCodTitle').textContent = CONFIG.fullCodTitle; document.getElementById('codFullCodDesc').textContent = CONFIG.fullCodSubtitle; document.getElementById('codProceed').textContent = CONFIG.proceedButtonText; overlayElement.style.setProperty('--cod-primary', CONFIG.primaryColor); overlayElement.style.setProperty('--cod-accent', CONFIG.accentColor); overlayElement.style.setProperty('--cod-selected-border', CONFIG.selectedBorderColor); overlayElement.style.setProperty('--cod-popup-bg', CONFIG.popupBackgroundColor || '#ffffff'); overlayElement.style.setProperty('--cod-title-color', CONFIG.titleColor || '#1a1a1a'); overlayElement.style.setProperty('--cod-option-title', CONFIG.optionTitleColor || '#1a1a1a'); overlayElement.style.setProperty('--cod-option-subtitle', CONFIG.optionSubtitleColor || '#666666'); overlayElement.style.setProperty('--cod-selected-bg', CONFIG.selectedBackgroundColor || '#f8f8f8'); overlayElement.style.setProperty('--cod-unselected-border', CONFIG.unselectedBorderColor || '#e0e0e0'); overlayElement.style.setProperty('--cod-radio-selected', CONFIG.radioSelectedColor || '#000000'); overlayElement.style.setProperty('--cod-radio-unselected', CONFIG.radioUnselectedColor || '#cccccc'); overlayElement.style.setProperty('--cod-cta-bg', CONFIG.ctaBackgroundColor || '#5c2d2d'); overlayElement.style.setProperty('--cod-cta-text', CONFIG.ctaTextColor || '#ffffff'); overlayElement.style.setProperty('--cod-header-bg', CONFIG.popupHeaderBackground || '#1a1a2e'); overlayElement.style.setProperty('--cod-header-text', CONFIG.popupHeaderTextColor || '#ffffff'); updateHeaderSummary(); updateOptionAmounts(); } function updateHeaderSummary() { const headerTotal = document.getElementById('codHeaderTotal'); const headerItems = document.getElementById('codHeaderItems'); if (headerTotal) headerTotal.textContent = formatMoney(CONFIG.cartTotal); if (headerItems) headerItems.textContent = CONFIG.itemCount + ' ' + CONFIG.cartItemsLabel; } function showVerifiedPhoneInHeader(phone) { const verifiedRow = document.getElementById('codHeaderVerified'); const verifiedPhone = document.getElementById('codHeaderVerifiedPhone'); if (verifiedRow && verifiedPhone) { const formatted = phone.length > 5 ? '+' + phone.slice(0,2) + ' ' + phone.slice(2,7) + ' ' + phone.slice(7) : '+' + phone; verifiedPhone.textContent = formatted; verifiedRow.style.display = 'flex'; } } function hideVerifiedPhoneInHeader() { const verifiedRow = document.getElementById('codHeaderVerified'); if (verifiedRow) verifiedRow.style.display = 'none'; } function calculatePrepaidDiscount() { if (!CONFIG.prepaidDiscountEnabled) { return { discountAmount: 0, finalAmount: CONFIG.cartTotal }; } const rule = findApplicableRule(); if (!rule || !rule.prepaidDiscountValue || rule.prepaidDiscountValue <= 0) { return { discountAmount: 0, finalAmount: CONFIG.cartTotal }; } let discountAmount = 0; if (rule.prepaidDiscountType === 'percentage') { discountAmount = (CONFIG.cartTotal * rule.prepaidDiscountValue) / 100; } else { discountAmount = Math.min(rule.prepaidDiscountValue, CONFIG.cartTotal); } const finalAmount = CONFIG.cartTotal - discountAmount; return { discountAmount, finalAmount }; } function calculatePartialPrepaidDiscount() { const rule = findApplicableRule(); if (!rule || !rule.partialPrepaidDiscountValue || rule.partialPrepaidDiscountValue <= 0) { return { discountAmount: 0, depositDiscount: 0, codDiscount: 0 }; } let depositAmount = 0; if (rule.chargeType === 'percentage') { depositAmount = (CONFIG.cartTotal * rule.chargeValue) / 100; } else { depositAmount = Math.min(rule.chargeValue, CONFIG.cartTotal); } const codAmount = CONFIG.cartTotal - depositAmount; let depositDiscount = 0; let codDiscount = 0; if (rule.partialPrepaidDiscountType === 'percentage') { depositDiscount = (depositAmount * rule.partialPrepaidDiscountValue) / 100; codDiscount = (codAmount * rule.partialPrepaidDiscountValue) / 100; } else { const totalDiscount = Math.min(rule.partialPrepaidDiscountValue, CONFIG.cartTotal); const depositRatio = depositAmount / CONFIG.cartTotal; depositDiscount = totalDiscount * depositRatio; codDiscount = totalDiscount * (1 - depositRatio); } const totalDiscount = depositDiscount + codDiscount; return { discountAmount: totalDiscount, depositDiscount, codDiscount }; } function calculateCodFee() { if (!CONFIG.codFeeEnabled) { return 0; } const rule = findApplicableRule(); if (!rule || !rule.codFeeAmount || rule.codFeeAmount <= 0) { return 0; } return parseFloat(rule.codFeeAmount) || 0; } function calculateFullCodFee() { if (!CONFIG.fullCodFeeEnabled) { return 0; } const rule = findApplicableRule(); if (!rule || !rule.fullCodFeeAmount || rule.fullCodFeeAmount <= 0) { return 0; } return parseFloat(rule.fullCodFeeAmount) || 0; } function isFullCodAvailableForRule(rule) { return CONFIG.fullCodEnabled && rule && rule.fullCodEnabled; } function updateOptionAmounts() { const deposit = calculateDeposit(); const codFee = calculateCodFee(); const remaining = CONFIG.cartTotal - deposit; const partialPrepaidDiscount = calculatePartialPrepaidDiscount(); const partialNowEl = document.getElementById('codPartialNowValue'); const partialCodEl = document.getElementById('codPartialCodValue'); const partialFeeEl = document.getElementById('codPartialFeeNote'); if (partialNowEl && partialCodEl) { const depositAfterDiscount = deposit - partialPrepaidDiscount.depositDiscount; const displayNowAmount = depositAfterDiscount + codFee; const remainingAfterDiscount = remaining - partialPrepaidDiscount.codDiscount; partialNowEl.textContent = formatMoney(displayNowAmount) + ' ' + CONFIG.partialDepositLabel; partialCodEl.textContent = '+' + formatMoney(remainingAfterDiscount) + ' ' + CONFIG.partialCodLabel; } if (partialFeeEl) { if (codFee > 0) { partialFeeEl.textContent = CONFIG.partialCodFeeLabel + ' ' + formatMoney(codFee); partialFeeEl.style.display = 'block'; } else { partialFeeEl.style.display = 'none'; } } const partialDiscountBadgeEl = document.getElementById('codPartialDiscountBadge'); if (partialDiscountBadgeEl) { if (partialPrepaidDiscount.discountAmount > 0) { partialDiscountBadgeEl.textContent = '-' + formatMoney(partialPrepaidDiscount.discountAmount) + ' ' + CONFIG.partialPrepaidDiscountLabel; partialDiscountBadgeEl.style.display = 'block'; } else { partialDiscountBadgeEl.style.display = 'none'; } } const { discountAmount, finalAmount } = calculatePrepaidDiscount(); const fullAmountEl = document.getElementById('codFullAmountValue'); const discountBadgeEl = document.getElementById('codDiscountBadge'); if (fullAmountEl) { fullAmountEl.textContent = formatMoney(finalAmount); } if (discountBadgeEl) { if (discountAmount > 0) { discountBadgeEl.textContent = 'Includes ' + formatMoney(discountAmount) + ' OFF'; discountBadgeEl.style.display = 'block'; } else { discountBadgeEl.style.display = 'none'; } } const fullCodFee = calculateFullCodFee(); const fullCodTotal = CONFIG.cartTotal + fullCodFee; const fullCodValueEl = document.getElementById('codFullCodValue'); const fullCodFeeEl = document.getElementById('codFullCodFeeNote'); const fullCodOptionEl = document.getElementById('codOptionFullCod'); const applicableRule = findApplicableRule(); const fullCodAvailable = isFullCodAvailableForRule(applicableRule); if (fullCodOptionEl) { fullCodOptionEl.style.display = fullCodAvailable ? 'flex' : 'none'; } if (fullCodValueEl) { fullCodValueEl.textContent = formatMoney(fullCodTotal) + ' ' + CONFIG.fullCodLabel; } if (fullCodFeeEl) { if (fullCodFee > 0) { fullCodFeeEl.textContent = CONFIG.fullCodFeeLabel + ' ' + formatMoney(fullCodFee); fullCodFeeEl.style.display = 'block'; } else { fullCodFeeEl.style.display = 'none'; } } } function checkCodAvailability(cart) { const optionPartial = document.getElementById('codOptionPartial'); const partialUnavailableEl = document.getElementById('codPartialUnavailable'); const optionFullCod = document.getElementById('codOptionFullCod'); const fullCodUnavailableEl = document.getElementById('codFullCodUnavailable'); const cartData = cart || { items: currentCartItems }; if (!CONFIG.codEnabled) { codAvailable = false; optionPartial.style.display = 'none'; } else { optionPartial.style.display = 'flex'; const applicableRule = findApplicableRule(); if (!applicableRule) { codAvailable = false; const rules = CONFIG.rules || []; const sortedRules = [...rules].sort((a, b) => (a.minCartValue || 0) - (b.minCartValue || 0)); if (sortedRules.length > 0) { const firstRule = sortedRules[0]; const lastRule = sortedRules[sortedRules.length - 1]; if (CONFIG.cartTotal < (firstRule.minCartValue || 0)) { partialUnavailableEl.textContent = 'Available for orders above ' + formatMoney(firstRule.minCartValue); } else if (lastRule.maxCartValue != null && CONFIG.cartTotal > lastRule.maxCartValue) { partialUnavailableEl.textContent = 'Not available for orders above ' + formatMoney(lastRule.maxCartValue); } else { partialUnavailableEl.textContent = 'Not available for this cart value'; } } else { partialUnavailableEl.textContent = 'Not configured'; } optionPartial.classList.add('cod-disabled'); partialUnavailableEl.style.display = 'block'; } else { const partialEligibility = checkCollectionEligibility( CONFIG.partialPrepaidApplyTo, CONFIG.partialPrepaidCollectionIds, cartData, true ); if (!partialEligibility.eligible) { codAvailable = false; optionPartial.classList.add('cod-disabled'); partialUnavailableEl.textContent = partialEligibility.reason || 'Not available for selected products'; partialUnavailableEl.style.display = 'block'; } else { codAvailable = true; optionPartial.classList.remove('cod-disabled'); partialUnavailableEl.style.display = 'none'; } } } const applicableRule = findApplicableRule(); let fullCodRuleAvailable = isFullCodAvailableForRule(applicableRule); if (optionFullCod) { if (!fullCodRuleAvailable) { fullCodAvailable = false; optionFullCod.style.display = 'none'; } else { const fullCodEligibility = checkCollectionEligibility( CONFIG.fullCodApplyTo, CONFIG.fullCodCollectionIds, cartData, false ); if (!fullCodEligibility.eligible) { fullCodAvailable = false; optionFullCod.style.display = 'flex'; optionFullCod.classList.add('cod-disabled'); if (fullCodUnavailableEl) { fullCodUnavailableEl.textContent = fullCodEligibility.reason || 'Not available for selected products'; fullCodUnavailableEl.style.display = 'block'; } } else { fullCodAvailable = true; optionFullCod.style.display = 'flex'; optionFullCod.classList.remove('cod-disabled'); if (fullCodUnavailableEl) { fullCodUnavailableEl.style.display = 'none'; } } } } } function selectOption(option) { if (option === 'partial' && !codAvailable) return; if (option === 'full_cod' && !fullCodAvailable) return; selectedOption = option; const optionFull = document.getElementById('codOptionFull'); const optionPartial = document.getElementById('codOptionPartial'); const optionFullCod = document.getElementById('codOptionFullCod'); const proceedBtn = document.getElementById('codProceed'); optionFull.classList.toggle('cod-selected', option === 'full'); optionPartial.classList.toggle('cod-selected', option === 'partial'); optionFullCod.classList.toggle('cod-selected', option === 'full_cod'); proceedBtn.disabled = false; } async function proceedToCheckout() { if (!selectedOption) return; const paymentOption = selectedOption; const proceedBtn = document.getElementById('codProceed'); proceedBtn.disabled = true; proceedBtn.textContent = 'Redirecting...'; isRedirecting = true; try { if (pendingFormContext && pendingFormContext.isBuyNow) { const { form } = pendingFormContext; const variantInput = form.querySelector('input[name="id"], select[name="id"]'); const variantId = variantInput ? variantInput.value : null; const quantity = pendingFormContext.quantity || getFormQuantity(form); if (!variantId) { window.location.href = '/checkout'; return; } await fetch('/cart/clear.js', { method: 'POST', headers: { 'Content-Type': 'application/json' } }); const cartItem = { id: parseInt(variantId), quantity: quantity }; if (paymentOption === 'partial') { cartItem.properties = { '_cod_payment_type': 'partial' }; } else { } const response = await fetch('/cart/add.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ items: [cartItem] }) }); if (!response.ok) { throw new Error('Failed to add item to cart'); } const applicableRule = findApplicableRule(); const tierNumber = applicableRule ? (CONFIG.rules.indexOf(applicableRule) + 1) : 1; await fetch('/cart/update.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ attributes: { '_cod_payment_type': paymentOption, '_cod_tier': String(tierNumber) } }) }); pendingFormContext = null; window.location.href = '/checkout'; } else { const applicableRule = findApplicableRule(); const tierNumber = applicableRule ? (CONFIG.rules.indexOf(applicableRule) + 1) : 1; if (paymentOption === 'partial') { await markEffectivePrices(); } await fetch('/cart/update.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ attributes: { '_cod_payment_type': paymentOption, '_cod_tier': String(tierNumber) } }) }); window.location.href = '/checkout'; } } catch (e) { isRedirecting = false; window.location.href = '/checkout'; } } async function markEffectivePrices() { try { const cartResp = await fetch('/cart.json'); const cart = await cartResp.json(); const allItems = cart.items || []; const bundleTitle = (CONFIG && CONFIG.codBundleTitle) || 'Part Payment'; const items = allItems.filter(item => item.title !== bundleTitle); const toUpdate = items.filter(item => { const isFree = item.final_price === 0; const isDiscounted = item.final_price < item.price && item.final_price > 0; const shouldMarkEffective = isFree || isDiscounted; const effectiveUnitPrice = (item.final_price / 100).toFixed(2); const currentEffective = item.properties && item.properties['_cod_effective_price']; const currentSkip = item.properties && item.properties['_cod_skip']; return shouldMarkEffective ? currentEffective !== effectiveUnitPrice : (currentEffective !== undefined || currentSkip === 'true'); }); if (toUpdate.length === 0) return; await Promise.all(toUpdate.map(item => { const isFree = item.final_price === 0; const isDiscounted = item.final_price < item.price && item.final_price > 0; const shouldMarkEffective = isFree || isDiscounted; const effectiveUnitPrice = (item.final_price / 100).toFixed(2); const newProperties = { ...item.properties }; delete newProperties['_cod_skip']; if (shouldMarkEffective) { newProperties['_cod_effective_price'] = effectiveUnitPrice; } else { delete newProperties['_cod_effective_price']; } return fetch('/cart/change.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: item.key, quantity: item.quantity, properties: newProperties }) }); })); } catch (e) { } } function isAcceleratedCheckout(element) { if (!element) return false; let buyNowCheck = element; while (buyNowCheck && buyNowCheck !== document.body) { if (buyNowCheck.tagName && buyNowCheck.tagName.toLowerCase() === 'shopify-buy-it-now-button') {; return false; } buyNowCheck = buyNowCheck.parentElement; } let current = element; while (current && current !== document.body) { if (current.matches && current.matches( '.shopify-payment-button, ' + '[data-shopify="payment-button"], ' + '.dynamic-checkout__buttons, ' + '.additional-checkout-buttons, ' + '.shopify-cleanslate, ' + '[data-shopify-buttoncontainer], ' + '.accelerated-checkout-button' )) {; return true; } current = current.parentElement; } return false; } function isCheckoutClick(element) { if (!element) return false; const tagName = element.tagName; const isClickableElement = tagName === 'BUTTON' || tagName === 'INPUT' || tagName === 'A' || element.getAttribute('role') === 'button'; if (isClickableElement) { const text = (element.textContent || '').toLowerCase().trim(); const hasBuyNowText = text.length < 50 && text.includes('buy') && text.includes('now'); if (hasBuyNowText) { const productForm = element.closest('form'); if (productForm && isProductForm(productForm)) { element._codProductForm = productForm; return true; } return true; } } if (element.tagName && element.tagName.toLowerCase() === 'shopify-buy-it-now-button') {; return true; } if (isAcceleratedCheckout(element)) {; return false; } let current = element; while (current && current !== document.body) { if (current.classList && current.classList.contains('cod-dialog')) { return false; } if (current.tagName === 'A') { const href = current.getAttribute('href') || ''; if (isCheckoutUrl(href)) { return true; } } if (current.tagName === 'BUTTON' || current.tagName === 'INPUT') { if (current.name === 'checkout') { return true; } if (current.formAction && isCheckoutUrl(current.formAction)) { return true; } } if (current.tagName === 'A' || current.tagName === 'BUTTON') { const text = current.textContent || ''; if (isCheckoutText(text)) { const form = current.closest('form'); if (!form || !isAddToCartForm(form)) { return true; } } } const className = current.className; const classes = (typeof className === 'string' ? className : String(className || '')).toLowerCase(); if (classes.includes('checkout') && !classes.includes('continue') && !classes.includes('guest') && !classes.includes('dynamic') && !classes.includes('accelerated') && !classes.includes('shopify-payment') && (current.tagName === 'A' || current.tagName === 'BUTTON')) { return true; } if (current.matches && current.matches('[data-checkout], [data-action="checkout"], [data-cart-checkout]')) { return true; } current = current.parentElement; } const form = element.closest('form'); if (form && !isAddToCartForm(form)) { if (isCheckoutUrl(form.action)) { return true; } if ((form.action || '').toLowerCase().includes('/cart')) { const clickedBtn = element.closest('button, input[type="submit"]'); if (clickedBtn && clickedBtn.name === 'checkout') { return true; } } } return false; } async function interceptClick(e) { if (e.target.closest('#codDialog') || e.target.closest('.cod-dialog')) { return; } if (overlayElement && overlayElement.open) { return; } if (isCheckoutClick(e.target)) { e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); const productForm = e.target._codProductForm || e.target.closest('form'); if (productForm && isProductForm(productForm)) { const quantity = getFormQuantity(productForm); const productPrice = await getProductPrice(productForm); if (productPrice) { let productId = null; if (window.ShopifyAnalytics?.meta?.product?.id) { productId = window.ShopifyAnalytics.meta.product.id; } pendingFormContext = { form: productForm, submitter: e.target, isBuyNow: true, quantity: quantity, productId: productId }; showPopupForBuyNow(productPrice * quantity, { productId }); return false; } } setTimeout(() => { showPopup(); }, 50); return false; } } function interceptForm(e) { const form = e.target; if (!form || isAddToCartForm(form)) return; if (form.closest('#codDialog') || form.closest('.cod-dialog')) return; if (overlayElement && overlayElement.open) return; if (isAcceleratedCheckout(form)) { return; } if (isCheckoutUrl(form.action)) { e.preventDefault(); e.stopPropagation(); setTimeout(() => showPopup(), 50); return false; } if ((form.action || '').toLowerCase().includes('/cart')) { const submitter = e.submitter; if (submitter && submitter.name === 'checkout') { e.preventDefault(); e.stopPropagation(); setTimeout(() => showPopup(), 50); return false; } } } async function interceptProductFormSubmit(e) { const form = e.target; const submitter = e.submitter; if (!isProductForm(form)) { return; } if (overlayElement && overlayElement.open) { return; } if (form.dataset.codResubmit === 'true') { form.dataset.codResubmit = 'false'; return; } if (isBuyNowSubmitter(submitter)) { e.preventDefault(); e.stopPropagation(); const quantity = getFormQuantity(form); const productPrice = await getProductPrice(form); if (!productPrice) { return; } let productId = null; if (window.ShopifyAnalytics?.meta?.product?.id) { productId = window.ShopifyAnalytics.meta.product.id; } pendingFormContext = { form: form, submitter: submitter, isBuyNow: true, productPrice: productPrice, quantity: quantity, productId: productId }; showPopupForBuyNow(productPrice * quantity, { productId }); return false; } } function attachShadowDomInterceptors() { const hooked = new WeakSet(); function hook(el) { if (!el.shadowRoot || hooked.has(el)) return; hooked.add(el); el.shadowRoot.addEventListener('click', interceptClick, true); el.shadowRoot.addEventListener('submit', interceptForm, true); } const sel = 'shadow-dom-container, gokwik-cart, [id*="gokwik"], [class*="gokwik"]'; document.querySelectorAll(sel).forEach(hook); new MutationObserver(() => document.querySelectorAll(sel).forEach(hook)) .observe(document.body, { childList: true, subtree: true }); } function interceptBuyItNowButtons() { const hooked = new WeakSet(); function hookBuyItNow(btn) { if (hooked.has(btn)) return; hooked.add(btn); const overlay = document.createElement('div'); overlay.setAttribute('data-cod-buy-now-overlay', 'true'); overlay.style.cssText = 'position:fixed;z-index:2147483646;cursor:pointer;background:transparent;display:none;'; document.body.appendChild(overlay); function positionOverlay() { const targetEl = btn.querySelector('.shopify-payment-button__button') || btn.querySelector('button') || btn; const rect = targetEl.getBoundingClientRect(); if (!rect.width || rect.height < 25) { overlay.style.display = 'none'; return; } overlay.style.display = ''; overlay.style.top = rect.top + 'px'; overlay.style.left = rect.left + 'px'; overlay.style.width = rect.width + 'px'; overlay.style.height = rect.height + 'px'; } positionOverlay(); window.addEventListener('scroll', positionOverlay, { passive: true }); window.addEventListener('resize', positionOverlay, { passive: true }); if (window.ResizeObserver) { new ResizeObserver(positionOverlay).observe(btn); } [100, 300, 700, 1500, 3000].forEach(function(d) { setTimeout(positionOverlay, d); }); overlay.addEventListener('click', async function(e) { e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); if (overlayElement && overlayElement.open) return; const productForm = btn.closest('form'); if (productForm && isProductForm(productForm)) { const quantity = getFormQuantity(productForm); const productPrice = await getProductPrice(productForm); if (productPrice) { let productId = null; if (window.ShopifyAnalytics && window.ShopifyAnalytics.meta && window.ShopifyAnalytics.meta.product) { productId = window.ShopifyAnalytics.meta.product.id; } pendingFormContext = { form: productForm, submitter: btn, isBuyNow: true, productId: productId, quantity: quantity }; showPopupForBuyNow(productPrice * quantity, { productId: productId }); return; } } setTimeout(function() { showPopup(); }, 50); }); } function scanAndHook() { document.querySelectorAll('shopify-buy-it-now-button').forEach(hookBuyItNow); } scanAndHook(); new MutationObserver(scanAndHook).observe(document.body, { childList: true, subtree: true }); } async function init() { document.addEventListener('click', interceptClick, true); document.addEventListener('submit', interceptForm, true); document.addEventListener('submit', interceptProductFormSubmit, true); attachShadowDomInterceptors(); interceptBuyItNowButtons(); await loadConfig(); createPopup(); clearStaleCodAttribute().then(reloading => { if (reloading) { } }).catch(e => { }); window.addEventListener('pageshow', async (event) => { if (overlayElement && overlayElement.open) { overlayElement.close(); } document.body.style.overflow = ''; pendingFormContext = null; if (event.persisted) { await clearStaleCodAttribute(); } }); window.addEventListener('popstate', async () => { setTimeout(async () => { await clearStaleCodAttribute(); }, 100); }); document.addEventListener('visibilitychange', async () => { if (document.visibilityState === 'visible' && !window.location.pathname.includes('/checkout')) { await clearStaleCodAttribute(); } }); } let initRun = false; if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { if (!initRun) { initRun = true; init(); } }); } else { if (!initRun) { initRun = true; init(); } } })();
    -->

    Certified Minted

    What makes our devices special

    Built From Originals

    Every Minted device starts as a genuine, premium product, then gets professionally restored with factory standards in our labs

    Protected for 24 Months

    Every Minted device comes with a full 24-month warranty and 14-day free returns. We take the risk. Not you.

    Tested for Real Performance

    Every device goes through 70+ checks battery, speed, camera, screen, and more.

    Switch Without Stress

    Trade your old device and step into your next one without starting from zero