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

WooCommerce数字钱包折扣金额计算异常及税费显示问题求助

问题场景
  • 订单商品金额22.05,运费9.66,订单总计31.71
  • 数字钱包余额500,完全可覆盖订单金额
  • 折扣费用始终显示为-31.70,而非预期的-31.71
  • 订单总计正确显示为0,但仍展示"含0.01税费"的提示,逻辑不合理
代码问题排查

1. 折扣金额计算偏差原因

在hpb2b_handle_wallet_usage函数中,存在两个问题导致金额偏差:

  • 依赖WC()->cart->total作为抵扣基数,但该值在调用calculate_totals()前可能未完成精确计算,存在浮点精度误差
  • 使用ceil()向上取整的方式,会在部分场景下导致金额截断或偏差,不符合常规财务计算逻辑

2. 税费提示不合理原因

adjust_final_total_based_on_wallet仅强制将订单总计设为0,但未处理已计算的税费金额,前端仍会展示税费明细,造成逻辑矛盾。

修正后的代码
// Wallet value applied to cart including shipping cost
function hpb2b_handle_wallet_usage() {
    if (isset($_POST['use_wallet'])) {
        $use_wallet = $_POST['use_wallet'] === 'yes';
        
        if ($use_wallet) {
            $user_id = get_current_user_id();
            $balance = get_user_meta($user_id, '_wallet_balance', true) ?: 0;
            
            WC()->session->set('use_wallet', true);
            // 改用明细求和获取精确订单总额(含商品、运费、税费)
            $cart = WC()->cart;
            $total_cart_and_shipping = $cart->cart_contents_total + $cart->shipping_total + $cart->get_cart_contents_tax() + $cart->get_shipping_tax();
            $total_to_deduct = min($balance, $total_cart_and_shipping);
            // 四舍五入到分,符合常规财务计算逻辑
            $total_to_deduct = round($total_to_deduct * 100) / 100;
            WC()->session->set('wallet_amount', $total_to_deduct);
        } else {
            WC()->session->set('use_wallet', false);
            WC()->session->set('wallet_amount', 0);
        }
    }
    WC()->cart->calculate_totals();
    wp_die();
}
add_action('wp_ajax_apply_wallet_discount', 'hpb2b_handle_wallet_usage');
add_action('wp_ajax_nopriv_apply_wallet_discount', 'hpb2b_handle_wallet_usage');

add_action('woocommerce_cart_calculate_fees', 'apply_wallet_discount_to_cart_and_shipping', 20);
function apply_wallet_discount_to_cart_and_shipping($cart) {
    if (is_admin() && !defined('DOING_AJAX'))
        return;

    if (WC()->session->get('use_wallet')) {
        $discount_amount = WC()->session->get('wallet_amount');
        if ($discount_amount > 0) {
            $cart->add_fee(__('Carteira Digital', 'hpb2b-custom'), -$discount_amount, false);
        }
    }
}

add_action('woocommerce_thankyou', 'update_wallet_balance_after_purchase', 10, 1);
function update_wallet_balance_after_purchase($order_id) {
    $order = wc_get_order($order_id);
    $user_id = $order->get_user_id();
    $balance = get_user_meta($user_id, '_wallet_balance', true) ?: 0;
    
    if (WC()->session->get('use_wallet')) {
        $discount_amount = WC()->session->get('wallet_amount');
        update_user_meta($user_id, '_wallet_balance', max(0, $balance - $discount_amount));
        
        WC()->session->set('use_wallet', false);
        WC()->session->set('wallet_amount', 0);
    }
}

add_filter('woocommerce_calculated_total', 'adjust_final_total_based_on_wallet', 10, 2);
function adjust_final_total_based_on_wallet($total, $cart) {
    if (WC()->session->get('use_wallet')) {
        $wallet_amount = WC()->session->get('wallet_amount');
        $cart_total = $cart->cart_contents_total + $cart->shipping_total + $cart->get_cart_contents_tax() + $cart->get_shipping_tax();

        if ($wallet_amount >= $cart_total) {
            return 0;
        } else {
            return max(0, $cart_total - $wallet_amount);
        }
    }

    return $total;
}

// 钱包覆盖全额时,隐藏购物车税费显示
add_filter('woocommerce_cart_taxes_total', 'adjust_tax_display_when_wallet_covers', 10, 1);
function adjust_tax_display_when_wallet_covers($tax_total) {
    if (WC()->session->get('use_wallet')) {
        $wallet_amount = WC()->session->get('wallet_amount');
        $cart = WC()->cart;
        $cart_total = $cart->cart_contents_total + $cart->shipping_total + $cart->get_cart_contents_tax() + $cart->get_shipping_tax();
        
        if ($wallet_amount >= $cart_total) {
            return 0;
        }
    }
    return $tax_total;
}

// 订单创建时记录钱包使用状态
add_action('woocommerce_checkout_create_order', 'save_wallet_usage_to_order', 10, 2);
function save_wallet_usage_to_order($order, $data) {
    if (WC()->session->get('use_wallet')) {
        $order->update_meta_data('_use_wallet', true);
        $order->update_meta_data('_wallet_amount', WC()->session->get('wallet_amount'));
    }
}

// 订单页面隐藏不合理的税费明细
add_filter('woocommerce_order_taxes', 'adjust_order_tax_display_when_wallet_covers', 10, 2);
function adjust_order_tax_display_when_wallet_covers($taxes, $order) {
    $use_wallet = get_post_meta($order->get_id(), '_use_wallet', true);
    $wallet_amount = get_post_meta($order->get_id(), '_wallet_amount', true);
    
    if ($use_wallet && $wallet_amount >= $order->get_total()) {
        return [];
    }
    return $taxes;
}

关键修改说明

  1. 折扣金额精确计算:

    • 替换WC()->cart->total为明细求和方式,避免WC内部计算时机导致的精度误差
    • 将ceil()改为round(),确保金额四舍五入到分,符合常规财务逻辑
  2. 税费提示修正:

    • 新增购物车税费过滤逻辑,钱包覆盖全额时将税费总额设为0,前端不再显示税费提示
    • 新增订单元数据记录,保存钱包使用状态,确保订单页面也能正确隐藏不合理的税费明细

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:24:54