Paso final

Finalizar pedido

Completa tus datos y confirma tu compra. Te contactaremos por WhatsApp antes de despachar.

Compra segura

Tus datos protegidos

Envíos a todo el país

SD e interior

Calidad premium

Productos seleccionados

Atención 24/7

Confirmación por WhatsApp

1

Datos de entrega

Completa tu información

Escribe el código de la persona que te recomendó. Si llegaste desde su enlace, aparecerá automáticamente.

Método de pago

Confirmaremos disponibilidad, descuentos y total final antes de despachar tu pedido.

Ningún pedido se despacha sin confirmación previa por WhatsApp.

`; } window.amparoDownloadFacturaCheckout = function () { const ctx = amparoCheckoutContext(); amparoDownloadFile(`factura-amparo-${amparoFileName(ctx.orderId)}.html`, amparoInvoiceHtml(ctx), "text/html;charset=utf-8"); }; window.amparoDownloadOrdenCheckout = function () { const ctx = amparoCheckoutContext(); amparoDownloadFile(`orden-amparo-${amparoFileName(ctx.orderId)}.txt`, amparoCheckoutText(ctx), "text/plain;charset=utf-8"); }; window.amparoSendEmailCheckout = function () { const ctx = amparoCheckoutContext(); const subject = `Orden Amparo Comercial ${ctx.orderId || ""}`.trim(); window.location.href = `mailto:?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(amparoCheckoutText(ctx))}`; }; function renderSuccessCard(snapshot, apiResult) { if (!successEl) return; const orderId = (apiResult && (apiResult.orderId || apiResult._id || apiResult.id)) ? (apiResult.orderId || apiResult._id || apiResult.id) : null; const pairs = snapshot?.totals?.totalPairs ?? 0; const subtotal = snapshot?.totals?.subtotal ?? 0; const discountText = snapshot?.totals?.discountLabel || " "; const shipping = snapshot?.totals?.shippingAmount ?? SHIPPING_INSIDE_SD; const total = snapshot?.totals?.totalWithShipping ?? ((snapshot?.totals?.total ?? 0) + shipping); const customerName = snapshot?.customerName || ""; const customerPhone = snapshot?.customerPhone || ""; const customerAddress = snapshot?.customerAddress || ""; const pm = snapshot?.paymentMethod || "contraentrega"; const items = Array.isArray(snapshot?.cart) ? snapshot.cart : []; const topItems = items.slice(0, 4); const itemsHtml = topItems.map((it) => { const qty = Number(it.quantity || 0); const size = it.size || "-"; const color = (it.color ?? null); const meta = `${color ? ("Color " + escapeHTML(color) + " • ") : ""}Talla ${escapeHTML(size)} • ${qty} par(es)`; return `
${it.code ? `

Código: ${escapeHTML(it.code)}

` : ""}

${escapeHTML(it.name || "Producto")}

${meta}

${localFormatCurrency((Number(it.price || 0) * qty) || 0)}
`; }).join(""); const extraCount = Math.max(0, items.length - topItems.length); window.__amparoLastCheckoutSuccess = { snapshot, apiResult }; successEl.innerHTML = `

¡Pedido recibido!

Hemos recibido tu pedido${orderId ? ` (#${escapeHTML(orderId)})` : ""}. Te contactaremos por WhatsApp para confirmar disponibilidad y total final antes de despachar.

Puedes descargar o compartir tu factura y orden antes de volver a la tienda.

Cliente

${escapeHTML(customerName || " ")}

${escapeHTML(customerPhone || " ")}

Método de pago

${paymentLabel(pm)}

Dirección

${escapeHTML(customerAddress || " ")}

Resumen

${itemsHtml || '

'} ${extraCount > 0 ? `

+ ${extraCount} producto(s) más

` : ""}
Subtotal ${localFormatCurrency(subtotal)}
Descuento ${discountText}
Pares ${pairs}
Envío ${localFormatCurrency(shipping)}
Total estimado ${localFormatCurrency(total)}

El total final se confirma al procesar tu pedido.

Ningún pedido se despacha sin confirmación previa.

Volver a la tienda

La factura se descarga como archivo imprimible. El correo comparte el resumen del pedido.

`; successEl.classList.remove("hidden"); nukeEmptyWarning(); // No redirigir automáticamente: el cliente ahora puede descargar o compartir su factura/orden. } function renderCartSummary() { const cart = typeof getCart === "function" ? getCart() : []; const totals = typeof calculateCartTotals === "function" ? calculateCartTotals(cart) : { subtotal: 0, totalPairs: 0, discountLabel: "Sin descuento", total: 0 }; const shippingAmount = calculateShippingAmount(); if (successEl && !successEl.classList.contains("hidden")) { nukeEmptyWarning(); } if (!cart.length) { if (successEl && !successEl.classList.contains("hidden")) { if (itemsContainer) { itemsContainer.innerHTML = `
Pedido enviado correctamente ✅
`; } if (subtotalLabel) subtotalLabel.textContent = localFormatCurrency(0); if (discountLabel) discountLabel.textContent = " "; if (shippingLabel) shippingLabel.textContent = localFormatCurrency(0); if (totalLabel) totalLabel.textContent = localFormatCurrency(0); if (pairsInfoLabel) pairsInfoLabel.textContent = ""; if (form) form.classList.add("pointer-events-none", "opacity-60"); return; } if (itemsContainer) { itemsContainer.innerHTML = '

Tu carrito está vacío. Vuelve a la tienda para agregar productos.

'; } const warn = document.getElementById("emptyCartAlert"); if (warn) warn.classList.remove("hidden"); if (subtotalLabel) subtotalLabel.textContent = localFormatCurrency(0); if (discountLabel) discountLabel.textContent = " "; if (shippingLabel) shippingLabel.textContent = localFormatCurrency(0); if (totalLabel) totalLabel.textContent = localFormatCurrency(0); if (pairsInfoLabel) pairsInfoLabel.textContent = ""; if (form) form.classList.add("pointer-events-none", "opacity-60"); return; } const warn = document.getElementById("emptyCartAlert"); if (warn) warn.classList.add("hidden"); if (form) form.classList.remove("pointer-events-none", "opacity-60"); if (itemsContainer) { itemsContainer.innerHTML = ""; cart.forEach((item) => { const lineTotal = Number(item.price || 0) * Number(item.quantity || 0); const imgSrc = normalizeImageUrl(item.image || "/assets/brand/logo-icon-speed.webp"); const color = item.color ?? null; const isSealedBox = item.purchaseMode === "sealed_box" || item.sealedBoxCount; const row = document.createElement("div"); row.className = "flex items-start justify-between gap-3 border border-blue-100 bg-white rounded-2xl p-3 shadow-sm"; row.innerHTML = `
${escapeHTML(item.name ||
${item.code ? `

Código: ${escapeHTML(item.code)}

` : ""} ${isSealedBox ? `

Caja

` : ""}

${escapeHTML(item.name || "Producto")}

${color ? ("Color " + escapeHTML(color) + " • ") : ""}Talla ${escapeHTML(item.size || "-")} • ${Number(item.quantity || 0)} par(es)

Precio unitario: ${localFormatCurrency(item.price || 0)} ${item.sealedBoxComposition ? `
Composición caja: ${escapeHTML(item.sealedBoxComposition)}` : ''}

${localFormatCurrency(lineTotal)}
`; itemsContainer.appendChild(row); }); } if (subtotalLabel) subtotalLabel.textContent = localFormatCurrency(totals.subtotal); if (discountLabel) discountLabel.textContent = totals.discountLabel; if (shippingLabel) shippingLabel.textContent = localFormatCurrency(shippingAmount); if (totalLabel) totalLabel.textContent = localFormatCurrency(Number(totals.total || 0) + shippingAmount); if (pairsInfoLabel) pairsInfoLabel.textContent = `${totals.totalPairs || 0} par(es) en el carrito`; } renderCartSummary(); [customerAddressInput, customerCityInput, customerProvinceInput].forEach((input) => { input?.addEventListener("input", renderCartSummary); }); if (!form) return; form.addEventListener("submit", async (e) => { e.preventDefault(); if (errorEl) errorEl.classList.add("hidden"); if (successEl) successEl.classList.add("hidden"); const customerName = document.getElementById("customerName").value.trim(); const customerPhone = document.getElementById("customerPhone").value.trim(); const baseAddress = document.getElementById("customerAddress").value.trim(); const city = document.getElementById("customerCity").value.trim(); const province = document.getElementById("customerProvince").value.trim(); const reference = document.getElementById("customerReference").value.trim(); const deliveryDestination = calculateDeliveryDestination(); const vendorCode = getCheckoutVendorCode(); const paymentMethod = document.querySelector('input[name="paymentMethod"]:checked')?.value || "contraentrega"; if ( !customerName || !customerPhone || !baseAddress || !deliveryDestination ) { if (errorEl) { errorEl.textContent = "Completa tus datos y selecciona una provincia válida."; errorEl.classList.remove("hidden"); } return; } const fullAddress = [baseAddress, reference, city, province].filter(Boolean).join(", "); const shippingAmount = calculateShippingAmount(); const cart = typeof getCart === "function" ? getCart() : []; if (!cart.length) { if (errorEl) { errorEl.textContent = "Tu carrito está vacío. Agrega productos antes de confirmar el pedido."; errorEl.classList.remove("hidden"); } return; } const totals = typeof calculateCartTotals === "function" ? calculateCartTotals(cart) : { total: 0, subtotal: 0, totalPairs: 0, discountLabel: " " }; const items = cart.map((item) => ({ productId: item.productId || item._id || item.id, color: item.color ?? null, size: item.size || "", quantity: Number(item.quantity || 0), })); const payload = { items, customerName, customerPhone, customerAddress: fullAddress, customerCity: city, customerProvince: province, vendorCode, paymentMethod, deliveryDestination, shippingAmount, clientTotal: Number(totals.total || 0) + shippingAmount, }; if (submitBtn) { submitBtn.disabled = true; submitBtn.textContent = "Procesando..."; } try { if (typeof createOrder !== "function") throw new Error("No está disponible la función de crear pedido."); lastOrderSnapshot = { cart: JSON.parse(JSON.stringify(cart)), totals: { ...totals, shippingAmount, totalWithShipping: Number(totals.total || 0) + shippingAmount }, customerName, customerPhone, customerAddress: fullAddress, paymentMethod, }; const apiResult = await createOrder(payload); const createdOrderId = apiResult && (apiResult._id || apiResult.orderId || apiResult.id || apiResult.orderNumber); if (!createdOrderId) { throw new Error("Pedido creado, pero no se recibió el ID de la orden."); } if (typeof clearCart === "function") clearCart(); if (submitBtn) submitBtn.textContent = "Pedido realizado"; window.location.href = `gracias.html?order=${encodeURIComponent(createdOrderId)}`; return; } catch (err) { console.error(err); if (errorEl) { errorEl.textContent = err.message || "No pudimos procesar tu pedido. Intenta de nuevo o escríbenos por WhatsApp."; errorEl.classList.remove("hidden"); } if (submitBtn) { submitBtn.disabled = false; submitBtn.textContent = "Confirmar pedido"; } } }); function setupMenu() { const menuBtn = document.getElementById('menuBtn'); const mobileNav = document.getElementById('mobileNav'); if (menuBtn && mobileNav) { menuBtn.addEventListener('click', () => { mobileNav.classList.toggle('hidden'); }); } } function setupSearch() { const desktopForm = document.getElementById('searchForm'); const desktopInput = document.getElementById('desktopSearchInput'); const mobileForm = document.getElementById('mobileSearchForm'); const mobileInput = document.getElementById('mobileSearchInput'); function goSearch(input) { const q = String(input?.value || '').trim(); if (!q) { window.location.href = 'category.html'; return; } window.location.href = `category.html?search=${encodeURIComponent(q)}`; } if (desktopForm && desktopInput) { desktopForm.addEventListener('submit', (event) => { event.preventDefault(); goSearch(desktopInput); }); } if (mobileForm && mobileInput) { mobileForm.addEventListener('submit', (event) => { event.preventDefault(); goSearch(mobileInput); }); } } function setupHeaderScrollAnimation() { const header = document.getElementById('siteHeader'); if (!header) return; /* * FUNNEL_HEADER_STABLE_V2 * El encabezado permanece visible, sin saltos, * compactación ni desplazamientos automáticos. */ header.classList.remove( 'header-hidden', 'header-compact' ); } setupMenu(); setupSearch(); setupHeaderScrollAnimation(); });