WooCommerce 自定义运费和产品级别的成本

WooCommerce custom shipping rate with cost at product level

我想根据每个产品的不同固定成本在 WooCommerce 中创建多个运费,我将其保存为元值。我想为我的每个送货区域提供不同的费率选择:例如,在英国,我想要 UK FirstUK Second,每个区域的费用不同每个产品。

我已经创建了我的第一个送货方式,我可以将它添加到送货区域。但是当我尝试在该区域结帐时,购物车显示 No shipping options were found。谁能发现我做错了什么?

$this->add_rate(
    $rate = array(
        'id'    => $this->id,
        'label' => $this->title,
        'cost'  => 101,
    )
);
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {

    function shipping_method_uk_first_init() {

        class Shipping_Method_UK_First extends \WC_Shipping_Method {

            private string $meta_key = 'shipping_uk_1st';

            public function __construct() {
                $this->id                 = 'shipping_method_uk_first';
                $this->method_title       = __( 'UK First' );
                $this->method_description = __( 'Royal Mail first class' );
                $this->enabled            = 'yes';
                $this->title              = 'UK First Class';
                $this->supports           = array(
                    'shipping-zones',
                    'instance-settings',
                );
                $this->init();
            }

            function init() {
                $this->init_form_fields();
                $this->init_settings();

                add_action(
                    'woocommerce_update_options_shipping_' . $this->id,
                    array(
                        $this,
                        'process_admin_options',
                    )
                );
            }

            public function calculate_shipping( $package = array() ) {
                $cost = 0;

                foreach ( $package['contents'] as $item_id => $values ) {
                    $product                      = $values['data'];
                    $product_shipping_method_cost = $product->get_meta( $this->meta_key );
                    $cost += floatval( $product_shipping_method_cost );
                }

                $rate = array(
                    'id'    => $this->id,
                    'label' => $this->title,
                    'cost'  => $cost,
                );

                $this->add_rate( $rate );
            }
        }

    }

    add_action( 'woocommerce_shipping_init', 'shipping_method_uk_first_init' );

    function add_shipping_method_uk_first( $methods ) {
        $methods['shipping_method_uk_first'] = 'Shipping_Method_UK_First';

        return $methods;
    }

    add_filter( 'woocommerce_shipping_methods', 'add_shipping_method_uk_first' );

}

有一些错误和遗漏。我还在产品运输选项中添加了一个产品自定义字段。请尝试以下操作:

if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {

    function shipping_method_uk_first_init() {

        class Shipping_Method_UK_First extends \WC_Shipping_Method {

            public function __construct( $instance_id = 0 ) {
                $this->id                 = 'shipping_method_uk_first';
                $this->instance_id        = absint( $instance_id );
                $this->method_title       = __( 'UK First' );
                $this->method_description = __( 'Royal Mail first class' );
                $this->enabled            = 'yes';
                $this->meta_key           = 'shipping_uk_1st'; // <= HERE define the related product meta key
                $this->title              = __('UK First Class' );
                $this->supports           = array(
                    'shipping-zones',
                    'instance-settings',
                );
                $this->init();
            }

            function init() {
                $this->init_form_fields();
                $this->init_settings();

                add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
            }

            public function calculate_shipping( $package = array() ) {
                $cost = 0; // Initializing

                foreach ( $package['contents'] as $item_key => $item ) {
                    // Get the parent variable product for product variation items
                    $product = $item['variation_id'] > 0 ? wc_get_product( $item['product_id']) : $item['data'];

                    $cost += floatval( $product->get_meta( $this->meta_key ) );
                }

                $rate = array(
                    'id'    => $this->id,
                    'label' => $this->title,
                    'cost'  => $cost,
                );

                $this->add_rate( $rate );
            }
        }

    }

    add_action( 'woocommerce_shipping_init', 'shipping_method_uk_first_init' );

    function add_shipping_method_uk_first( $methods ) {
        $methods['shipping_method_uk_first'] = 'Shipping_Method_UK_First';

        return $methods;
    }

    add_filter( 'woocommerce_shipping_methods', 'add_shipping_method_uk_first' );

    // Add a custom field to product shipping options
    function add_custom_field_product_options_shipping() {
        global $product_object;

        echo '</div><div class="options_group">'; // New option group

        woocommerce_wp_text_input( array(
            'id'          => 'shipping_uk_1st',
            'label'       => __( 'UK First shipping cost', 'woocommerce' ),
            'placeholder' => '',
            'desc_tip'    => 'true',
            'description' => __( 'Enter the UK First shipping cost value here.', 'woocommerce' ),
            'value'       => (float) $product_object->get_meta( 'shipping_uk_1st' ),
        ) );
    }

    // Save product custom field shipping option value
    function save_custom_field_product_options_shipping( $product ) {
        if ( isset($_POST['shipping_uk_1st']) ) {
            $product->update_meta_data( 'shipping_uk_1st', (float) sanitize_text_field($_POST['shipping_uk_1st']) );
        }
    }

    add_action( 'woocommerce_product_options_shipping', 'add_custom_field_product_options_shipping', 5 );
    add_action( 'woocommerce_admin_process_product_object', 'save_custom_field_product_options_shipping' );
}

代码进入活动子主题(或活动主题)的 functions.php 文件。已测试并有效。