Add radio buttons to specific shipping method on WooCommerce checkout

旧巷老猫 提交于 2021-02-04 08:10:28

问题


I added a new shipping method "pickup from store" with free shipping to WooCommerce.

I have 2 stores, "Barsha" and "Deira". I would like when customer choose pickup from a store to be able to select which store he will visit.

Here is what I added to cart-shipping.php template file:

<?php                   
    <hr><p>Please choose the pickup store:</p>
        <input type="radio" id="barsha" sname="store" value="barsha">
        <label for="barsha">Barsha<a href=""> Check Location</a></label><br>
        <input type="radio" id="deira" sname="store" value="deira">
        <label for="deira">Deira<a href=""> Check Location</a></label>

    $sname= sname;
    if ( $sname = 'barsha'); {
        printf ('barsha')
    } else {
        printf ('deira')
    }
?>

But I can't get it working. How can I add some radio buttons to a specific shipping method and save the chosen option when order is submitted?

回答1:


I suppose that in your case, you want to display some fields under "Local pickup" WooCommerce enabled shipping method.

Instead of overriding cart-shipping.php template, you can better use the dedicated action hook for shipping methods that will allow you to display fields for a specific shipping method.

The following code will allow you to display 2 radio buttons under "Local pickup" shipping method, when it's selected. If customer forget to choose a store, a message will remind him to chose a store for pickup. Then when order will be placed, the chosen store will be saved as custom order meta data, displayed in admin order under the billing address and everywhere near the chosen shipping method (orders and email notifications):

// Add custom fields to a specific selected shipping method
add_action( 'woocommerce_after_shipping_rate', 'pickup_store_custom_field', 100, 2 );
function pickup_store_custom_field( $method, $index ) {
    // Only on checkout page and for Local pickup shipping method
    if( is_cart() || $method->method_id !== 'local_pickup' )
        return;

    $chosen_shipping_methods = WC()->session->get('chosen_shipping_methods')[ $index ];

    $chosen_method_id = explode(':', $chosen_shipping_methods);
    $chosen_method_id = reset($chosen_method_id);

    // Only when the chosen shipping method is "local_pickup"
    if( $chosen_method_id !== 'local_pickup' )
        return;

    echo '<div class="wrapper-pickup_store" style="margin-top:16px">
        <label class="title">' . __("Choose your pickup store") . ':</label><br>
        <label for="barsha-store">
            <input type="radio" id="barsha-store" name="pickup_store" value="Barsha">' 
            . __("Barsha") . '<a href="#"><small> '. __("Check Location") . '</small></a>
        </label><br>
        <label for="deira-store">
            <input type="radio" id="deira-store" name="pickup_store" value="Deira">' 
            . __("Deira") . '<a href="#"><small> '. __("Check Location") . '</small></a>
        </label>
    </div>';
}

// Pickup store field validation
add_action('woocommerce_checkout_process', 'pickup_store_checkout_validation');
function pickup_store_checkout_validation() {

    $chosen_shipping_methods = WC()->session->get('chosen_shipping_methods')['0'];

    $chosen_method_id = explode(':', $chosen_shipping_methods);
    $chosen_method_id = reset($chosen_method_id);

    if( $chosen_method_id === 'local_pickup' && empty( $_POST['pickup_store'] ) )
        wc_add_notice( __("Please choose a pickup store"), "error" );
}

// Save chosen Pickup store as custom order meta data
add_action( 'woocommerce_checkout_create_order', 'pickup_store_update_order_meta' );
function pickup_store_update_order_meta( $order ) {
    if( isset( $_POST['pickup_store'] ) && ! empty( $_POST['pickup_store'] ) )
        $order->update_meta_data( 'pickup_store', esc_attr( $_POST['pickup_store'] ) );
}

// Display the chosen pickup store under billing address
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_pickup_store_on_order_edit_pages' );
function display_pickup_store_on_order_edit_pages( $order ){
    if( $pickup_store = $order->get_meta( 'pickup_store' ) )
        echo '<p><strong>Pickup store:</strong> '.$pickup_store.'</p>';
}

// Display the chosen pickup store below the chosen shipping method everywhere
add_filter( 'woocommerce_get_order_item_totals', 'display_pickup_store_on_order_item_totals', 1000, 3 );
function display_pickup_store_on_order_item_totals( $total_rows, $order, $tax_display ){
    if( $pickup_store = $order->get_meta( 'pickup_store' ) ) {
        $new_total_rows = [];

        // Loop through order total rows
        foreach( $total_rows as $key => $values ) {
            $new_total_rows[$key] = $values;
            // Inserting the pickup store under shipping method
            if( $key === 'shipping' ) {
                $new_total_rows['pickup_store'] = array(
                    'label' => __("Pickup store"),
                    'value' => $pickup_store
                );
            }
        }
        return $new_total_rows;
    }

    return $total_rows;
}

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


On checkout page:

On customer Orders (and email notifications):

On admin order edit pages (under the billing address):


Related answers:

  • Shipping carrier custom fields validation in Woocommerce checkout page
  • Add a checkbox below a specific shipping method in WooCommerce 3


来源:https://stackoverflow.com/questions/62191919/add-radio-buttons-to-specific-shipping-method-on-woocommerce-checkout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!