我创建了一种自定义送货方式,用于计算外部送货API的送货成本 . 我按照发现here (Woocommerce docs)here(Tutsplus)的说明进行操作 .

我已经添加了运费,如下所示

//...
public function calculate_shipping( $package ) {
    //...
$rate = array(
            'id' => $this->id,
            'label' => $this->title,
            'cost' => $cost //calculated based on the distance
        );
$this->add_rate( $rate );
}
//...

一切正常,直到客户必须完成订单,然后购物车中的商品是订单总额中包含的唯一商品 .

在购物车确认部分中可以看到送货方式和费用,但确认订单后,订单和收据中不包含费用 .

记录运输方法,但不包括成本 .

编辑...这是我的整个送货插件文件

<?php
/*
Woocommerce plugin details
*/
if (!defined('ABSPATH')) {
    exit;
    // Exit if accessed directly
}
/**
 * Check if WooCommerce is active
 **/
if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
    function my_shipping_method()
    {
        if (!class_exists('my_shipping_method')) {
            class my_shipping_method extends WC_Shipping_Method
            {
                /**
                 * Constructor for the shipping class
                 *
                 * @access public
                 * @return void
                 */
                public function __construct()
                {
                    $this->id = 'my_shipping_method';
                    $this->method_title = __('Custom Ondemand Shipping', 'my_shipping_method');
                    $this->method_description = __('Custom Shipping Method for Custom Ondemand', 'my_shipping_method');
                    // Availability & Countries
                    $this->availability = 'including';
                    $this->countries = array('KE');
                    $this->init();
                    $this->enabled = isset($this->settings['enabled']) ? $this->settings['enabled'] : 'yes';
                    $this->title = isset($this->settings['title']) ? $this->settings['title'] : __('Custom Ondemand Shipping', 'my_shipping_method');
                    $this->API_username = isset($this->settings['API_username']) ? $this->settings['API_username'] : 'myusername';
                    $this->API_key = isset($this->settings['API_key']) ? $this->settings['API_key'] : 'mykey';
                    $this->CUSTOM_LIVE_URL = 'https://api.custom.com/v1';
                    $this->CUSTOM_TEST_URL = 'https://apitest.custom.com/v1/';
                    $this->CUSTOM_URL = (isset($this->settingd['USE_LIVE_API']) && $this->settingd['USE_LIVE_API'] == 'yes' )? $this->CUSTOM_LIVE_URL : $this->CUSTOM_TEST_URL;
                }

                /**
                 * Init the settings
                 *
                 * @access public
                 * @return void
                 */
                function init()
                {
                    // Load the settings API
                    $this->init_form_fields();
                    $this->init_settings();
                    // Save settings in admin if you have any defined
                    add_action('woocommerce_update_options_shipping_' . $this->id, array($this, 'process_admin_options'));
                    //register google maps places library
                    wp_register_script('mapsPlaces', 'https://maps.googleapis.com/maps/api/js?key=' . $this->settings['maps_API_key'] . '&libraries=places', array(), false);

                    wp_register_style('main_style', plugins_url('css/my_shipping_method-woocommerce.css', __FILE__));
                    wp_enqueue_style('main_style');

                }

                /**
                 * Define settings field for this shipping
                 * @return void
                 */
                function init_form_fields()
                {
                    $this->form_fields = array(
                        'enabled' => array(
                            'title' => __('Enable', 'my_shipping_method'),
                            'type' => 'checkbox',
                            'description' => __('Enable this shipping method.', 'my_shipping_method'),
                            'default' => 'yes'
                        ),
                        'USE_LIVE_API' => array(
                            'title' => __('Use Live API', 'my_shipping_method'),
                            'type' => 'checkbox',
                            'description' => __('Check if you want to use the live API or uncheck to use the test API.', 'my_shipping_method'),
                            'default' => 'yes'
                        ),
                        'title' => array(
                            'title' => __('Title', 'my_shipping_method'),
                            'type' => 'text',
                            'description' => __('Title displayed to users', 'my_shipping_method'),
                            'default' => __('Custom Ondemand', 'my_shipping_method')
                        ),
                        'API_username' => array(
                            'title' => __('Custom Ondemand username', 'my_shipping_method'),
                            'type' => 'text',
                            'description' => __('Custom Ondemand merchant username. You can signup here <a href="http://custom.com">http://custom.com</a>', 'my_shipping_method'),
                            'default' => __('myusername', 'my_shipping_method')
                        ),
                        'API_key' => array(
                            'title' => __('Custom Ondemand API key', 'my_shipping_method'),
                            'type' => 'text',
                            'description' => __('Custom Ondemand merchant API key. You can find it in your Custom Ondemand merchant profile', 'my_shipping_method'),
                            'default' => __('mykey', 'my_shipping_method')
                        ),
                        'maps_API_key' => array(
                            'title' => __('Maps API key', 'my_shipping_method'),
                            'type' => 'text',
                            'description' => __('Google maps API key. You can find it Go to the <a href="https://console.developers.google.com/project/_/apiui/apis/enabled">Google API Console</a>' .
                                'Click the Select a project button, then select the same project you set up for the Google Maps JavaScript API and click Open.' .
                                'From the list of APIs on the Dashboard, look for Google Places API Web Service.' .
                                'If you see the API in the list, you are all set. If the API is not listed, enable it:' .
                                'At the top of the page, select ENABLE API to display the Library tab. Alternatively, from the left side menu, select Library.' .
                                'Search for Google Places API Web Service, then select it from the results list.' .
                                'Select ENABLE. When the process finishes, Google Places API Web Service appears in the list of APIs on the Dashboard.'

                                , 'my_shipping_method'),
                            'default' => __('mapskey', 'my_shipping_method')
                        ),
                    );
                }

                /**
                 * This function is used to calculate the shipping cost. Within this function we can check for weights, dimensions and other parameters.
                 *
                 * @access public
                 * @param mixed $package
                 * @return void
                 */
                public function calculate_shipping($package = Array())
                {
                    $cost = 150;
                    $weight = 0;

                    parse_str($_POST['post_data'], $order_data);

                    $to_name = "";
                    $to_lat = "";
                    $to_long = "";
                    $recepient_name = "";
                    $recepient_phone = "";
                    $recepient_email = "";

                    if ($order_data['ship_to_different_address']) {
                        $to_name = $order_data['shipping_address_1'];
                        $to_lat = $order_data['shipping_lat'];
                        $to_long = $order_data['shipping_lng'];
                        $recepient_name = $order_data['shipping_first_name'] . " " . $order_data['shipping_last_name'];
                        $recepient_phone = isset($order_data['shipping_phone']) ? $order_data['shipping_phone'] : $order_data['billing_phone'];
                        $recepient_email = isset($order_data['shipping_email']) ? $order_data['shipping_email'] : $order_data['billing_email'];

                    } else {
                        $to_name = $order_data['billing_address_1'];
                        $to_lat = $order_data['billing_lat'];
                        $to_long = $order_data['billing_lng'];
                        $recepient_name = $order_data['billing_first_name'] . " " . $order_data['billing_last_name'];
                        $recepient_phone = $order_data['billing_phone'];
                        $recepient_email = $order_data['billing_email'];
                    }

                    foreach ($package['contents'] as $item_id => $values) {
                        $_product = $values['data'];
                        if ($_product->has_weight()) {
                            $weight = $weight + $_product->weight() * $values['quantity'];
                        }
                    }


                    $api_username = $this->settings['API_username'];
                    $api_key = $this->settings['API_key'];
                    $data = '';//data passed to the api. Tested to be okay.

                    $curl = curl_init();

                    curl_setopt_array($curl, array(
                        CURLOPT_URL =>$this->CUSTOM_URL,
                        CURLOPT_RETURNTRANSFER => true,
                        CURLOPT_ENCODING => "",
                        CURLOPT_MAXREDIRS => 10,
                        CURLOPT_TIMEOUT => 30,
                        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                        CURLOPT_CUSTOMREQUEST => "POST",
                        CURLOPT_POSTFIELDS => $data,
                        CURLOPT_HTTPHEADER => array(
                            "cache-control: no-cache",
                            "content-type: application/json"
                        ),
                    ));

                    $response = curl_exec($curl);
                    $err = curl_error($curl);

                    curl_close($curl);

                    if ($err) {

                        $cost = 200;
                    } else {
//                        echo $response;
                        $result = json_decode($response, true);
                        $cost = $result['data']['amount'];
                    }


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

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

    add_action('woocommerce_shipping_init', 'my_shipping_method');
    function add_my_shipping_method($methods)
    {
        $methods['my_shipping_method'] = 'my_shipping_method';
        return $methods;
    }

    add_filter('woocommerce_shipping_methods', 'add_my_shipping_method');

    function my_shipping_method_validate_order($posted)
    {

        $packages = WC()->shipping->get_packages();

        $chosen_methods = WC()->session->get('chosen_shipping_methods');

        if (is_array($chosen_methods) && in_array('my_shipping_method', $chosen_methods)) {

            foreach ($packages as $i => $package) {

                if ($chosen_methods[$i] != "my_shipping_method") {

                    continue;

                }

                $my_shipping_method = new my_shipping_method();
                $weight = 0;

                foreach ($package['contents'] as $item_id => $values) {
                    $_product = $values['data'];
                    if ($_product->has_weight()) {
                        $weight = $weight + $_product->weight * $values['quantity'];
                    }
                }

                $weight = wc_get_weight($weight, 'kg');
            }
        }
    }

//    add_action('woocommerce_review_order_before_cart_contents', 'my_shipping_method_validate_order', 10);
//    add_action('woocommerce_after_checkout_validation', 'my_shipping_method_validate_order', 10);

    // Hook in
    add_filter('woocommerce_checkout_fields', 'my_shipping_method_override_checkout_fields');

    // Our hooked in function - $fields is passed via the filter!
    function my_shipping_method_override_checkout_fields($fields)
    {
        // load the autocomplete script
        wp_enqueue_script('my_shipping_method-woocommerce', plugin_dir_url(__FILE__) . 'js/my_shipping_method-woocommerce.js', array('mapsPlaces'));

        $fields['shipping']['shipping_lat'] = array(
            'label' => __('Latitude', 'my_shipping_method'),
            'placeholder' => _x('Lat', 'placeholder', 'my_shipping_method'),
            'required' => true,
            'class' => array('form-row-first', 'placesAutoComplete', 'hidden'),
            'label_class' => array('hidden'),
            'clear' => true
        );
        $fields['shipping']['shipping_lng'] = array(
            'label' => __('Longitude', 'my_shipping_method'),
            'placeholder' => _x('long', 'placeholder', 'my_shipping_method'),
            'required' => true,
            'class' => array('form-row-last', 'placesAutoComplete', 'hidden'),
            'label_class' => array('hidden'),
            'clear' => true
        );
        $fields['billing']['billing_lat'] = array(
            'label' => __('Latitude', 'my_shipping_method'),
            'placeholder' => _x('Lat', 'placeholder', 'my_shipping_method'),
            'required' => true,
            'class' => array('form-row-first', 'placesAutoComplete', 'hidden'),
            'label_class' => array('hidden'),
            'clear' => true
        );
        $fields['billing']['billing_lng'] = array(
            'label' => __('Longitude', 'my_shipping_method'),
            'placeholder' => _x('long', 'placeholder', 'my_shipping_method'),
            'required' => true,
            'class' => array('form-row-last', 'placesAutoComplete', 'hidden'),
            'label_class' => array('hidden'),
            'clear' => true
        );


        return $fields;
    }

    /**
     * Display field value on the order edit page
     */

    add_action('woocommerce_admin_order_data_after_shipping_address', 'my_shipping_method_custom_checkout_field_display_admin_order_meta', 10, 1);

    function my_shipping_method_custom_checkout_field_display_admin_order_meta($order)
    {
        echo '<p><strong>' . __('Delivery location') . ':</strong> ' . get_post_meta($order->get_id(), '_shipping_location', true) . '</p>';
    }

    /**
     * Process the checkout
     */
    add_action('woocommerce_checkout_process', 'location_checkout_field_process');

    function location_checkout_field_process()
    {
//        // Check if set, if its not set add an error.
//        if (!$_POST['shipping_location'] && !$_POST['billing_location'])
//            wc_add_notice(__('Please enter a biling location.'), 'error');
//
//    }
        // FORCE SHIPPING COST RECALCULATION

        WC()->cart->calculate_shipping();
        WC()->cart->calculate_totals();

    }
}