Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add a dynamic fee based on a select field in WooCommerce Checkout

I am using Update fee dynamically based on radio buttons in Woocommerce checkout answer code solution that worked very well for me to add checkbox fields with a different price for each one, and the price changes are reflected in the checkout.

But I need some help: When I select a type of packaging with additional tax, it appears in the backend in the order area, but only shows the price, and I would like to show the title as well.

The checkbox options have:

'options' => array (
    'bag' => __ ('In a bag' .wc_price (3.00), $ domain),
    'box' => __ ('In a gift box' .wc_price (9.00), $ domain),
),

How to make it show the name on the order? Also if it's possible to change the checkboxes to select field instead?

like image 811
kamuran Avatar asked Sep 03 '19 03:09

kamuran


People also ask

How to add fees to WooCommerce checkout?

1. Add Fees to WooCommerce Checkout from WooCommerce To add additional charges directly through WooCommerce, make sure that you have set up WooCommerce correctly. After that, in your WordPress dashboard go to WooCommerce > Settings and open the Shipping tab. Then, click Add Shipping Zone.

How to add shipping zones in WooCommerce?

After that, in your WordPress dashboard go to WooCommerce > Settings and open the Shipping tab. Then, click Add Shipping Zone. Here, you can add shipping zones by adding their names, regions, and shipping methods.

How do I add additional fees on the checkout page?

Most of the time, the additional fees that we add on the checkout page are fixed fees. For example, the express delivery and special handling fees that we saw before. To add this type of extra charge, use the following code and edit the required text for the field name. In our case, we’ll call it “ Additional Charge ” and the fee will be $5.

How do I add fields for extra fees without conditional logic?

Adding fields for extra fees without conditional logic is pretty straightforward. For example, let’s create a field so that customers can select fast delivery during checkout. We’ll use simple radio buttons for it but you can use other field options depending on your needs.


1 Answers

I have made some changes to the original code that will:

  • Display a custom select field (instead of radio buttons input fields)
  • Display a custom error notice if customer has not selected a packing option
  • Display the selected packing type everywhere (on orders and email notifications)

The code:

// Add a custom select fields for packing option fee
add_action( 'woocommerce_review_order_after_shipping', 'checkout_shipping_form_packing_addition', 20 );
function checkout_shipping_form_packing_addition( ) {
    $domain = 'woocommerce';

    echo '<tr class="packing-select"><th>' . __('Packing options', $domain) . '</th><td>';

    $chosen   = WC()->session->get('chosen_packing');

    // Add a custom checkbox field
    woocommerce_form_field( 'chosen_packing', array(
        'type'      => 'select',
        'class'     => array( 'form-row-wide packing' ),
        'options'   => array(
            ''    => __("Choose a packing option ...", $domain),
            'bag' => sprintf( __("In a bag (%s)", $domain), strip_tags( wc_price(3.00) ) ),
            'box' => sprintf( __("In a gift box (%s)", $domain), strip_tags( wc_price(9.00) ) ),
        ),
        'required'  => true,
    ), $chosen );

    echo '</td></tr>';
}

// jQuery - Ajax script
add_action( 'wp_footer', 'checkout_shipping_packing_script' );
function checkout_shipping_packing_script() {
    // Only checkout page
    if ( is_checkout() && ! is_wc_endpoint_url() ) :

    WC()->session->__unset('chosen_packing');
    ?>
    <script type="text/javascript">
    jQuery( function($){
        $('form.checkout').on('change', 'select#chosen_packing', function(){
            var p = $(this).val();
            console.log(p);
            $.ajax({
                type: 'POST',
                url: wc_checkout_params.ajax_url,
                data: {
                    'action': 'woo_get_ajax_data',
                    'packing': p,
                },
                success: function (result) {
                    $('body').trigger('update_checkout');
                    console.log('response: '+result); // just for testing | TO BE REMOVED
                },
                error: function(error){
                    console.log(error); // just for testing | TO BE REMOVED
                }
            });
        });
    });
    </script>
    <?php
    endif;
}

// Php Ajax (Receiving request and saving to WC session)
add_action( 'wp_ajax_woo_get_ajax_data', 'woo_get_ajax_data' );
add_action( 'wp_ajax_nopriv_woo_get_ajax_data', 'woo_get_ajax_data' );
function woo_get_ajax_data() {
    if ( isset($_POST['packing']) ){
        $packing = sanitize_key( $_POST['packing'] );
        WC()->session->set('chosen_packing', $packing );
        echo json_encode( $packing );
    }
    die(); // Alway at the end (to avoid server error 500)
}

// Add a custom dynamic packaging fee
add_action( 'woocommerce_cart_calculate_fees', 'add_packaging_fee', 20, 1 );
function add_packaging_fee( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    $domain      = "woocommerce";
    $packing_fee = WC()->session->get( 'chosen_packing' ); // Dynamic packing fee

    if ( $packing_fee === 'bag' ) {
        $label = __("Bag packing fee", $domain);
        $cost  = 3.00;
    } elseif ( $packing_fee === 'box' ) {
        $label = __("Gift box packing fee", $domain);
        $cost  = 9.00;
    }

    if ( isset($cost) )
        $cart->add_fee( $label, $cost );
}

// Field validation, as this packing field is required
add_action('woocommerce_checkout_process', 'packing_field_checkout_process');
function packing_field_checkout_process() {
    // Check if set, if its not set add an error.
    if ( isset($_POST['chosen_packing']) && empty($_POST['chosen_packing']) )
        wc_add_notice( __( "Please choose a packing option...", "woocommerce" ), 'error' );
}

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

enter image description here

The error message when customer hasn't chosen a packing option:

enter image description here

like image 74
LoicTheAztec Avatar answered Sep 30 '22 16:09

LoicTheAztec