Wholesale Suite plugins expose PHP hooks and filters. You can use them to change prices, forms, emails, quotes, and payment behaviour without editing plugin files. This article shows you how to add your own code to a hook, and lists the hooks that are meant for use in your own code, with their arguments and what they change. It is a selection, not every hook the plugins fire.
Each table lists the hook name, its type, its arguments, and what it changes. A filter must return a value. An action does not return a value.
Add your code to a hook
- Choose where to add your code: the
functions.phpfile of a child theme, or a code snippets plugin. - Find the hook you need in the plugin tables below. Note its type and its arguments.
- Add your snippet with
add_filter()for a filter oradd_action()for an action. The examples in the plugin sections show the pattern. - Save the file.
- Test the change on a staging site before you add it to your live store.
Do not edit the plugin files. A plugin update replaces them and removes your change.
Hooks from a Wholesale Suite plugin only run when that plugin is active. For example, the WooCommerce Wholesale Prices Premium hooks need WooCommerce Wholesale Prices Premium on your site.
The hook details in this article match these plugin versions: WooCommerce Wholesale Prices 2.3.1, WooCommerce Wholesale Prices Premium 2.1.5, WooCommerce Wholesale Order Form 3.1.3, WooCommerce Wholesale Lead Capture 2.0.7, WooCommerce Wholesale Quotes 1.0.3, WooCommerce Wholesale Payments 1.0.8, and Invoice Gateway for WooCommerce 1.1.7.
WooCommerce Wholesale Prices
WooCommerce Wholesale Prices adds hooks around the wholesale price fields in the WooCommerce quick edit panel. It also has a filter to turn off the AI abilities of Wholesale Suite. For more on abilities, see How to use AI abilities in Wholesale Suite.
| Hook | Type | Arguments | What it changes |
|---|---|---|---|
wwp_before_quick_edit_wholesale_price_fields | Action | $all_wholesale_roles (array, registered wholesale roles) | Runs in the quick edit panel, before the Wholesale Price fields. Use it to print your own markup. It does not run when the wwp_product_editor_show_wholesale_prices_fields filter returns false. |
wwp_after_quick_edit_wholesale_price_fields | Action | $all_wholesale_roles (array, registered wholesale roles) | Runs in the quick edit panel, after the Wholesale Price fields. It follows the same rule as the before hook. |
wwp_quick_edit_allowed_product_types | Filter | $allowed_product_types (array, default simple and external)$context (string, wholesale_price_fields) | Sets which product types show and save the wholesale price fields in quick edit. It also sets which products get the wholesale price data in the product list. |
wwp_product_editor_show_wholesale_prices_fields | Filter | $show (bool, default true) | Return false to hide the wholesale price fields in the product editor and in quick edit. |
wwp_disable_abilities | Filter | $disabled (bool, default false) | Return true to turn off the Wholesale Suite AI abilities. This also turns off the abilities of the other Wholesale Suite plugins, because they register through WooCommerce Wholesale Prices. |
Example: add a note under the wholesale price fields
This example prints a short note after the wholesale price fields in quick edit.
add_action( 'wwp_after_quick_edit_wholesale_price_fields', function ( $all_wholesale_roles ) {
echo '<p>' . esc_html__( 'Enter prices without tax.', 'your-text-domain' ) . '</p>';
} );
WooCommerce Wholesale Prices Premium
WooCommerce Wholesale Prices Premium has hooks for quantity discounts, cart discounts, minimum order checks, reports, and the REST API. All hooks in this section need WooCommerce Wholesale Prices Premium.
| Hook | Type | Arguments | What it changes |
|---|---|---|---|
wwpp_quantity_based_discount_base_price | Filter | $base_price (float|string, the price that quantity tiers work from)$mapping (array, quantity discount rules)$raw_wholesale_price (float|string)$product (WC_Product)$wholesale_role (array) | Changes the base price that quantity-based discount tiers apply to. The base is the active wholesale sale price if there is one, otherwise the wholesale price. When the store setting that uses the regular price for discount calculation is on, the base is the regular price. |
wwpp_cart_subtotal_discount_eligible_item | Filter | $is_eligible (bool, default true)$cart_item (array, cart item data)$wholesale_role (array) | Decides if a cart item counts toward the subtotal used for the cart subtotal discount. Return false to leave the item out. |
wwpp_min_order_requirement_check | Filter | $apply (bool, the result of the check)$cart_total (float, wholesale cart total)$cart_items (float, total item quantity)$cart (WC_Cart)$wholesale_role (array) | Changes the result of the minimum order check for cart discounts. The cart subtotal discount only applies when the result is exactly true. |
wwpp_add_wholesale_role_general_discount_mapping | Action | None | Runs after a general discount is saved for a wholesale role. |
wwpp_edit_wholesale_role_general_discount_mapping | Action | None | Runs after the general discount of a wholesale role is updated. |
wwpp_process_category_products_in_api | Filter | $products_in_api (bool, default false)$category_id (int, the category term ID) | Sets which code updates the wholesale price flags of the products in a category. When it returns true, the category discount REST API does the update and the category edit screen skips it. |
wwpp_meta_data | Filter | $meta_data (array, wholesale data, empty values removed)$product (WC_Product)$request (WP_REST_Request) | Changes the wholesale data that the wholesale products REST API returns for a product. |
wwpp_api_update_wholesale_roles_filter | Filter | $wholesale_roles (array, all registered roles)$request (WP_REST_Request) | Changes the list of wholesale roles before the REST API saves it. It runs when a role is created or updated through the API. |
wwpp_reports_sales_transient_expiration_constant | Filter | $expiration (int, seconds, default HOUR_IN_SECONDS) | Sets how long the sales report response stays cached. |
wwpp_disable_abilities | Filter | $disabled (bool, default false) | Return true to turn off the abilities that this plugin registers. |
Example: exclude a product category from the cart subtotal discount
This example leaves items in the gift-cards category out of the subtotal that the cart subtotal discount uses.
add_filter( 'wwpp_cart_subtotal_discount_eligible_item', function ( $is_eligible, $cart_item, $wholesale_role ) {
if ( has_term( 'gift-cards', 'product_cat', $cart_item['product_id'] ) ) {
return false;
}
return $is_eligible;
}, 10, 3 );
WooCommerce Wholesale Order Form
WooCommerce Wholesale Order Form has hooks for the order form REST requests, product search, variation loading, and form scripts.
| Hook | Type | Arguments | What it changes |
|---|---|---|---|
wwof_rest_read_permissions | Filter | $permission (bool, the result of the order form rules)$object_id (int|string, the object ID, or 0 for a collection)$post_type (string, post type or taxonomy) | Grants or refuses a REST read that the order form rules refused. It runs only for view-context reads on the routes the order form uses. A true value never reaches an object that is not published. |
wwof_wc_rest_prepare_product_object | Filter | $response (WP_REST_Response)$wc_data (WC_Product)$request (WP_REST_Request)$wc (WC, the order form WooCommerce integration object) | Changes the product data that the order form REST request returns for a product. |
wwof_product_type_terms | Filter | $product_type_terms (array, product type slugs) | Sets the product types the order form lists. The default is simple, grouped, and external when variations show individually. Otherwise it also includes variable. Add a type, such as bundle, to list it. |
wwof_search_post_clauses_request | Filter | $clauses (array, SQL clauses)$wc (WC, the order form WooCommerce integration object) | Changes the SQL clauses of the product search in the order form. |
wwof_force_load_form_posts | Filter | $form_posts (array, default empty) | Forces the order form script to load on a page. Return an array of order form objects keyed by form ID when the shortcode is not detected. |
wwof_login_url | Filter | $login_url (string) | Changes the login URL that the order form script uses. |
wwof_min_requirement_current_user_id | Filter | $user_id (int, default is the current user ID) | Changes the user ID that the order form uses to look up minimum order requirements. |
wwof_required_plugins | Filter | $required_plugins (array, plugin file paths) | Changes the list of plugins that must be active. The order form reports each listed plugin that is not active. |
wwof_after_register_order_form_post_type | Action | $post_type (string, the order form post type name) | Runs after the order form post type is registered. |
wwof_variations_max_requests | Filter | $variations_max_requests (int, default 12) | Sets how many variation list requests the order form sends at the same time. The lowest value is 1. |
wwof_variations_response_cache_bypass | Filter | $bypass (bool, default false)$request (WP_REST_Request)$user_id (int, 0 for guests) | Return true to skip the variations response cache for a request. Use it when another plugin sets prices per user or per session. |
wwof_variations_response_cache_ttl | Filter | $ttl (int, seconds, default 5 minutes)$request (WP_REST_Request)$product_id (int, the parent product ID) | Sets how long a variations response stays cached. |
wwof_disable_abilities | Filter | $disable (bool, default false) | Return true to turn off the abilities that this plugin registers. |
Example: shorten the variations cache
This example keeps cached variation responses for one minute.
add_filter( 'wwof_variations_response_cache_ttl', function ( $ttl, $request, $product_id ) {
return MINUTE_IN_SECONDS;
}, 10, 3 );
WP-CLI command: migrate order forms
Run this command to migrate order forms from the version 2 format to the version 3 format. The command saves a copy of each form’s old settings in the _settings post meta before it migrates the form.
wp wwof migrate_forms_settings
To migrate only some forms, add one or more order form IDs after the command name:
wp wwof migrate_forms_settings 123 456
Without IDs, the command migrates all version 2 forms. If it finds no forms, it shows the error No forms found.
The plugin also has two more WP-CLI commands. Use wp wwof export_order_forms [<format>] to export forms as json or yml. Use wp wwof import_v2_forms_from_json_file <json_file_path> to import version 2 forms from a JSON file.
WooCommerce Wholesale Lead Capture
WooCommerce Wholesale Lead Capture has hooks for the lead life cycle, the registration form, login redirects, emails, and the Leads REST API. Every lead action passes a WP_User object.
| Hook | Type | Arguments | What it changes |
|---|---|---|---|
wwlc_action_before_approve_user | Action | $user (WP_User) | Runs before WooCommerce Wholesale Lead Capture approves a lead. |
wwlc_action_after_approve_user | Action | $user (WP_User) | Runs after the lead is approved and the approval email is sent. |
wwlc_action_before_reject_user | Action | $user (WP_User) | Runs before a lead is rejected. It does not run for a lead that is already rejected. |
wwlc_action_after_reject_user | Action | $user (WP_User) | Runs after a lead is rejected. The lead gets the Rejected role, or the account is deleted when the settings say so. |
wwlc_action_before_activate_user | Action | $user (WP_User) | Runs before a lead account is activated. |
wwlc_action_after_activate_user | Action | $user (WP_User) | Runs after a lead account is marked active. |
wwlc_action_before_deactivate_user | Action | $user (WP_User, the roles before the change) | Runs before a lead account is deactivated. It also runs when the Leads REST API deactivates a lead. |
wwlc_action_after_deactivate_user | Action | $user (WP_User) | Runs after a lead account is deactivated. The user gets the customer role and is logged out of all sessions. |
wwlc_action_after_create_wholesale_lead | Action | $new_lead (WP_User) | Runs after a lead registers, and after auto-approval is processed. It also runs when an existing customer upgrades to a wholesale account. |
wwlc_stop_registering | Filter | $stop (bool, default false)$user_data (array, the submitted form data) | Return true to stop the registration. The form shows the error “You are not allowed to register.” |
wwlc_login_redirect_url | Filter | $redirect_url (string)$user (WP_User) | Changes the URL where a user goes after login on the wholesale login form. It also applies to a WooCommerce login (for example My Account) when the user has a wholesale role. |
wwlc_registration_form_fields | Filter | $form_fields (array, default, custom, and reCAPTCHA fields, sorted by order) | Changes the fields that the registration form shows. |
wwlc_filter_{field}_field_form_label | Filter | $label (string, the translated default label) | Changes the label of one default registration field. Replace {field} with one of: first_name, last_name, phone, email, company, country, address1, address2, city, state, postcode, password. For example, wwlc_filter_first_name_field_form_label. |
wwlc_email_format_string | Filter | $text (string, email content after placeholders are replaced)$wc_email (WC_Email) | Changes the text of a Wholesale Lead Capture email after the placeholders are replaced. |
wwlc_default_email_lead_role | Filter | $role (string, default wholesale_customer) | Sets the role used to pick the sample lead for the email objects. The role that is set in the lead role setting overrides it when that setting is not empty. |
wwlc_rest_api_routes | Filter | $routes (array, route definitions) | Adds or changes the routes of the Leads REST API in the wwlc/v1 namespace. Each route is keyed as leads/<route>. |
wwlc_disable_abilities | Filter | $disabled (bool, default false) | Return true to turn off the abilities that this plugin registers. The constant WWLC_DISABLE_ABILITIES does the same. |
Example: run code when you approve a lead
This example saves a flag on the user after approval. A sync script can read the flag later.
add_action( 'wwlc_action_after_approve_user', function ( $user ) {
update_user_meta( $user->ID, 'needs_crm_sync', 'yes' );
} );
WooCommerce Wholesale Quotes
WooCommerce Wholesale Quotes has filters for quote data, the quote button label, front end options, and REST API permissions.
| Hook | Type | Arguments | What it changes |
|---|---|---|---|
wholesale_quotes_api_admin_permissions_check | Filter | $response (true|WP_Error, true when the user has manage_woocommerce)$request (WP_REST_Request) | Changes the permission check of the admin REST routes. Return true to allow the request, or a WP_Error to refuse it. |
wholesale_quotes_quote_items_data | Filter | $data (array, quote item objects) | Changes the list of quote items before the plugin uses it. It applies to the items of a quote and to the quote item list. |
wholesale_quotes_quote_item_product_data | Filter | $product (array, product data of the quote item)$item_product_id (int) | Changes the product data of a quote item. The data has the image, link, stock status, and product type. |
wws_wq_quote_button_shop_label | Filter | $label (string, default is the label in the quote settings) | Changes the label of the quote button on shop pages. |
wws_wq_guest_quote_products_data | Filter | $products (array, quote item objects)$product_data (array, the product data from the request) | Changes the products that the guest quote REST route returns. |
wholesale_quotes_options | Filter | $options (array, front end options) | Changes the options array that the quote front end uses. It has keys such as title, description, and quoteUrl. |
wwq_disable_abilities | Filter | $disabled (bool, default false) | Return true to turn off the abilities that this plugin registers. |
Example: change the quote button label
This example changes the label of the quote button on shop pages.
add_filter( 'wws_wq_quote_button_shop_label', function ( $label ) {
return __( 'Request pricing', 'your-text-domain' );
} );
WooCommerce Wholesale Payments
WooCommerce Wholesale Payments has filters for the invoice schedule, payment plan and order queries, the Stripe API version, and reminder email templates.
| Hook | Type | Arguments | What it changes |
|---|---|---|---|
wpay_filter_cron_schedule | Filter | $cron_schedule (string, default is the saved schedule, daily if none) | Sets the interval of the recurring invoice action. The plugin reads it only when it creates that action, so it does not change an existing schedule. Use daily, hourly, or 15min. Any other value runs daily. |
wpay_get_payment_plans | Filter | $args (array, WP_Query arguments) | Changes the query arguments that load payment plans. The plugin sets the post type after the filter runs. |
wpay_get_payment_orders | Filter | $args (array, wc_get_orders() arguments) | Changes the query arguments that load payment orders. The plugin limits the page size after the filter runs. |
wpay_stripe_api_version | Filter | $version (string, the Stripe API version the plugin uses) | Changes the Stripe API version in the request header. It also sets the version when the plugin creates a Stripe webhook. |
wpay_payment_due_today_email_template_html | Filter | $template (string, default payment-due-today.php) | Changes the HTML template file of the payment due today email. |
wpay_payment_due_today_email_template_plain | Filter | $template (string, default payment-due-today.php) | Changes the plain text template file of the payment due today email. |
wpay_payment_overdue_email_template_html | Filter | $template (string, default payment-overdue.php) | Changes the HTML template file of the payment overdue email. |
wpay_payment_overdue_email_template_plain | Filter | $template (string, default payment-overdue.php) | Changes the plain text template file of the payment overdue email. |
wpay_disable_abilities | Filter | $disabled (bool, default false) | Return true to turn off the abilities that this plugin registers. |
Invoice Gateway for WooCommerce
Invoice Gateway for WooCommerce has hooks for the invoice due date, the order status, free orders, and overdue invoices.
| Hook | Type | Arguments | What it changes |
|---|---|---|---|
igfw_invoice_due_date | Filter | $due (int, Unix timestamp)$order (WC_Order) | Changes the payment due date of an invoice order. The default is the order date plus the payment terms in days. A value of 0 or less is ignored. |
igfw_invoice_gateway_default_order_status | Filter | $status (string, default is the saved order status, on-hold if none) | Changes the status that the gateway gives to an order at checkout. |
igfw_show_invoice_gateway_on_free_orders | Filter | $show (bool, default true) | Return false to hide the invoice gateway when the cart total is zero. |
igfw_invoice_gateway_construct | Action | None | Runs at the end of the invoice gateway constructor. |
igfw_invoice_payment_overdue | Action | $order (WC_Order, the overdue order) | Runs when the plugin finds an overdue invoice order, after it sends the overdue email to the store admin. The plugin does not charge the order. Use this hook to start your own process. |
Example: add seven days to the invoice due date
This example moves every invoice due date seven days later.
add_filter( 'igfw_invoice_due_date', function ( $due, $order ) {
return $due + ( 7 * DAY_IN_SECONDS );
}, 10, 2 );
What to read next
Need help?
If you have a question or run into any issues, we’re here to help.
- Premium users: Open a support ticket
- Free users: Visit our community forum
