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

WooCommerce购物车页应用优惠券后无法刷新总额问题求助

WooCommerce AJAX优惠券应用后购物车总额不更新问题

我正在WooCommerce的cart.php页面实现AJAX功能,目标是让用户无需刷新页面就能应用优惠券。目前已有进展,但遇到问题:优惠券成功应用后,购物车总额没有按预期更新。

截图

cart.php 优惠券表单代码

<?php if ( wc_coupons_enabled() ) { ?>
<form class="checkout_coupon mb-0" method="post">
    <h1 class="cart-small-title">Discount Code</h1>
    <div class="main_cou_nav">
        <p class="cc_code">Coupon Code</p>
        <div class="coupon">
            <h3 class="widget-title"><?php echo get_flatsome_icon( 'icon-tag' ); ?> <?php esc_html_e( 'Coupon', 'woocommerce' ); ?></h3><label for="coupon_code" class="screen-reader-text"><?php esc_html_e( 'Coupon:', 'woocommerce' ); ?></label><input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" placeholder="<?php esc_attr_e( 'Enter Your Coupon code', 'woocommerce' ); ?>" /> <button type="button" class="is-form expand button<?php if ( fl_woocommerce_version_check( '7.0.1' ) ) { echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ); } ?>" id="apply_coupon" name="apply_coupon" value="<?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?>"><?php esc_attr_e( 'Apply coupon', 'woocommerce' ); ?></button>
          <?php do_action( 'woocommerce_cart_coupon' ); ?>
          <div id="custom-coupon-notice"></div>
        </div>
    </div>
</form>

<?php } ?>

functions.php 代码

function enqueue_my_custom_script() {
  wp_enqueue_script(
    'ajax-script-cart', // 脚本标识
    get_stylesheet_directory_uri() . '/js/custom-cart.js', // 脚本路径
    array('jquery'), // 依赖项
    '6.0.0', // 版本号
    true // 在页脚加载
  );

  wp_localize_script(
    'ajax-script-cart', // 对应脚本标识
    'wc_cart_params', // JS对象名称
    array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) // 传递给JS的数据
  );
}

add_action('wp_enqueue_scripts', 'enqueue_my_custom_script');

function ajax_apply_coupon_cart() {
  if(!isset($_POST['coupon_code']) || empty($_POST['coupon_code'])) {
    wp_send_json(['success' => false, 'data' => ['message' => 'No coupon code provided']], 200);
    return;
  }

  $coupon_code = sanitize_text_field($_POST['coupon_code']);

  if(!WC()->cart->has_discount($coupon_code)) {
    $coupon_id = wc_get_coupon_id_by_code($coupon_code);

    if(!$coupon_id) {
      wp_send_json(['success' => false, 'data' => ['message' => sprintf(__('Coupon  does not exist!', 'woocommerce'), $coupon_code)]], 200);
      return;
    }

    WC()->cart->apply_coupon($coupon_code);
    wp_send_json_success(['message' => sprintf(__('Coupon  applied successfully.', 'woocommerce'), $coupon_code)], 200);
  } else {
    wp_send_json_error(['message' => sprintf(__('Coupon  is already applied!', 'woocommerce'), $coupon_code)], 200);
  }
}

add_action('wp_ajax_ajax_apply_coupon_cart', 'ajax_apply_coupon_cart');
add_action('wp_ajax_nopriv_ajax_apply_coupon_cart', 'ajax_apply_coupon_cart');

custom-ajax.js 代码

console.log("Cart script is working")

jQuery(document).on('click', '#apply_coupon', function () {
  console.log("button working as well")
  var code = jQuery('#coupon_code').val();

  data = {
    action: 'ajax_apply_coupon_cart',
    coupon_code: code
  };

  jQuery.post(wc_cart_params.ajax_url, data, function (returned_data) {
    console.log("Data returned from server: ", returned_data); // 调试日志
    if(returned_data.success) {
      jQuery('#custom-coupon-notice').html(returned_data.data.message).removeClass('woocommerce-error').addClass('woocommerce-message').show();
    } else {
      jQuery('#custom-coupon-notice').html(returned_data.data.message).removeClass('woocommerce-message').addClass('woocommerce-error').show();
    }
    jQuery(document.body).trigger('updated_wc_div'); // 应用优惠券后更新购物车页面
  })
    .fail(function (jqXHR) {
      console.error(jqXHR); // 调试日志
      var errorData = jqXHR.responseJSON;
      var errorMessage = errorData && errorData.message ? errorData.message : 'An unknown error occurred';
      jQuery('#custom-coupon-notice').html(errorMessage).addClass('woocommerce-error').show();
    });
});

问题原因及解决方法

核心问题

当前AJAX逻辑仅在服务器端完成优惠券应用,但未将更新后的购物车数据返回前端,也未正确触发WooCommerce的购物车更新机制。updated_wc_div事件需要配合局部刷新组件生效,现有实现缺少更新购物车总额的关键数据传递。

修复步骤

  1. 修改后台AJAX回调,返回更新后的购物车HTML
    在ajax_apply_coupon_cart函数中,应用优惠券后获取购物车关键区域的HTML并返回:

    function ajax_apply_coupon_cart() {
      if(!isset($_POST['coupon_code']) || empty($_POST['coupon_code'])) {
        wp_send_json(['success' => false, 'data' => ['message' => '请输入优惠券代码']], 200);
        return;
      }
    
      $coupon_code = sanitize_text_field($_POST['coupon_code']);
      $response = [];
    
      if(!WC()->cart->has_discount($coupon_code)) {
        $coupon_id = wc_get_coupon_id_by_code($coupon_code);
    
        if(!$coupon_id) {
          wp_send_json(['success' => false, 'data' => ['message' => sprintf(__('优惠券 %s 不存在!', 'woocommerce'), $coupon_code)]], 200);
          return;
        }
    
        WC()->cart->apply_coupon($coupon_code);
        $response['message'] = sprintf(__('优惠券 %s 已成功应用。', 'woocommerce'), $coupon_code);
      } else {
        $response['message'] = sprintf(__('优惠券 %s 已应用!', 'woocommerce'), $coupon_code);
      }
    
      // 获取购物车总额区域HTML(根据主题结构调整模板路径)
      ob_start();
      wc_get_template('cart/cart-totals.php');
      $response['cart_totals'] = ob_get_clean();
    
      wp_send_json_success($response, 200);
    }
    
  2. 修改前端JS,替换DOM元素
    在AJAX成功回调中,用返回的HTML替换页面上的购物车总额区域:

    jQuery.post(wc_cart_params.ajax_url, data, function (returned_data) {
      console.log("Data returned from server: ", returned_data);
      if(returned_data.success) {
        jQuery('#custom-coupon-notice').html(returned_data.data.message).removeClass('woocommerce-error').addClass('woocommerce-message').show();
        // 替换购物车总额区域(根据主题实际DOM结构调整选择器)
        jQuery('.cart-totals').html(returned_data.data.cart_totals);
      } else {
        jQuery('#custom-coupon-notice').html(returned_data.data.message).removeClass('woocommerce-message').addClass('woocommerce-error').show();
      }
      // 触发WooCommerce内置更新事件
      jQuery(document.body).trigger('updated_cart_totals');
      jQuery(document.body).trigger('updated_wc_div');
    })
    
  3. 注意事项

    • 根据主题实际DOM结构调整选择器(如.cart-totals可能需要替换为主题对应类名)
    • 确保wc_get_template加载的模板路径与主题WooCommerce模板结构一致
    • 测试前清空浏览器缓存,确保新代码生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 15:30:55