TECHNICAL GUIDE

WooCommerce Hooks for Checkout, Cart, and Pricing

Extend your WooCommerce checkout pipelines, dynamic wholesale pricing tiers, and conditional fees with update-safe PHP hook snippets.

Optimize B2B and B2C store customer checkout experiences with update-safe PHP hook snippets.

1. B2B Role-Based Dynamic & Tiered Pricing

WHAT IT SOLVES:
Calculates wholesale discounts dynamically based on user role and applies tiered quantity discounts directly in the cart object.
HOOKS: woocommerce_product_get_price woocommerce_product_variation_get_price woocommerce_before_calculate_totals

Dynamically overrides product catalog prices based on user role and quantity discount tiers.

b2b-rolebased-dynamic--tiered-pricing.php
// 1. Catalog Pricing Overrides (Simple & Variable Products)
add_filter('woocommerce_product_get_price', 'ppunch_b2b_role_based_price', 10, 2);
add_filter('woocommerce_product_variation_get_price', 'ppunch_b2b_role_based_price', 10, 2);

function ppunch_b2b_role_based_price($price, $product) {
    if (is_admin() || !is_user_logged_in()) {
        return $price;
    }

    $user = wp_get_current_user();
    if (in_array('wholesale_customer', (array) $user->roles)) {
        // Apply a flat 20% discount for B2B wholesale buyers
        return floatval($price) * 0.8;
    }

    return $price;
}

// 2. Tiered Quantity Discounts inside Cart
add_action('woocommerce_before_calculate_totals', 'ppunch_apply_cart_quantity_tiers', 10, 1);

function ppunch_apply_cart_quantity_tiers($cart) {
    if (is_admin()) {
        return;
    }

    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        $quantity = $cart_item['quantity'];
        $product = $cart_item['data'];
        $base_price = floatval($product->get_regular_price());

        // Apply bulk tiers: 10+ items get 10% off, 20+ items get 15% off
        if ($quantity >= 20) {
            $product->set_price($base_price * 0.85);
        } elseif ($quantity >= 10) {
            $product->set_price($base_price * 0.90);
        }
    }
}
Explanation:

Overrides simple/variable product catalog prices and adjusts cart item totals dynamically before final checkout calculations.

wholesale dynamic pricing tiered cart discounts woocommerce volume discounts

2. Dynamic Minimum-Order Fee

WHAT IT SOLVES:
Appends a handling fee dynamically to the checkout total if the customer's cart subtotal falls below a minimum threshold.
HOOKS: woocommerce_cart_calculate_fees

Adds a surcharge handling fee to cart totals conditionally for low-value orders.

dynamic-minimumorder-fee.php
// 1. Dynamic Low Order Fee Injection
add_action('woocommerce_cart_calculate_fees', 'ppunch_apply_low_order_fee', 10, 1);

function ppunch_apply_low_order_fee($cart) {
    if (is_admin()) {
        return;
    }

    $subtotal = floatval($cart->get_subtotal());
    
    // Apply a $5.00 fee for orders under $50
    if ($subtotal > 0 && $subtotal < 50.00) {
        $cart->add_fee('Low Order Handling Fee', 5.00, true, 'standard');
    }
}
Explanation:

Intercepts cart total calculations, checks if the subtotal is under the threshold, and appends a handling surcharge.

low order fee woocommerce cart surcharges minimum cart totals minimum order fee

3. Custom Corporate Checkout Fields & Meta Sync

WHAT IT SOLVES:
Adds corporate billing fields to checkout, validates the user input, and saves values to order metadata.
HOOKS: woocommerce_checkout_fields woocommerce_checkout_process woocommerce_checkout_create_order

Injects, validates, and syncs custom fields (such as VAT or Tax ID) directly to the Order object.

custom-corporate-checkout-fields--meta-sync.php
// 1. Inject Custom Checkout Fields
add_filter('woocommerce_checkout_fields', 'ppunch_inject_corporate_checkout_fields', 10, 1);

function ppunch_inject_corporate_checkout_fields($fields) {

    $fields['billing']['billing_company_tax_id'] = [
        'type'        => 'text',
        'label'       => 'Company Tax ID / VAT Number',
        'placeholder' => 'Enter corporate registration number',
        'required'    => false,
        'class'       => ['form-row-wide'],
        'clear'       => true,
    ];

    return $fields;
}

// 2. Validate Custom Field Formatting
add_action('woocommerce_checkout_process', 'ppunch_validate_corporate_fields');

function ppunch_validate_corporate_fields() {

    // Require Tax ID if billing company is filled out
    if (!empty($_POST['billing_company']) && empty($_POST['billing_company_tax_id'])) {
        wc_add_notice('<strong>Company Tax ID / VAT Number</strong> is required for corporate orders.', 'error');
    }

    // Basic format validation (alphanumeric limit)
    if (!empty($_POST['billing_company_tax_id'])) {
        if (!preg_match('/^[A-Z0-9-]{4,15}$/i', $_POST['billing_company_tax_id'])) {
            wc_add_notice('Please enter a valid alphanumeric <strong>Company Tax ID / VAT Number</strong>.', 'error');
        }
    }
}

// 3. Save Custom Field directly to WooCommerce Order object
add_action('woocommerce_checkout_create_order', 'ppunch_save_corporate_fields_to_order', 10, 2);

function ppunch_save_corporate_fields_to_order($order, $data) {

    if (isset($_POST['billing_company_tax_id'])) {
        $tax_id = sanitize_text_field($_POST['billing_company_tax_id']);
        // Save using clean Order API wrapper method
        $order->update_meta_data('_billing_company_tax_id', $tax_id);
    }
}
Explanation:

Registers new form fields on checkout, checks input formats on submit, and attaches values to the order object metadata.

custom checkout fields save order metadata validate vat number

4. Smart Cart Item Restrictions & Limit Validations

WHAT IT SOLVES:
Enforces purchase constraints such as preventing mixing wholesale and retail items or limiting cart to a single subscription.
HOOKS: woocommerce_add_to_cart_validation woocommerce_check_cart_items

Prevents incompatible products from being mixed inside the cart checkout page.

smart-cart-item-restrictions--limit-validations.php
// 1. Validate Item Compatibility before adding to Cart
add_filter('woocommerce_add_to_cart_validation', 'ppunch_restrict_mixed_cart_items', 10, 2);

function ppunch_restrict_mixed_cart_items($passed, $product_id) {

    $is_b2b_product = has_term('wholesale-only', 'product_cat', $product_id);

    foreach (WC()->cart->get_cart() as $cart_item) {
        $cart_product_id = $cart_item['product_id'];
        $cart_is_b2b = has_term('wholesale-only', 'product_cat', $cart_product_id);

        // Block mixing B2B wholesale items with regular retail items
        if ($is_b2b_product !== $cart_is_b2b) {
            wc_add_notice('Wholesale items cannot be mixed with standard retail items in the same checkout. Please submit separate orders.', 'error');
            return false;
        }
    }

    return $passed;
}

// 2. Safety scan during checkout page load
add_action('woocommerce_check_cart_items', 'ppunch_verify_cart_compatibility_on_checkout');

function ppunch_verify_cart_compatibility_on_checkout() {

    $has_wholesale = false;
    $has_retail = false;

    foreach (WC()->cart->get_cart() as $cart_item) {
        if (has_term('wholesale-only', 'product_cat', $cart_item['product_id'])) {
            $has_wholesale = true;
        } else {
            $has_retail = true;
        }
    }

    if ($has_wholesale && $has_retail) {
        wc_add_notice('Your cart contains both wholesale and retail items. Please split your order before proceeding to checkout.', 'error');
    }
}
Explanation:

Prevents incompatible B2B/B2C products from entering the cart, running checks at both add-to-cart and checkout initialization.

limit add to cart prevent mixed checkout cart validation rules

5. Conditional Shipping Method Filtering

WHAT IT SOLVES:
Hides specific shipping rates dynamically (like Free Shipping) if the cart contents exceed weight limits.
HOOKS: woocommerce_package_rates

Hides specific shipping methods based on total cart weight.

conditional-shipping-method-filtering.php
// 1. Filter out shipping rates dynamically based on package weight
add_filter('woocommerce_package_rates', 'ppunch_filter_shipping_methods_by_weight', 10, 2);

function ppunch_filter_shipping_methods_by_weight($rates, $package) {

    // If total package weight is over 50 lbs, hide standard free shipping
    $total_weight = WC()->cart->get_cart_contents_weight();

    if ($total_weight > 50.00) {
        foreach ($rates as $rate_key => $rate) {
            // Remove Free Shipping option if it exists
            if ('free_shipping' === $rate->method_id) {
                unset($rates[$rate_key]);
            }
        }
    }

    return $rates;
}
Explanation:

Intercepts active shipping rate packages and filters out standard options (like Free Shipping) if cart contents exceed weight limits.

hide free shipping restrict shipping methods woocommerce shipping weight hooks

6. Non-Blocking Post-Checkout Webhooks

WHAT IT SOLVES:
Sends order telemetry details to external CRMs or ERP webhooks instantly upon checkout completion without delaying the customer's page load.
HOOKS: woocommerce_payment_complete

Fires custom background webhook requests to external systems when checkouts are completed.

nonblocking-postcheckout-webhooks.php
// 1. Fire Webhook Sync on Successful Payment
add_action('woocommerce_payment_complete', 'ppunch_fire_non_blocking_checkout_webhook', 10, 1);

function ppunch_fire_non_blocking_checkout_webhook($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) {
        return;
    }

    // Guard: Prevent duplicate webhook execution
    if ($order->get_meta('_ppunch_webhook_sent')) {
        return;
    }

    // Set flag immediately to prevent race conditions or multiple triggers
    $order->update_meta_data('_ppunch_webhook_sent', 'yes');
    $order->save();

    $webhook_url = 'https://api.yourcrm.com/v1/orders';
    $payload = [
        'order_id'      => $order_id,
        'order_total'   => $order->get_total(),
        'customer_email'=> $order->get_billing_email(),
        'items_count'   => $order->get_item_count(),
    ];

    wp_remote_post($webhook_url, [
        'method'    => 'POST',
        'blocking'  => false, // Essential: Does not wait for external response to keep checkout fast
        'body'      => json_encode($payload),
        'headers'   => [
            'Content-Type' => 'application/json',
        ],
        'timeout'   => 3,
    ]);
}
Explanation:

Triggers an asynchronous, non-blocking HTTP request on successful payment completion, avoiding CRM lag during checkout redirect.

woocommerce webhook sync non blocking wp remote post checkout webhook integrations
KNOWLEDGE BASE

Common Questions

Yes. If you need custom wholesale tiers, advanced checkout validations, or conditional surcharges built and tested safely away from your live customers, we can write the custom plugin for you. Get a free quote to discuss your project directly with our technical team.
Yes. The snippets in this guide are common examples, but we regularly build custom WooCommerce logic for unique store requirements. Get a free quote to discuss your project with our technical lead.
// AUTHOR Muneeb K. Lead WordPress Developer

16 years building custom WordPress plugins for WooCommerce, MemberPress, and LearnDash platforms — 500+ projects delivered. Focused on performance, stability, and clean architecture.

WooCommerce Solutions

Are you looking to customize your WooCommerce cart and checkout?

We write clean, update-safe hooks, custom fees logic, and optimized checkout pipelines. Talk to us.

// TECH STACK

Tools We Master
Inside Out.

Starting with WordPress at the core, we use a curated stack of powerful tools to build fast, stable, and scalable systems for your business.