A veces no me llega el formulario liquid con la información del cliente al correo

Hola!

Tengo un problema con el formulario Liquid. Dado que necesitaba una solución más avanzada que la que ofrece Shopify, lo he desarrollado en HTML y JavaScript. En general, funciona bien: recoge la información correctamente y el correo que me llega cuando un cliente envía el formulario tiene la estructura adecuada.

El problema es que, en algunos casos (aproximadamente 2 de cada 8 envíos), el formulario indica al cliente que todo ha salido bien, pero yo no recibo el correo. No sé qué puede estar causando esto ni cómo solucionarlo.

Además, quería preguntar si hay alguna forma de conectar este formulario con la base de datos de formularios de Shopify o si eso no es posible.

Agradecería mucho vuestra ayuda!!

Muchas gracias:)

El formulario está aquí:
WEB risonona

CÓDIGO LIQUID:

<div class="formulario-container">
        <div class="FormularioTextoGeneral">
            <h1>¡Hablemos!</h1>
            <h4 class="LetrasVerde">Pide presupuesto especificando las características de tu
                pedido y añade tus datos para poder contactar contigo</h4>
        </div>
        <form class="formulario" method="POST" action="/contact" id="contact_form">
            <input type="hidden" name="return_to" value="/pages/agradecimientos">
            <input type="hidden" name="form_type" value="contact">
            <input type="hidden" name="utf8" value="✓">
            <div class="formulario-datos-personales">
                <h3 class="FormularioTextoGeneral">Datos personales</h3>

                <h4 class="EspacioMargin LetrasVerde"><label for="nombre">Nombre y Apellidos</label>
                    <input class="SeccionesInteractivasFormulario" type="text" id="nombre" name="contact[name]"
                        required>
                </h4>

                <h4 class="apartadoFormulario LetrasVerde">
                    <label for="email">Correo Electrónico</label>
                    <input class="SeccionesInteractivasFormulario" type="email" id="email" name="contact[email]"
                        required>
                </h4>
                <h4 class="apartadoFormulario LetrasVerde">
                    <label for="telefono">Número de Teléfono</label>
                    <input class="SeccionesInteractivasFormulario" type="tel" id="telefono" name="contact[phone]"
                        required>
                </h4>
            </div>

            <h3 class="FormularioTextoGeneral">Información del pedido</h3>

            <h4 class="formulario-opcion">
                <label for="copies">¿Cuántas copias A3 quieres?</label>
                <input class="SeccionesInteractivasFormulario" type="number" name="copies" id="copies" min="20"
                    value="20">
            </h4>

            <h4 class="formulario-opcion">
                <label for="format">¿Qué formato?</label>
                <p class="tipoFormulario">En el manual de impresión se explica cuantos elementos de tu diseño caben en
                    un A3. Calcúlalo y elige las copias de A3.</p>
                <select class="seleccionFormatos SeccionesInteractivasFormulario" name="format" id="format">
                    <option value="A3">A3</option>
                    <option value="A4">A4</option>
                    <option value="A5">A5</option>
                    <option value="A6">A6</option>
                    <option value="Tarjetas de visita">Tarjetas de visita</option>
                    <option value="Fanzine">Fanzine</option>
                    <option value="Otros">Otros</option>
                </select>
            </h4>

            <h4 class="formulario-opcion">
                <label for="paper">Tipo de papel</label>
                <select class="seleccionPapel SeccionesInteractivasFormulario" name="paper" id="paper">
                    <option value="Munken Polar 100" data-price="0.10">Munken Polar 100gr</option>
                    <option value="Munken Polar 150" data-price="0.20">Munken Polar 150gr</option>
                    <option value="Munken Polar 240" data-price="0.35">Munken Polar 240gr</option>
                    <option value="Munken Print 90" data-price="0.10">Munken Print 90gr</option>
                    <option value="Munken Print 150" data-price="0.20">Munken Print 150gr</option>
                    <option value="Munken Pure 100" data-price="0.10">Munken Pure 100gr</option>
                    <option value="Munken Pure 170" data-price="0.20">Munken Pure 170gr</option>
                    <option value="Munken Pure 240" data-price="0.35">Munken Pure 240gr</option>
                    <option value="Munken Pure 300" data-price="0.50">Munken Pure 300gr</option>
                </select>
            </h4>

            <h4 class="formulario-opcion">
                <label>Colores de tinta</label>

                <div id="ink-options" class="color-grid ">
                    <div class="color-option ColorNaranja" data-color="#ff6c2f">
                        <div class="color-box colorBoxNaranja ColorNaranja"></div>
                        <p class="SeleccionColorTexto ColorNaranja">Naranja</p>
                    </div>
                    <div class="color-option ColorAzul" data-color="#0078bf">
                        <div class="color-box colorBoxAzul ColorAzul"></div>
                        <p class="SeleccionColorTexto ColorAzul">Azul</p>
                    </div>
                    <div class="color-option ColorNegro" data-color="#00a95c">
                        <div class="color-box colorBoxNegro ColorNegro"></div>

                        <p class="SeleccionColorTexto ColorNegro">Negro</p>
                    </div>
                    <div class="color-option ColorAmarillo" data-color="#ffe800">
                        <div class="color-box colorBoxAmarillo ColorAmarillo"></div>
                        <p class="SeleccionColorTexto ColorAmarillo">Amarillo</p>
                    </div>
                    <div class="color-option ColorRosaFluor" data-color="#ff48b0">
                        <div class="color-box colorBoxRosaFluor ColorRosaFluor"></div>
                        <p class="SeleccionColorTexto ColorRosaFluor">Rosa Fluor</p>
                    </div>
                    <div class="color-option ColorVerdeCazador" data-color="#407060">
                        <div class="color-box colorBoxVerdeCazador ColorVerdeCazador"></div>

                        <p class="SeleccionColorTexto ColorVerdeCazador">V.Cazador</p>
                    </div>
                </div>
            </h4>

            <h4 class="formulario-opcion dobleCara">
                <label for="double-sided">¿Doble cara?</label>
                <input class="checkboxStyle" type="checkbox" id="double-sided">
            </h4>
            <h4 class="formulario-opcion dobleCara">
                <label for="guillotine">¿Guillotinado?</label>
                <p class="tipoFormulario">Si quieres que el diseño vaya a sangre, se puede guillotinar.
                    Si tienes varios diseños en el A3 también.</p>
                <input class="checkboxStyle" type="checkbox" id="guillotine">
            </h4>

            <h4 class="formulario-opcion ">
                <label for="comments">Comentarios adicionales:</label>
                <textarea class="areaComentarios SeccionesInteractivasFormulario" id="comments" rows="1"
                    placeholder="Añade cualquier duda o información adicional que creas relevante!"></textarea>
            </h4>
            <div class="GrupoResumenpedido">
                <h3>Resumen del Pedido</h3>
                <div class="resumenPedido ">
                    <p class="resumen-linea">Precio base: 15€</p>
                    <div class="resumen-linea"><span class="TicketAlineacion">Copias</span><span
                            id="resumen-copias">20</span><span id="precio-copias">0.00€</span></div>
                    <div class="resumen-linea"><span class="TicketAlineacion">Formato</span><span
                            id="resumen-formato">A3</span><span>-</span></div>
                    <div class="resumen-linea"><span class="TicketAlineacion">Papel</span><span
                            id="resumen-papel">Munken Polar 100</span><span id="precio-papel">0.00€</span></div>
                    <div class="resumen-linea"><span class="TicketAlineacion">Tintas</span><span
                            id="resumen-tintas">Ninguna</span><span id="precio-tintas">0.00€</span></div>
                    <div class="resumen-linea"><span class="TicketAlineacion">Doble cara</span><span
                            id="resumen-doble-cara">No</span><span id="precio-doble">0.00€</span></div>
                    <div class="resumen-linea">
                        <span class="TicketAlineacion">Guillotinado</span>
                        <span id="resumen-guillotinado">No</span>
                        <span id="precio-guillotinado">0.00€</span>
                    </div>

                    <p class="FormularioTextoGeneral texto-destacado">Precio total: <span class="LetrasNaranja"
                            id="total-price"> 15.00€ </span></p>

                    <p class="FormularioTextoGeneral"> +IVA</p>
                </div>

            </div>

            <div class="BloqueEnviar">
                <button class="botonEnviar" type="submit">Enviar</button>
            </div>
            <input type="hidden" id="resumen_pedido" name="contact[body]">

        </form>
    </div>

<script>
        document.addEventListener("DOMContentLoaded", function () {
            // Elementos del formulario
            const copiesInput = document.getElementById("copies");
            const paperSelect = document.getElementById("paper");
            const inkOptions = document.querySelectorAll(".color-option");
            const doubleSidedCheckbox = document.getElementById("double-sided");
            const guillotineCheckbox = document.getElementById("guillotine");
            const totalPriceElement = document.getElementById("total-price");

            // Elementos del resumen
            const resumenCopias = document.getElementById("resumen-copias");
            const resumenPapel = document.getElementById("resumen-papel");
            const resumenTintas = document.getElementById("resumen-tintas");
            const resumenDobleCara = document.getElementById("resumen-doble-cara");
            const resumenGuillotinado = document.getElementById("resumen-guillotinado");

            // Elementos de precio en el resumen
            const precioCopias = document.getElementById("precio-copias");
            const precioTintas = document.getElementById("precio-tintas");
            const precioPapel = document.getElementById("precio-papel");
            const precioDoble = document.getElementById("precio-doble");
            const precioGuillotinado = document.getElementById("precio-guillotinado");

            // Función para actualizar el precio
            function updatePrice() {
                let copies = parseInt(copiesInput.value) || 20;
                let inks = document.querySelectorAll(".color-option.selected").length;
                let extraCost = parseFloat(paperSelect.selectedOptions[0]?.dataset.price || "0");
                let doubleSided = doubleSidedCheckbox.checked ? 2 : 1;
                let guillotinado = guillotineCheckbox.checked ? 5 : 0;

                let masterCost = inks * 6 * doubleSided; // Cada tinta necesita un master, se duplica si es doble cara
                let inkCost = (copies * inks * 0.04) * doubleSided; // Cada pasada de tinta cuesta 0,04€, se duplica si es doble cara

                let finalPrice = (15 + extraCost * copies + masterCost + inkCost + guillotinado).toFixed(2);

                totalPriceElement.textContent = finalPrice + "€";

                updateResumen();
            }

            function updateResumen() {
                let copies = parseInt(copiesInput.value) || 20;
                let inks = Array.from(document.querySelectorAll(".color-option.selected p"))
                    .map(el => el.textContent)
                    .join(", ") || "Ninguna";

                let formatText = document.getElementById("format").options[document.getElementById("format").selectedIndex].text;
                let paperText = paperSelect.options[paperSelect.selectedIndex].text;
                let doubleSided = doubleSidedCheckbox.checked ? "Sí" : "No";
                let guillotinado = guillotineCheckbox.checked ? "Sí" : "No";

                resumenCopias.textContent = copies;
                resumenPapel.textContent = paperText;
                resumenTintas.textContent = inks;
                resumenDobleCara.textContent = doubleSided;
                resumenGuillotinado.textContent = guillotinado;
                document.getElementById("resumen-formato").textContent = formatText;

                let extraCost = parseFloat(paperSelect.selectedOptions[0]?.dataset.price || "0");

                precioCopias.textContent = "-";
                precioTintas.textContent = ((document.querySelectorAll(".color-option.selected").length * 6 * (doubleSidedCheckbox.checked ? 2 : 1))
                    + (copies * document.querySelectorAll(".color-option.selected").length * 0.04 * (doubleSidedCheckbox.checked ? 2 : 1))).toFixed(2) + "€";

                precioPapel.textContent = (extraCost * copies).toFixed(2) + "€";
                precioDoble.textContent = doubleSided === "Sí" ? "Incluido" : "No aplica";
                precioGuillotinado.textContent = guillotineCheckbox.checked ? "5.00€" : "No aplica";
            }

            // Función para generar y asignar el resumen al input oculto
            function generateSummary() {
                let nombre = document.getElementById("nombre").value;
                let email = document.getElementById("email").value;
                let telefono = document.getElementById("telefono").value;
                let comentarios = document.getElementById("comments").value;

                let copies = document.getElementById("copies").value;
                let format = document.getElementById("format").value;
                let paper = document.getElementById("paper").value;

                let inks = Array.from(document.querySelectorAll(".color-option.selected p"))
                    .map(el => el.textContent)
                    .join(", ") || "Ninguna";

                let doubleSided = document.getElementById("double-sided").checked ? "Sí" : "No";
                let guillotine = document.getElementById("guillotine").checked ? "Sí" : "No";

                let resumen = `\nDATOS PERSONALES\n- Nombre: ${nombre}\n- Email: ${email}\n- Teléfono: ${telefono}\n\nPEDIDO\n- Copias: ${copies}\n- Formato: ${format}\n- Papel: ${paper}\n- Tintas: ${inks}\n- Doble cara: ${doubleSided}\n- Guillotinado: ${guillotine}\n\nComentarios: ${comentarios}`;

                document.getElementById("resumen_pedido").value = resumen;
            }

            // Enviar formulario con AJAX y redirigir a la página de agradecimientos
            function handleSubmit(event) {
                event.preventDefault(); // Evita el envío tradicional

                generateSummary();
                const form = event.target;
                const formData = new FormData(form);
                const actionUrl = form.getAttribute("action");

                fetch(actionUrl, {
                    method: "POST",
                    body: formData,
                    headers: { "Accept": "text/html" }
                })
                    .then(response => response.text())
                    .then(data => {
                        if (data.toLowerCase().includes("thank") || data.toLowerCase().includes("gracias")) {
                            window.location.href = "/pages/agradecimientos";
                        }
                    })
                    .catch(error => console.error("Error en el envío:", error));
            }

            // Escuchar cambios en los inputs para actualizar el precio
            copiesInput.addEventListener("input", updatePrice);
            paperSelect.addEventListener("change", updatePrice);
            doubleSidedCheckbox.addEventListener("change", updatePrice);
            guillotineCheckbox.addEventListener("change", updatePrice);
            document.getElementById("format").addEventListener("change", updateResumen);

            inkOptions.forEach(option => {
                option.addEventListener("click", function () {
                    this.classList.toggle("selected");
                    updatePrice();
                });
            });

            // Manejo del formulario
            document.querySelector(".formulario").addEventListener("submit", handleSubmit);

            // Inicializar precio al cargar la página
            updatePrice();

            function handleSubmit(event) {
                event.preventDefault(); // Evita el envío tradicional

                generateSummary();
                const form = event.target;
                const formData = new FormData(form);
                const actionUrl = form.getAttribute("action");

                // Enviar a Google Sheets
                fetch("https://script.google.com/macros/s/AKfycbyR-OU5MwWA0DWGOnPOm3mW9HPuECKAmFSgmcxoUNpud7y8Xcv61UQjHGfAbqW-UGqj/exec", {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json"
                    },
                    body: JSON.stringify(Object.fromEntries(formData))
                })
                    .then(response => response.json())
                    .then(data => console.log("Datos enviados a Google Sheets", data))
                    .catch(error => console.error("Error en el envío a Google Sheets:", error));
            }
        });

    </script>