
在 woocommerce 商店中,有时需要为用户提供额外的促销选项,例如通过勾选一个复选框来获得特定折扣。这个折扣需要是动态的:用户勾选时应用,取消勾选时移除,并且折扣金额应在购物车、结账页、迷你购物车、订单详情以及管理后台等所有相关位置正确显示和计算。理想情况下,此折扣也应能在管理员后台的订单详情页中进行管理。
实现这一功能需要结合 WordPress/WooCommerce 的钩子(Hooks)、JavaScript 和 AJAX 技术,以实现前端交互与后端逻辑的无缝连接。
为了实现购物车页面的动态折扣复选框功能,我们将遵循以下核心策略:
首先,我们需要在 WooCommerce 购物车页面添加一个复选框。我们可以利用 woocommerce_cart_totals_before_shipping 钩子,在购物车总计信息中的运费上方插入我们的复选框。
/**
* 在购物车总计区域添加折扣复选框
*/
function add_discount_checkbox_to_cart_totals() {
// 确保在购物车页面且购物车不为空
if ( is_cart() && ! WC()->cart->is_empty() ) {
// 从会话中获取复选框的当前状态
$is_discount_applied = WC()->session->get( 'apply_custom_discount', false );
?>
<tr class="discount-checkbox-row">
<th><?php esc_html_e( '应用折扣', 'your-text-domain' ); ?></th>
<td data-title="<?php esc_attr_e( '应用折扣', 'your-text-domain' ); ?>">
<label for="custom_discount_checkbox">
<input type="checkbox" id="custom_discount_checkbox" name="custom_discount_checkbox" value="1" <?php checked( $is_discount_applied, true ); ?>>
<?php esc_html_e( '勾选以获得固定折扣', 'your-text-domain' ); ?>
</label>
</td>
</tr>
<?php
}
}
add_action( 'woocommerce_cart_totals_before_shipping', 'add_discount_checkbox_to_cart_totals' );代码解释:
接下来,我们需要编写 JavaScript 代码来监听复选框的状态变化,并使用 AJAX 将其发送到后端。同时,在 AJAX 成功后,需要刷新购物车片段,以便用户立即看到总价的变化。
/**
* 前端 JavaScript 监听复选框变化并发送 AJAX 请求
*/
jQuery(function($) {
var $checkbox = $('#custom_discount_checkbox');
if ($checkbox.length) {
$checkbox.on('change', function() {
var isChecked = $(this).is(':checked');
// 显示加载指示器 (可选)
$('.woocommerce-cart-form, .cart_totals').block({
message: null,
overlayCSS: {
background: '#fff',
opacity: 0.6
}
});
$.ajax({
type: 'POST',
url: wc_cart_params.ajax_url, // WooCommerce 提供的 AJAX URL
data: {
action: 'update_custom_discount_status', // 后端 AJAX 动作
security: wc_cart_params.update_shipping_method_nonce, // 使用 WooCommerce 提供的 nonce
apply_discount: isChecked ? 1 : 0
},
success: function(response) {
if (response.success) {
// 成功后刷新购物车片段
$(document.body).trigger('update_checkout'); // 刷新结账页 (如果用户在结账页)
$(document.body).trigger('wc_fragment_refresh'); // 刷新迷你购物车
$(document.body).trigger('wc_update_cart'); // 刷新购物车总计
} else {
console.error('更新折扣状态失败:', response.data);
alert('更新折扣状态失败,请重试。');
}
},
error: function(xhr, status, error) {
console.error('AJAX 请求错误:', error);
alert('网络错误,请重试。');
},
complete: function() {
// 隐藏加载指示器
$('.woocommerce-cart-form, .cart_totals').unblock();
}
});
});
}
});代码解释:
现在,我们需要在 PHP 后端注册 AJAX 处理器,接收前端发送的复选框状态,并据此在 WooCommerce 会话中存储状态,最后通过 woocommerce_cart_calculate_fees 钩子动态应用或移除折扣。
/**
* 后端 AJAX 处理器:更新折扣复选框状态
*/
function handle_custom_discount_ajax() {
// 验证 nonce
if ( ! isset( $_POST['security'] ) || ! wp_verify_nonce( $_POST['security'], 'woocommerce-cart' ) ) {
wp_send_json_error( 'Nonce 验证失败!' );
}
$apply_discount = isset( $_POST['apply_discount'] ) ? (bool) intval( $_POST['apply_discount'] ) : false;
// 将状态存储到 WooCommerce Session
WC()->session->set( 'apply_custom_discount', $apply_discount );
// 重新计算购物车总计
WC()->cart->calculate_totals();
wp_send_json_success( array( 'message' => '折扣状态已更新。' ) );
}
add_action( 'wp_ajax_update_custom_discount_status', 'handle_custom_discount_ajax' );
add_action( 'wp_ajax_nopriv_update_custom_discount_status', 'handle_custom_discount_ajax' ); // 允许未登录用户使用
/**
* 根据复选框状态动态添加或移除购物车折扣费用
*/
function apply_custom_discount_fee( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
return; // 避免在管理后台非 AJAX 请求时执行
}
// 获取折扣金额 (固定值)
$discount_amount = 10; // 例如:固定折扣 10 元/美元
// 从会话中获取复选框状态
$apply_discount = WC()->session->get( 'apply_custom_discount', false );
if ( $apply_discount ) {
// 如果折扣已勾选,添加负值费用 (即折扣)
// 参数: name, amount, taxable, tax_class
$cart->add_fee( esc_html__( '自定义折扣', 'your-text-domain' ), -$discount_amount, false );
} else {
// 如果未勾选,确保移除任何之前可能存在的折扣 (虽然 add_fee 是动态的,但明确处理更好)
// 实际上,如果条件不满足,add_fee 就不会被调用,也就不会添加费用。
// 但如果需要更复杂的逻辑,这里可以进行清理。
}
}
add_action( 'woocommerce_cart_calculate_fees', 'apply_custom_discount_fee', 10, 1 );
/**
* 初始化 WooCommerce Session,如果尚未初始化
* 这对于某些环境可能不是必需的,但可以作为一种健壮性措施
*/
function init_woocommerce_session_for_discount() {
if ( ! WC()->session->has_session() ) {
WC()->session->set_customer_session_cookie( true );
}
}
add_action( 'init', 'init_woocommerce_session_for_discount' );代码解释:
由于我们通过 add_fee 方法将折扣添加为购物车费用,WooCommerce 会自动处理其在以下位置的显示:
管理员后台管理: 当折扣作为费用添加到订单时,管理员可以在 WooCommerce 订单编辑页面看到并编辑(或移除)这个费用。这满足了在管理后台管理折扣的需求。
// 示例:从选项中获取折扣金额 $discount_amount = floatval( get_option( 'custom_discount_amount', 10 ) ); // 你还需要在后台添加一个设置页面来管理这个选项
// 示例:百分比折扣 $percentage_discount = 0.05; // 5% $discount_amount = $cart->get_subtotal() * $percentage_discount; $cart->add_fee( esc_html__( '自定义折扣 (5%)', 'your-text-domain' ), -$discount_amount, false );
通过上述步骤,我们成功地在 WooCommerce 购物车页面实现了一个功能完善的动态折扣复选框。该方案利用了 WooCommerce 的会话管理、AJAX 机制和费用钩子,确保了折扣的动态应用、持久化以及在整个购物流程和后台管理中的正确显示。遵循这些最佳实践,可以为你的 WooCommerce 商店添加灵活且用户友好的促销功能。
以上就是在 WooCommerce 购物车页面添加动态折扣复选框教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号