在产品页面上显示运费 - WooCommerce

Display shipping cost on product page - WooCommerce

我正在尝试在 Wordpress 上创建一个自定义页面,以一种形式显示 2 种订阅类型,每种类型有 3 种变体(每月、6 个月、12 个月)。每个变体都有一个单选按钮,当用户单击单选按钮时,我有一个实时更新的总价。这部分正在运行。

但是现在,我想添加另外 3 个单选按钮来选择发货方式。 (当用户 select 一个时,它也会实时更新总价)。

我已经搜索了很长时间如何获取产品的运费,但没有任何效果。

有人知道吗:)?

这个问题太宽泛了。所以我可以部分回答,因为你需要自己做一些工作,然后再问更具体的问题……

Now the correct way to set shipping data on product page, is to use Ajax to update the data, as the action is made by the customer on client side (browser), avoiding 'post' and reload the page. But this should be your work...

1) 客户位置 (对于运输区域):

您需要先获取客户位置或送货区域。

然后您需要更新 WC()->sessionWC()->customer 对象中的客户国家/地区。这可以通过以下方式完成:

## Get the geolocated customer country code *(if enabled)*:
$country_code = WC()->customer->get_billing_country();
// or
// $country_code = WC()->customer->get_shipping_country();


## Set a new country code
$new_country_code = 'FR';

## 1. WC_session: set customer billing and shipping country

// Get the data
$customer_session = WC()->session->get( 'customer' );
// Change some data
$customer_session['country'] = $new_country_code; // Billing
$customer_session['shipping_country'] = $new_country_code; // Shipping
// Set the changed data
$customer_session = WC()->session->set( 'customer', $customer_session );

## 2. WC_Customer: set customer billing and shipping country

WC()->customer->set_billing_country( $new_country_code );
WC()->customer->set_shipping_country( $new_country_code );

2) 送货方式 (按送货区域,含费用):

在 Woocommerce 中,运输区域的运输方法仅在客户将产品添加到购物车时可用...

基于此答案代码:
我们可以创建一个自定义数组,其中包含必要的数据,用于通过运输区域获取运输方式、成本和所需的一切。

下面的代码更完整,包括运输方式费用:

// Initializing variable
$zones = $data = $classes_keys = array();

// Rest of the World zone
$zone                                              = new \WC_Shipping_Zone(0);
$zones[$zone->get_id()]                            = $zone->get_data();
$zones[$zone->get_id()]['formatted_zone_location'] = $zone->get_formatted_location();
$zones[$zone->get_id()]['shipping_methods']        = $zone->get_shipping_methods();

// Merging shipping zones
$shipping_zones = array_merge( $zones, WC_Shipping_Zones::get_zones() );

// Shipping Classes
$shipping           = new \WC_Shipping();
$shipping_classes   = $shipping->get_shipping_classes();

// The Shipping Classes for costs in "Flat rate" Shipping Method
foreach($shipping_classes as $shipping_class) {
    //
    $key_class_cost = 'class_cost_'.$shipping_class->term_id;

    // The shipping classes
    $classes_keys[$shipping_class->term_id] = array(
        'term_id' => $shipping_class->term_id,
        'name' => $shipping_class->name,
        'slug' => $shipping_class->slug,
        'count' => $shipping_class->count,
        'key_cost' => $key_class_cost
    );
}

// For 'No class" cost
$classes_keys[0] = array(
    'term_id' => '',
    'name' =>  'No shipping class',
    'slug' => 'no_class',
    'count' => '',
    'key_cost' => 'no_class_cost'
);

foreach ( $shipping_zones as $shipping_zone ) {
    $zone_id = $shipping_zone['id'];
    $zone_name = $zone_id == '0' ? __('Rest of the word', 'woocommerce') : $shipping_zone['zone_name'];
    $zone_locations = $shipping_zone['zone_locations']; // array
    $zone_location_name = $shipping_zone['formatted_zone_location'];

    // Set the data in an array:
    $data[$zone_id]= array(
        'zone_id'               => $zone_id,
        'zone_name'             => $zone_name,
        'zone_location_name'    => $zone_location_name,
        'zone_locations'        => $zone_locations,
        'shipping_methods'      => array()
    );

    foreach ( $shipping_zone['shipping_methods'] as $sm_obj ) {
        $method_id   = $sm_obj->id;
        $instance_id = $sm_obj->get_instance_id();
        $enabled = $sm_obj->is_enabled() ? true : 0;
        // Settings specific to each shipping method
        $instance_settings = $sm_obj->instance_settings;
        if( $enabled ){
            $data[$zone_id]['shipping_methods'][$instance_id] = array(
                '$method_id'    => $sm_obj->id,
                'instance_id'   => $instance_id,
                'rate_id'       => $sm_obj->get_rate_id(),
                'default_name'  => $sm_obj->get_method_title(),
                'custom_name'   => $sm_obj->get_title(),
            );

            if( $method_id == 'free_shipping' ){
                $data[$zone_id]['shipping_methods'][$instance_id]['requires'] = $instance_settings['requires'];
                $data[$zone_id]['shipping_methods'][$instance_id]['min_amount'] = $instance_settings['min_amount'];
            }
            if( $method_id == 'flat_rate' || $method_id == 'local_pickup' ){
                $data[$zone_id]['shipping_methods'][$instance_id]['tax_status'] = $instance_settings['tax_status'];
                $data[$zone_id]['shipping_methods'][$instance_id]['cost'] = $sm_obj->cost;
            }
            if( $method_id == 'flat_rate' ){
                $data[$zone_id]['shipping_methods'][$instance_id]['class_costs'] = $instance_settings['class_costs'];
                $data[$zone_id]['shipping_methods'][$instance_id]['calculation_type'] = $instance_settings['type'];
                $classes_keys[0]['cost'] = $instance_settings['no_class_cost'];
                foreach( $instance_settings as $key => $setting )
                    if ( strpos( $key, 'class_cost_') !== false ){
                        $class_id = str_replace('class_cost_', '', $key );
                        $classes_keys[$class_id]['cost'] = $setting;
                    }

                $data[$zone_id]['shipping_methods'][$instance_id]['classes_&_costs'] = $classes_keys;
            }
        }
    }
}

// Row output (for testing)
echo '<pre>'; print_r($data); echo '</pre>';

custom shipping methods
Now if you are using custom shipping methods (enabled sometimes by 3rd party shipping plugins) you will need to make some changes in the code…

Costs and taxes calculation
You should need to make the taxes calculations, as the costs are displayed just as they are set in shipping settings…


3) 产品页面

客户所在地:
您首先需要有一个位置选择器(定义 送货区 )或根据 Woocommerce 地理位置设置位置。

送货方式:
定义运输区域后,您可以获得相应的 运输方式和费率 (成本),在此产品页面上显示您的运输单选按钮方法。

为此,您需要更改单个产品页面:

你应该需要 get/set/update "chosen_shipping_methods" 用下面的代码 (Ajax).

获取选择的送货方式:

$chosen_shipping = WC()->session->get('chosen_shipping_methods')[0];

Set/Update 选择的送货方式(通过 Javascript/Ajax 和 admin-ajax.php):

// HERE the new method ID
$method_rate_id = array('free_shipping:10');

// Set/Update the Chosen Shipping method
WC()->session->set( 'chosen_shipping_methods', $method_rate_id );