Advanced WooCommerce Customization Guide

 

Advanced WooCommerce Customization Guide: Fees, Checkout Fields, and Product Meta (EEAT Optimized)

Meta Title (Suggested)

Advanced WooCommerce Customization with Hooks: Fees, Checkout Fields & Product Meta (Complete Guide)

Meta Description (Suggested)

Learn advanced WooCommerce customization using hooks and actions. Add custom cart notices, dynamic fees, checkout gift options, and product meta fields with real-world code examples.


WooCommerce is powerful out of the box, but its real strength lies in customization through hooks and actions. As a WordPress and WooCommerce developer, you often need to go beyond default features—whether it’s adding conditional fees, improving checkout UX, or extending product data for business-specific needs.

In this in-depth, EEAT-optimized guide, we will walk through a complete real-world WooCommerce customization example based on the provided code. This article is written from the perspective of an experienced WooCommerce developer and consultant, explaining what the code does, why it’s needed, and how it works internally.

By the end of this article, you’ll clearly understand:

  • How to enable WooCommerce support in a theme

  • How to add custom cart notices

  • How to apply dynamic fees and discounts

  • How to extend the checkout with gift options

  • How to save and display custom order meta

  • How to add custom product meta fields in the admin

  • How to display custom product data on the frontend

This guide is ideal for WooCommerce developers, WordPress freelancers, and store owners who want clean, scalable customizations without third-party plugins.


1. Enabling WooCommerce Support in Your Theme

Before making any WooCommerce customizations, your theme must declare WooCommerce compatibility.

add_theme_support('woocommerce');

Why this matters

This tells WooCommerce that your theme supports its templates and features. Without this, certain layouts and hooks may not work correctly.

Best practice: Always add this in your theme’s functions.php or child theme.


2. Adding a Custom Notice Above the Cart Totals

Displaying contextual messages in the cart improves conversion and user experience.

Code Example

add_action(
    'woocommerce_cart_totals_after_order_total',
    function () {
        echo '<tr class="free-shipping-msg">
                <th></th>
                <td>Free shipping on orders above ₹999</td>
              </tr>';
    }
);

Explanation

  • Hook used: woocommerce_cart_totals_after_order_total

  • This hook runs inside the cart totals table

  • A custom table row is injected below the order total

Real-world use cases

  • Free shipping thresholds

  • Limited-time offers

  • Payment method notices

This approach is lightweight and avoids unnecessary JavaScript or plugins.


3. Adding Dynamic Fees and Discounts Based on Cart Value

WooCommerce allows you to programmatically add fees or discounts using the woocommerce_cart_calculate_fees hook.

Code Example

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

    if (is_admin() && !defined('DOING_AJAX')) return;

    // Fee for orders > ₹600
    if ($cart->subtotal > 600) {
        $cart->add_fee('Special Handling Fee', 100);
    }

    // Discount for orders > ₹500
    if ($cart->subtotal > 500) {
        $discount = $cart->subtotal * 0.5;
        $cart->add_fee('Special Discount', -$discount);
    }
});

Explanation

  • The function runs every time totals are recalculated

  • add_fee() supports negative values, making it perfect for discounts

  • Admin/AJAX check prevents unwanted execution in the backend

Important note

A 50% discount is extremely high and used here for demonstration. In production, always validate business rules carefully.

Use cases

  • COD charges

  • Bulk order discounts

  • Seasonal promotions


4. Adding Gift Options to the Checkout Page

Checkout customization directly impacts conversion. This example adds a gift wrap checkbox and gift message textarea.

Adding Custom Checkout Fields

add_action('woocommerce_after_order_notes', function ($checkout) {
    echo '<div id="custom_checkout_field"><h3>Gift Options</h3>';

    woocommerce_form_field('gift_wrap', array(
        'type'  => 'checkbox',
        'class' => array('form-row-wide'),
        'label' => 'Gift wrap this order?',
    ), $checkout->get_value('gift_wrap') === 'yes' ? '1' : '');

    woocommerce_form_field('gift_message', array(
        'type'  => 'textarea',
        'class' => array('form-row-wide'),
        'label' => 'Gift Message',
        'placeholder' => 'Write your message here',
        'required' => false,
    ), $checkout->get_value('gift_message'));

    echo '</div>';

Why woocommerce_after_order_notes?

This hook places custom fields logically after billing details, maintaining UX consistency.


5. Improving UX with jQuery (Show/Hide Gift Message)

<script type="text/javascript">
    jQuery(function($) {
        var $giftCheckbox = $('#gift_wrap');
        var $giftMessage = $('#gift_message_field');

        function toggleGiftMessage() {
            if ($giftCheckbox.is(':checked')) {
                $giftMessage.show();
            } else {
                $giftMessage.hide();
            }
        }

        toggleGiftMessage();
        $giftCheckbox.on('change', toggleGiftMessage);
    });
</script>
<style>
    #gift_message_field { display: none; }
</style>

Explanation

  • Enhances UX without page reload

  • Keeps checkout clean and uncluttered

  • Uses WooCommerce-generated field IDs


6. Saving Checkout Fields to Order Meta

add_action('woocommerce_checkout_update_order_meta', function ($order_id) {
    $gift_wrap = isset($_POST['gift_wrap']) ? 'yes' : 'no';
    update_post_meta($order_id, 'gift_wrap', $gift_wrap);

    if (isset($_POST['gift_message']) && !empty($_POST['gift_message'])) {
        update_post_meta($order_id, 'gift_message', sanitize_textarea_field($_POST['gift_message']));
    }
});

Best practices applied

  • Sanitization using sanitize_textarea_field

  • Explicit yes/no values for checkboxes


7. Displaying Gift Details in WooCommerce Admin Orders

add_action('woocommerce_admin_order_data_after_billing_address', function ($order) {
    $gift = get_post_meta($order->get_id(), 'gift_wrap', true);
    $message = get_post_meta($order->get_id(), 'gift_message', true);

    if ($gift === 'yes') {
        echo '<p><strong>Gift Wrap:</strong> Yes</p>';
        if ($message) {
            echo '<p><strong>Gift Message:</strong><br>' . nl2br(esc_html($message)) . '</p>';
        }
    }
});

This ensures order handlers never miss important gift instructions.


8. Adding Custom Product Meta Box (Admin Side)

add_action('add_meta_boxes', function () {
    add_meta_box(
        'product_email_box',
        'Product Email Options',
        'product_email_meta_box_html',
        'product',
        'normal',
        'high'
    );
});

Meta Box HTML

function product_email_meta_box_html($post)
{
    $email = get_post_meta($post->ID, '_product_email', true);
    $show_email = get_post_meta($post->ID, '_show_product_email', true);
    wp_nonce_field('product_email_nonce', 'product_email_nonce_field');
?>
    <p>
        <label>Email:</label><br>
        <input type="email" name="product_email" value="<?php echo esc_attr($email); ?>" style="width:100%;">
    </p>
    <p>
        <label>
            <input type="checkbox" name="show_product_email" value="yes" <?php checked($show_email, 'yes'); ?>>
            Show email on product page
        </label>
    </p>
<?php
}

9. Saving Product Meta Securely

add_action('save_post', function ($post_id) {
    if (!isset($_POST['product_email_nonce_field']) || !wp_verify_nonce($_POST['product_email_nonce_field'], 'product_email_nonce')) {
        return;
    }

    if (isset($_POST['product_email'])) {
        update_post_meta($post_id, '_product_email', sanitize_email($_POST['product_email']));
    }

    $show = isset($_POST['show_product_email']) ? 'yes' : 'no';
    update_post_meta($post_id, '_show_product_email', $show);
});

Nonce verification ensures security and data integrity.


10. Displaying Product Email on the Frontend

add_action('woocommerce_single_product_summary', function () {
    global $product;
    $show_email = get_post_meta($product->get_id(), '_show_product_email', true);
    $email = get_post_meta($product->get_id(), '_product_email', true);

    if ($show_email === 'yes' && !empty($email)) {
        echo '<p><strong>Contact Email:</strong> ' . esc_html($email) . '</p>';
    }
}, 25);

Why priority 25?

It places the email neatly after the product price, maintaining visual hierarchy.


11. Adding Custom WooCommerce Order Status (Preparing & Out for Delivery)

Order fulfillment is not always limited to WooCommerce’s default statuses like Processing or Completed. Real-world stores often need intermediate order statuses such as Preparing and Out for Delivery to better manage logistics and keep customers informed.

This section shows how to:

  • Register custom order statuses

  • Display them in the admin order status dropdown

  • Allow admins to update them easily

  • Show the current status clearly on the customer’s order page


Step 1: Register Custom Order Statuses

add_action('init', function () {
    register_post_status('wc-preparing', array(
        'label'                     => 'Preparing',
        'public'                    => true,
        'show_in_admin_status_list' => true,
        'show_in_admin_all_list'    => true,
        'exclude_from_search'       => false,
        'label_count'               => _n_noop('Preparing (%s)', 'Preparing (%s)')
    ));

    register_post_status('wc-out-for-delivery', array(
        'label'                     => 'Out for Delivery',
        'public'                    => true,
        'show_in_admin_status_list' => true,
        'show_in_admin_all_list'    => true,
        'exclude_from_search'       => false,
        'label_count'               => _n_noop('Out for Delivery (%s)', 'Out for Delivery (%s)')
    ));
});

Explanation

  • wc- prefix is mandatory for WooCommerce order statuses

  • show_in_admin_status_list ensures visibility in admin filters

  • These statuses behave like native WooCommerce statuses


Step 2: Add Custom Statuses to WooCommerce Order Status List

add_filter('wc_order_statuses', function ($order_statuses) {
    $new_statuses = array();

    foreach ($order_statuses as $key => $status) {
        $new_statuses[$key] = $status;

        if ($key === 'wc-processing') {
            $new_statuses['wc-preparing'] = 'Preparing';
            $new_statuses['wc-out-for-delivery'] = 'Out for Delivery';
        }
    }

    return $new_statuses;
});

Why this approach?

  • Inserts statuses logically after Processing

  • Keeps fulfillment flow intuitive for admins

Admin can now update order status directly from the order edit screen.


Step 3: Display Custom Order Status on My Account → Order Page

WooCommerce automatically displays order status text, but we can enhance clarity for customers.

add_action('woocommerce_view_order', function ($order_id) {
    $order = wc_get_order($order_id);
    $status = $order->get_status();

    if (in_array($status, array('preparing', 'out-for-delivery'))) {
        echo '<p class="custom-order-status"><strong>Order Status:</strong> ' . wc_get_order_status_name($status) . '</p>';
    }
});

Customer Experience Benefits

  • Customers clearly know if their order is being packed or shipped

  • Reduces "Where is my order?" support tickets

  • Improves trust and transparency


Optional: Styling the Status Message

.custom-order-status {
    padding: 12px;
    background: #f7f7f7;
    border-left: 4px solid #2271b1;
    margin-bottom: 20px;
}

Real-World Use Cases

  • Local delivery businesses

  • Hyperlocal grocery stores

  • Custom logistics workflows

  • Odoo or ERP-integrated WooCommerce stores

These custom statuses integrate perfectly with automation tools, webhooks, and ERP systems.


Add “Made in India” Checkbox in WooCommerce General Settings

What this does

  • ✅ Adds a checkbox in WooCommerce → Settings → General

  • ✅ Admin can enable/disable it globally

  • ✅ Saves value in WordPress options table

  • ✅ Displays “Made in India” on single product pages

  • ✅ Message shows only if checkbox is checked

  • ❌ No impact on products when disabled

1. Add Checkbox in WooCommerce General Settings

add_filter('woocommerce_general_settings', function ($settings) {

    $custom_settings = array();

    foreach ($settings as $setting) {
        $custom_settings[] = $setting;

        // Add setting after store address section
        if (isset($setting['id']) && $setting['id'] === 'woocommerce_store_address') {

            $custom_settings[] = array(
                'name' => 'Product Origin Label',
                'type' => 'title',
                'desc' => 'Global product origin message',
                'id'   => 'product_origin_label_section'
            );

            $custom_settings[] = array(
                'name'    => 'Show “Made in India” Label',
                'desc'    => 'Display “Made in India” message on all product pages',
                'id'      => 'wc_show_made_in_india',
                'type'    => 'checkbox',
                'default' => 'no'
            );

            $custom_settings[] = array(
                'type' => 'sectionend',
                'id'   => 'product_origin_label_section'
            );
        }
    }

    return $custom_settings;
});
Where it appears

📍 WooCommerce → Settings → General

Admin will see:
☑️ Show “Made in India” Label


2. Display Message on Single Product Pages (Frontend)

add_action('woocommerce_single_product_summary', function () {
    $enabled = get_option('wc_show_made_in_india');
    if ($enabled === 'yes') {
        echo '<p class="made-in-india-label">
                <strong>Made in India 🇮🇳</strong>
              </p>';
    }
}, 35); // 35 = below price & short description


Result

  • ✔ Shows message on all single product pages

  • ✔ Hidden automatically when checkbox is unchecked

  • ✔ No product-level configuration required

3. Optional Styling (Recommended)

.made-in-india-label {
    margin-top: 10px;
    padding: 8px 12px;
    background: #f6fff6;
    border-left: 4px solid #138808;
    color: #000;
    font-size: 14px;
}

 

How This Works (Logic Flow)

  1. Admin checks “Show Made in India Label”

  2. WooCommerce saves value as:

    wc_show_made_in_india = yes
  3. Single product page loads

  4. Hook checks option value

  5. Message displays only if enabled


Final Thoughts

This complete WooCommerce customization demonstrates how powerful hooks, actions, and clean PHP logic can be when implemented correctly.

Instead of relying on heavy plugins, you now have:

  • Performance-friendly custom logic

  • Better UX at checkout

  • Cleaner admin workflows

  • Scalable and maintainable code

If you’re a WooCommerce developer or store owner aiming for professional, enterprise-level customization, this approach aligns perfectly with EEAT principles—showing real expertise, practical experience, and trustworthy implementation.


Written by an experienced WooCommerce & WordPress developer with real-world implementation expertise.

h     21.6  
w    628.8  

21.6

628.8

 

 

 

 

 

 

 

 

 

 

 

 

16

 

16

 

 

 

 

 

 

 

 

h     58.4  
w    668.8  

58.4

668.8

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Post a Comment

Please Do Not Enter Any Spam Link or Abuse Word in The Comment Box.

Previous Post Next Post