Dynamic shipping fee based on custom radio buttons in Woocommerce

前端 未结 1 728
再見小時候
再見小時候 2020-11-30 13:21

In Woocommerce, I have added two custom radio buttons on the checkout page and on click, I called an ajax function to add a delivery fee.

Here is my code:



        
相关标签:
1条回答
  • 2020-11-30 13:49

    You should give all necessary related code in your question. Remember that "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself".

    So, in the code below, you will find a complete working solution, with additional custom radio buttons, that will add dynamically a delivery fee depending on the selected radio button and for "local pickup" shipping method.

    The code (where you will need to define your targeted "local pickup" method ID):

    // Enabling delivery options for a specific defined shipping method
    function targeted_shipping_method(){
        // HERE below define the shipping method Id that enable the custom delivery options
        return 'local_pickup:5';
    }
    
    // Customizing Woocommerce checkout radio form field
    add_action( 'woocommerce_form_field_radio', 'custom_form_field_radio', 20, 4 );
    function custom_form_field_radio( $field, $key, $args, $value ) {
        if ( ! empty( $args['options'] ) && is_checkout() ) {
            $field = str_replace( '</label><input ', '</label><br><input ', $field );
            $field = str_replace( '<label ', '<label style="display:inline;margin-left:8px;" ', $field );
        }
        return $field;
    }
    
    // Add a custom radio fields for packaging selection
    add_action( 'woocommerce_review_order_after_shipping', 'checkout_shipping_form_delivery_addition', 20 );
    function checkout_shipping_form_delivery_addition(){
        $domain = 'wocommerce';
    
        if (  WC()->session->get( 'chosen_shipping_methods' )[0] == targeted_shipping_method() ) :
    
            echo '<tr class="delivery-radio"><th>' . __('Delivery options', $domain) . '</th><td>';
    
            $chosen = WC()->session->get('chosen_delivery');
            $chosen = empty($chosen) ? WC()->checkout->get_value('delivery') : $chosen;
            $chosen = empty($chosen) ? 'regular' : $chosen;
    
            // Add a custom checkbox field
            woocommerce_form_field( 'radio_delivery', array(
                'type' => 'radio',
                'class' => array( 'form-row-wide' ),
                'options' => array(
                    'regular' => __('Regular', $domain),
                    'premium' => __('Premium +'.wc_price(2.00), $domain),
                ),
                'default' => $chosen,
            ), $chosen );
    
            echo '</td></tr>';
    
        endif;
    }
    
    // jQuery - Ajax script
    add_action( 'wp_footer', 'checkout_delivery_script' );
    function checkout_delivery_script() {
        // Only checkout page
        if ( ! is_checkout() ) return;
        ?>
        <script type="text/javascript">
        jQuery( function($){
            if (typeof wc_checkout_params === 'undefined')
                return false;
    
            $('form.checkout').on('change', 'input[name=radio_delivery]', function(e){
                e.preventDefault();
                var d = $(this).val();
                $.ajax({
                    type: 'POST',
                    url: wc_checkout_params.ajax_url,
                    data: {
                        'action': 'delivery',
                        'delivery': d,
                    },
                    success: function (result) {
                        $('body').trigger('update_checkout');
                        console.log(result); // just for testing | TO BE REMOVED
                    },
                    error: function(error){
                        console.log(error); // just for testing | TO BE REMOVED
                    }
                });
            });
        });
        </script>
        <?php
    
    }
    
    // Get Ajax request and saving to WC session
    add_action( 'wp_ajax_delivery', 'wc_get_delivery_ajax_data' );
    add_action( 'wp_ajax_nopriv_delivery', 'wc_get_delivery_ajax_data' );
    function wc_get_delivery_ajax_data() {
        if ( isset($_POST['delivery']) ){
            WC()->session->set('chosen_delivery', sanitize_key( $_POST['delivery'] ) );
            echo json_encode( $delivery ); // Return the value to jQuery
        }
        die();
    }
    
    // Add a custom dynamic delivery fee
    add_action( 'woocommerce_cart_calculate_fees', 'add_packaging_fee', 20, 1 );
    function add_packaging_fee( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        // Only for targeted shipping method
        if (  WC()->session->get( 'chosen_shipping_methods' )[0] != targeted_shipping_method() )
            return;
    
        if( WC()->session->get( 'chosen_delivery' ) == 'premium' )
            $cart->add_fee( __( 'Delivery fee', 'woocommerce' ), 2.00 );
    }
    

    Code goes in function.php file of your active child theme (or active theme). Tested and works.

    0 讨论(0)
提交回复
热议问题