2
votes

I am writing a WordPress plugin in which I need to add two radio buttons before the order total in the WooCommerce Order review section. I figured out how to add custom radio buttons to the order review section but I am unable to get the idea how to move delivery options just before the order total.

Please check the screenshot to understand what exactly I want to achieve.

enter image description here

Here's my code:

// Part 1 - Display Radio Buttons
add_action( 'woocommerce_review_order_before_payment', 'custom_checkout_radio_choice' );
function custom_checkout_radio_choice() {
     
   $chosen = WC()->session->get( 'radio_chosen' );
   $chosen = empty( $chosen ) ? WC()->checkout->get_value( 'radio_choice' ) : $chosen;
   $chosen = empty( $chosen ) ? '0' : $chosen;
        
   $args = array(
       'type' => 'radio',
       'class' => array( 'form-row-wide', 'update_totals_on_change' ),
        'options' => array(
            '2.95' => '60 MINUTES: €2.95',
            '0' => '24 - 48 HOURS',
        ),
        'default' => $chosen
   );
     
   echo '<div id="checkout-radio">';
   echo '<h3>Delivery Options</h3>';

   woocommerce_form_field( 'radio_choice', $args, $chosen );

   echo '</div>'; 
}
  
// Part 2 - Add Fee and Calculate Total
add_action( 'woocommerce_cart_calculate_fees', 'custom_checkout_radio_choice_fee', 20, 1 );
function custom_checkout_radio_choice_fee( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) 
        return;
    
    $radio = WC()->session->get( 'radio_chosen' );

    if ( $radio ) {
        $cart->add_fee( 'Delivery Fee', $radio );
    }
}
  
// Part 3 - Add Radio Choice to Session
add_action( 'woocommerce_checkout_update_order_review', 'custom_checkout_radio_choice_set_session' );
function custom_checkout_radio_choice_set_session( $posted_data ) {
    parse_str( $posted_data, $output );
    if ( isset( $output['radio_choice'] ) ){
        WC()->session->set( 'radio_chosen', $output['radio_choice'] );
    }
}

Please help me out with this.

1
Can't you just add those options as shipping methods? and use the built-in functionality in WooCommerce? if not, or I am missing something,then be sure to check it out the checkout/review-order.php template and how this is applied for fees. Also, do not forget that these are tables. <div> used in a table is printed above or below it, so use table tags for the output instead7uc1f3r
@7uc1f3r I'm very new to WordPress and it's my requirement to handle this with a custom plugin only. These options should disappear as soon as the plugin is deactivated. There's a lot more but I am stuck at here.luckyali444
Thanks @7uc1f3r for the clue. I did some digging on checkout/review-order.php file and it seems like I'm pretty close to my solution. I don't know whether that's a good practice or not, but I am pretty close. :)luckyali444

1 Answers

1
votes

To move your radio buttons before order total you will need to use another hook. But you can't have that delivery radio buttons on the fee total line…

I have simplified and revisited the code:

add_action( 'woocommerce_review_order_before_order_total', 'checkout_delivery_radio_buttons' );
function checkout_delivery_radio_buttons() {
    echo '<tr class="delivery-radio">
            <th>'.__("Delivery Options").'</th><td>';

    $chosen = WC()->session->get( 'delivery' );
    $chosen = empty( $chosen ) ? WC()->checkout->get_value( 'delivery' ) : $chosen;
    $chosen = empty( $chosen ) ? '0' : $chosen;

    woocommerce_form_field( 'delivery',  array(
        'type'      => 'radio',
        'class'     => array( 'form-row-wide', 'update_totals_on_change' ),
        'options'   => array(
            '2.95'  => '60 MINUTES: €2.95',
            '0'     => '24 - 48 HOURS',
        ),
    ), $chosen );
    
    echo '</td></tr>';
}

add_action( 'woocommerce_cart_calculate_fees', 'checkout_delivery_fee', 20, 1 );
function checkout_delivery_fee( $cart ) {
    if ( $radio = WC()->session->get( 'delivery' ) ) {
        $cart->add_fee( 'Delivery Fee', $radio );
    }
}

add_action( 'woocommerce_checkout_update_order_review', 'checkout_delivery_choice_to_session' );

function checkout_delivery_choice_to_session( $posted_data ) {
    parse_str( $posted_data, $output );
    if ( isset( $output['delivery'] ) ){
        WC()->session->set( 'delivery', $output['delivery'] );
    }
}

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