You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shopify购物车验证:阻止实体与数字商品混合结账

解决方案

方案一:Liquid配合实时购物车更新检测

原来的Liquid代码仅在页面加载时执行,无法响应购物车动态变化(比如删除商品)。可以把检测逻辑封装成可复用片段,在页面加载和购物车AJAX更新后都触发检测:

  1. 创建Liquid片段(比如snippets/cart-mixed-check.liquid),写入检测逻辑:
{% assign physical_products = 0 %}
{% assign digital_products = 0 %}
{% for item in cart.items %}
  {% if item.requires_shipping %}
    {% assign physical_products = physical_products | plus: 1 %}
  {% else %}
    {% assign digital_products = digital_products | plus: 1 %}
  {% endif %}
{% endfor %}

{% if digital_products > 0 and physical_products > 0 %}
  <p class="cart-error-message" style="color:red;">实体商品与数字商品不能同时下单,请分开购买!</p>
{% else %}
  <p class="cart-error-message" style="display: none;"></p>
{% endif %}
  1. 在main-cart-items.liquid中引入该片段:
<div class="cart-mixed-check-container">
  {% render 'cart-mixed-check' %}
</div>
  1. 在cart.js中监听购物车更新事件,实时刷新检测结果并控制结账按钮:
// 购物车更新后重新加载检测片段
document.addEventListener('cart:updated', () => {
  fetch('/cart')
    .then(res => res.text())
    .then(html => {
      const parser = new DOMParser();
      const doc = parser.parseFromString(html, 'text/html');
      const newCheckContent = doc.querySelector('.cart-mixed-check-container').innerHTML;
      document.querySelector('.cart-mixed-check-container').innerHTML = newCheckContent;
      toggleCheckoutBtnStatus();
    });
});

// 页面初始化时设置按钮状态
document.addEventListener('DOMContentLoaded', toggleCheckoutBtnStatus);

// 切换结账按钮禁用/启用状态
function toggleCheckoutBtnStatus() {
  const hasError = document.querySelector('.cart-error-message:not([style*="display: none"])');
  const checkoutBtn = document.querySelector('[data-action="checkout"]'); // 按实际按钮选择器调整
  
  if (hasError) {
    checkoutBtn.disabled = true;
    checkoutBtn.style.opacity = '0.6';
  } else {
    checkoutBtn.disabled = false;
    checkoutBtn.style.opacity = '1';
  }
}

方案二:点击结账时通过JS检测(调用Shopify Cart API)

直接在结账按钮点击事件中,通过API获取最新购物车数据,检测后阻止结账:

在cart.js中添加如下代码:

// 绑定结账按钮点击事件
document.querySelector('[data-action="checkout"]').addEventListener('click', (e) => {
  // 获取购物车JSON数据
  fetch('/cart.js')
    .then(res => res.json())
    .then(cart => {
      let hasPhysical = false;
      let hasDigital = false;

      // 遍历购物车商品,标记是否存在实体/数字商品
      cart.items.forEach(item => {
        if (item.requires_shipping) hasPhysical = true;
        else hasDigital = true;
      });

      // 同时存在两种商品时阻止结账
      if (hasPhysical && hasDigital) {
        e.preventDefault();
        // 显示错误提示(无则创建)
        let errorEl = document.querySelector('.cart-error-message');
        if (!errorEl) {
          errorEl = document.createElement('p');
          errorEl.className = 'cart-error-message';
          errorEl.style.color = 'red';
          document.querySelector('.cart__footer').prepend(errorEl); // 按布局调整位置
        }
        errorEl.textContent = '实体商品与数字商品不能同时下单,请分开购买!';
        errorEl.style.display = 'block';
      }
    })
    .catch(err => console.error('获取购物车数据失败:', err));
});

注意事项

  • 结账按钮的选择器(比如[data-action="checkout"])需要根据你店铺的实际HTML结构调整,可能是.checkout-button或其他类名。
  • 错误提示的样式和位置可根据主题自定义。

内容的提问来源于stack exchange,提问作者poko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 20:50:33