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

基于购物车小计的条件运费适配WooPayments多币种转换问题

WooPayments多币种下自定义阶梯运费的汇率转换问题

问题背景

我用以下自定义函数实现了基于购物车小计的阶梯运费:

function adjust_shipping_rate( $rates, $package ) {
    if (is_admin() && !defined('DOING_AJAX')) {
        return;
    }

    $cart_total = WC()->cart->get_subtotal();
    // Define shipping rates based on cart total
    $shipping_rates = [
        ['min' => 0, 'max' => 50, 'rate' => 20],
        ['min' => 50.1, 'max' => 100, 'rate' => 15],
        ['min' => 100.1, 'max' => 200, 'rate' => 10],
        ['min' => 200.1, 'max' => PHP_INT_MAX, 'rate' => 5]
    ];

    // Find the appropriate shipping rate
    foreach ($shipping_rates as $range) {
        if ($cart_total >= $range['min'] && $cart_total <= $range['max']) {
            foreach ($rates as $rate_key => $rate) {
                if (strpos($rate_key, 'flat_rate') === 0) {
                    $rates[$rate_key]->cost = $range['rate'];
                }
            }
            break;
        }
    }
    
    return $rates;
}
add_filter( 'woocommerce_package_rates', 'adjust_shipping_rate', 10, 2 );

未启用该函数时,WooPayments的多币种转换能正常转换运费金额;但启用后,仅转换运费的货币格式,金额未按汇率计算——比如原本$5运费应转为4.61€,实际显示为5.00€。

我已经知道用get_woocommerce_currency()可以获取当前货币代码,希望能直接获取WooPayments设置的当前汇率,在自定义函数里自行完成转换,且不想安装额外插件。


问题原因

你的处理方式确实存在问题:直接给$rates[$rate_key]->cost赋值原始金额时,跳过了WooPayments的多币种转换逻辑。WooPayments通常会在后续钩子中处理金额的汇率转换,但你直接覆盖了原始成本值,且未考虑当前币种的汇率。

解决方案

WooPayments的汇率存储在wp_options表的woocommerce_wcpay_multicurrency_settings选项中,我们可以直接读取该配置获取汇率,再手动完成运费金额转换:

修改后的函数代码

function adjust_shipping_rate( $rates, $package ) {
    if (is_admin() && !defined('DOING_AJAX')) {
        return $rates;
    }

    // 获取购物车小计(返回的是店铺基准货币金额)
    $cart_total = WC()->cart->get_subtotal();
    // 定义基准货币下的阶梯运费(金额需与店铺基准货币一致)
    $shipping_rates = [
        ['min' => 0, 'max' => 50, 'rate' => 20],
        ['min' => 50.1, 'max' => 100, 'rate' => 15],
        ['min' => 100.1, 'max' => 200, 'rate' => 10],
        ['min' => 200.1, 'max' => PHP_INT_MAX, 'rate' => 5]
    ];

    // 获取当前币种和店铺基准货币
    $current_currency = get_woocommerce_currency();
    $base_currency = get_option('woocommerce_currency');

    // 若使用基准货币,直接设置运费无需转换
    if ($current_currency === $base_currency) {
        foreach ($shipping_rates as $range) {
            if ($cart_total >= $range['min'] && $cart_total <= $range['max']) {
                foreach ($rates as $rate_key => $rate) {
                    if (strpos($rate_key, 'flat_rate') === 0) {
                        $rates[$rate_key]->cost = $range['rate'];
                    }
                }
                break;
            }
        }
        return $rates;
    }

    // 读取WooPayments多币种配置,提取当前币种汇率
    $wcpay_multicurrency = get_option('woocommerce_wcpay_multicurrency_settings');
    $exchange_rate = 1;
    if (!empty($wcpay_multicurrency['currencies'][$current_currency]['rate'])) {
        $exchange_rate = (float)$wcpay_multicurrency['currencies'][$current_currency]['rate'];
    }

    // 计算转换后的运费并赋值
    foreach ($shipping_rates as $range) {
        if ($cart_total >= $range['min'] && $cart_total <= $range['max']) {
            $converted_rate = round($range['rate'] * $exchange_rate, 2);
            foreach ($rates as $rate_key => $rate) {
                if (strpos($rate_key, 'flat_rate') === 0) {
                    $rates[$rate_key]->cost = $converted_rate;
                }
            }
            break;
        }
    }
    
    return $rates;
}
add_filter( 'woocommerce_package_rates', 'adjust_shipping_rate', 10, 2 );

关键说明

  1. 基准货币判断:如果当前使用的是店铺基准货币,无需转换,直接设置运费金额即可。
  2. 汇率获取:从WooPayments后台配置的汇率中读取值,确保和前台显示的汇率一致。
  3. 手动转换:用基准货币的运费金额乘以汇率,得到当前币种的运费,再赋值给运费成本。
  4. 小数处理:用round()保留两位小数,符合货币显示的通用规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 21:26:18