Agregar el código a Shopify
Primero completá la página de Configuración. Después seguí estos seis pasos: solo hay que copiar y pegar.
- 1
El botón de pago se llama siempre “Secure Checkout” y lleva directo al pago seguro. Ya no muestra ninguna alerta de dirección: el envío se calcula en el pago seguro.
- 2
En Shopify entrá a Tienda online → Temas, tocá los tres puntos del tema activo y elegí Editar código.
- 3
Abrí sections/main-product.liquid (o el snippet del formulario de producto) y reemplazá los botones actuales por el fragmento 1.
- 4
Abrí sections/main-cart-footer.liquid, templates/cart.liquid y snippets/cart-drawer.liquid y pegá el fragmento 2 donde estaba el botón de pago.
- 5
Reemplazá TU-DIRECCION-DE-APP por la dirección de esta app publicada (sin la parte /shopify-code).
- 6
Ocultá el botón viejo de Shopify: buscá el botón con name="checkout" y agregale style="display:none".
- 7
El campo “Código promocional” del carrito es el único lugar para descuentos: el código se valida contra Stripe en el servidor y se vuelve a verificar al crear el pago. El descuento automático de 2 remeras sigue igual y nunca se suma con un código.
- 8
Guardá y tocá Secure Checkout desde el producto o el carrito: se abre el pago seguro y ahí se calcula el envío real después de cargar la dirección.
Fragmento 1 — página de producto
“Add to cart” normal más “Secure Checkout”, que agrega la variante y abre el pago seguro sin alertas.
{%- comment -%}
Slow Life Club — PÁGINA DE PRODUCTO
"Add to cart" normal + botón "Secure Checkout" que agrega la variante al
carrito y lleva directo al pago seguro. Nunca muestra alertas: el envío se
calcula en el pago seguro, después de que el cliente carga su dirección.
{%- endcomment -%}
<button type="submit" name="add" class="button">
Add to cart
</button>
<button type="button" id="slc-product-checkout" class="button button--primary">
Secure Checkout
</button>
<p class="slc-pay-note">Secure payment with Stripe · Visa · Mastercard · Apple Pay</p>
<script>
(function () {
// 1. Pegá la dirección de tu app publicada entre las comillas (sin barra final).
var APP_URL = "https://TU-DIRECCION-DE-APP";
var button = document.getElementById("slc-product-checkout");
if (!button) return;
button.addEventListener("click", function () {
var form = button.closest("form[action*='/cart/add']");
var idField = form ? form.querySelector("[name='id']") : null;
var qtyField = form ? form.querySelector("[name='quantity']") : null;
var variantId = idField ? idField.value : "{{ product.selected_or_first_available_variant.id }}";
var quantity = qtyField && qtyField.value ? qtyField.value : 1;
button.disabled = true;
button.textContent = "Redirecting…";
fetch("/cart/add.js", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ id: variantId, quantity: Number(quantity) })
})
.then(function () { return fetch("/cart.js"); })
.then(function (r) { return r.json(); })
.then(function (cart) {
var lines = (cart.items || []).map(function (i) {
return i.variant_id + "x" + i.quantity;
});
window.location.href = APP_URL + "/pay?cart=" + encodeURIComponent(lines.join(","));
})
.catch(function () {
window.location.href = APP_URL + "/pay?cart=" + encodeURIComponent(variantId + "x" + quantity);
});
});
})();
</script>Fragmento 2 — carrito y cart drawer
{%- comment -%}
Slow Life Club — BOTÓN DEL CARRITO / CART DRAWER
Campo de código promocional + botón Secure Checkout centrado.
El código se valida SIEMPRE en el servidor (Stripe Promotion Codes).
{%- endcomment -%}
<div id="slc-promo" style="max-width:420px;margin:0 auto 16px;text-align:center;">
<label for="slc-promo-code" style="display:block;font-size:15px;font-weight:600;margin-bottom:8px;">
Código promocional
</label>
<div style="display:flex;gap:8px;">
<input id="slc-promo-code" type="text" autocomplete="off" placeholder="Ingresa tu código"
style="flex:1;padding:14px 16px;font-size:16px;border:1px solid #cfcabd;border-radius:8px;" />
<button type="button" id="slc-apply-promo" class="button" style="padding:14px 20px;font-size:16px;">
Aplicar
</button>
</div>
<p id="slc-promo-msg" style="margin-top:8px;font-size:14px;min-height:20px;"></p>
</div>
<div style="text-align:center;">
<button type="button" id="slc-secure-checkout" class="button button--primary">
Secure Checkout
</button>
<p class="slc-pay-note">Secure payment with Stripe · Visa · Mastercard · Apple Pay</p>
</div>
<script>
(function () {
// 1. Pegá la dirección de tu app publicada entre las comillas (sin barra final).
var APP_URL = "https://TU-DIRECCION-DE-APP";
var input = document.getElementById("slc-promo-code");
var applyBtn = document.getElementById("slc-apply-promo");
var msg = document.getElementById("slc-promo-msg");
var button = document.getElementById("slc-secure-checkout");
var validCode = null;
function show(text, ok) {
msg.textContent = text;
msg.style.color = ok ? "#2f6b3f" : "#a23a2f";
}
if (applyBtn) {
applyBtn.addEventListener("click", function () {
var code = (input.value || "").trim();
validCode = null;
if (!code) { show("Código no válido", false); return; }
applyBtn.disabled = true;
// La validacion real ocurre en el servidor: el navegador nunca decide.
fetch(APP_URL + "/api/public/validate-promo-code", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ code: code })
})
.then(function (r) { return r.json(); })
.then(function (res) {
if (res && res.valid) { validCode = res.code || code; show("Código aplicado", true); }
else { show((res && res.message) || "Código no válido", false); }
})
.catch(function () { show("Código no válido", false); })
.then(function () { applyBtn.disabled = false; });
});
}
if (!button) return;
button.addEventListener("click", function () {
button.disabled = true;
button.textContent = "Redirecting...";
var promoParam = validCode ? "&promo=" + encodeURIComponent(validCode) : "";
fetch("/cart.js")
.then(function (r) { return r.json(); })
.then(function (cart) {
var lines = (cart.items || []).map(function (i) {
return i.variant_id + "x" + i.quantity;
});
window.location.href = APP_URL + "/pay?cart=" + encodeURIComponent(lines.join(",")) + promoParam;
})
.catch(function () {
window.location.href = APP_URL + "/pay";
});
});
})();
</script>Qué pasa por detrás
- El botón envía solamente los identificadores de variante y las cantidades. Nunca se envían precios desde el navegador.
- El servidor consulta a Shopify el título, el precio, la moneda y la disponibilidad reales de cada variante, y rechaza cualquier producto desconocido, agotado o que no esté en dólares.
- Si hay dos o más remeras (según el tipo, la etiqueta o el título en Shopify) se aplica un cupón fijo del 10%. Si no se puede identificar la remera con certeza, no hay descuento.
- El comprador pasa primero por el paso de entrega de esta app: carga su dirección, el servidor le pide a Printify las tarifas reales de envío (Standard, Economy, Priority, Express o Printify Express) y elige una antes de pagar. Stripe cobra exactamente ese importe; nunca $0 ni una estimación.
- Tus claves secretas nunca salen del servidor.
Importante: los pagos quedan registrados en Stripe y en la base de datos de esta app, pero todavía NO se crea la orden en Shopify. Revisá Stripe para preparar los envíos mientras probás.