Add radio buttons to specific shipping method on WooCommerce checkout

前端 未结 1 1746
长情又很酷
长情又很酷 2021-01-28 23:55

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 picku

相关标签:
1条回答
  • 2021-01-29 00:28

    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
    0 讨论(0)
提交回复
热议问题