Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
310 views
in Technique[技术] by (71.8m points)

php - Dynamic shipping fee based on custom radio buttons in Woocommerce

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:

$(document).on('change','#shipping_method_0_local_pickup5',function(e) {              
            $('.woocommerce-shipping-fields').css({
                'display': 'none'
            });

                        $("#deli").css("display","block"); 
                        var selected = $("input[type='radio'][name='post-del']:checked");
                        var selectedVal = selected.val();               
                        var pickurl= "<?php echo admin_url('admin-ajax.php');?>?action=delivery";
                        $.ajax({   
                            url: pickurl,
                            type: "POST",
                            data:{
                                input:selectedVal,                       
                            },            
                            success: function(responseText) 
                            { 
                                jQuery(".order-total .woocommerce-Price-amount").html(responseText);
                                //$(".discount_code").css("display","block"); 
                            }
                        }); 

        });

when the radio button click I want to add addition price $2 on my total.

add_action( 'wp_ajax_delivery', 'delivery' );
add_action( 'wp_ajax_nopriv_delivery', 'delivery' );

function delivery()
{      
    //My code  
    do_action( 'woocommerce_cart_calculate_fees', 'prefix_add_discount_line' ); // not working
    exit;
}

Note: This is the hook which updates the code

add_action( 'woocommerce_cart_calculate_fees', 'prefix_add_discount_line' );
function prefix_add_discount_line( $cart ) {

    $discount = $cart->subtotal + 2;

    $cart->add_fee( __( 'Delivery', 'yourtext-domain' ) , +$discount );

}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

enter image description here

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...