Skip to main content

Conditional Shipping Rules

Overview​

Conditional Shipping Rules does not create a shipping method. It edits the rates WooCommerce has already produced: hiding a method when the cart does not qualify for it, revealing one that is normally hidden, overriding a cost, adding to it, or making it free.

Because it filters woocommerce_package_rates, it works with whatever methods the store already has — flat rate, free shipping, a carrier plugin — rather than replacing them. A rule names an action, an optional target method, a cost, a priority and the conditions under which it fires.

It is for stores whose methods are correct but whose availability depends on the cart.

Availability​

ItemValue
Module keyshipping-rules
TierPremium
Entitlement keyshipping-rules
Admin tabshipping-rules
Enabled optionaiowc_module_enabled_shipping-rules (off until turned on)
REST namespaceaiowc/v1

Enabling the module creates the three tables below, seeds the defaults and schedules the cache refresh job.

registerHooks() returns early when the licence does not grant shipping-rules. The REST routes register next, and the rate filter registers only when enable_filter is on — so switching that setting off stops the module touching checkout while leaving its screens and routes working.

Settings​

Stored in the bundled option row aiowc_as_settings.

Stored keyDefaultMeaning
enable_filtertrueWhether the rules are applied to checkout rates at all.
dimensional_weight_enabledfalseWhether a dimensional weight is computed and made available as a condition.
dimensional_weight_factor5000.0The divisor used for that calculation.
free_shipping_threshold0.0A cart total above which shipping is free. Zero means no threshold.

Rules​

A rule carries one action:

ActionEffect on the rates WooCommerce produced
showReveals the target method.
hideRemoves the target method from checkout.
set_costReplaces the method's cost with the rule's cost.
add_costAdds the rule's cost to the method's own.
freeSets the cost to zero.
disableTurns the rule off without deleting it.

Rules are ordered by priority, and each may be scoped to a custom zone defined by this module rather than to a WooCommerce zone.

Conditions​

Conditions are stored per rule and evaluated with the operators >=, <=, =, !=, in, not_in and between.

Condition kindTypes
Numericcart_total, weight, item_count, dimensional_weight
Stringcountry, state, postcode
Listcategory, product, user_role, coupon_applied

dimensional_weight is only meaningful when dimensional_weight_enabled is on; with it off the value is not computed.

Custom zones​

The module keeps its own zone table, so a rule can target a set of countries, states and postcodes that does not correspond to any WooCommerce shipping zone. A zone has a name, its country/state/postcode lists, a priority and an active flag.

Admin screen​

This module has two administrator surfaces, and they are not the same screen.

  • Shipping Rules in the Empora admin is the React screen reached from the module's own tab.
  • A separate top-level Shipping Rules menu item is registered in WordPress's own admin by the module's PHP admin handler, with an airplane icon at menu position 58. It renders a plain rules table and a create form, saving through admin_post_aiowc_as_save_rule and deleting through admin_post_aiowc_as_delete_rule, both behind a nonce and a manage_woocommerce capability check.

Both read and write the same rules table, so a rule created in one appears in the other.

REST API endpoints​

All routes are on aiowc/v1, answer with the { success, data, message } envelope, and require manage_woocommerce.

MethodPathPurposeRequired args
GET/shipping/rulesEvery rule.–
POST/shipping/rulesCreate a rule.name
PATCH / PUT /POST/shipping/rules/{id}Update a rule. All three verbs are registered.id
DELETE/shipping/rules/{id}Delete a rule.id
GET/shipping/zonesEvery custom zone.–
POST/shipping/zonesCreate a custom zone.name
PATCH / PUT /POST/shipping/zones/{id}Update a custom zone.id
DELETE/shipping/zones/{id}Delete a custom zone.id
POST/shipping/calculateEvaluate the rules against a supplied cart context.–

These sit under /shipping/, while the separate Advanced Shipping Rules module owns /shipping-rules/. The two prefixes are deliberately distinct so neither module shadows the other's routes.

WooCommerce integration​

HookWhat the module does
woocommerce_package_ratesApplies the matching rules to the rates WooCommerce produced — the whole feature.
admin_menuRegisters the standalone WordPress admin page.
admin_post_aiowc_as_save_rule / _delete_ruleHandles that page's form submissions.

Database schema​

TableHolds
{prefix}aiowc_shipping_rulesThe rule: name, action, target method id, cost, priority, active flag, and the zone it applies to.
{prefix}aiowc_shipping_conditionsOne row per condition on a rule: type, operator, value, sort order.
{prefix}aiowc_shipping_zones_customThe module's own zones: name, countries, states, postcodes, priority, active flag.

Background jobs​

HookIntervalWork
aiowc_shipping_cache_refreshhourlyRebuilds the cached rule set the rate filter reads from.

This job runs on WP-Cron, scheduled an hour after the module is enabled.

Action hooks for integrators​

HookFired when
aiowc_track_eventThe module is enabled or disabled.

The module exposes no filter for adding a condition type of your own.

Entitlement limits​

shipping-rules is an on/off grant with no cap on the number of rules, conditions or zones.

Health check​

The module reports a warning when its tables are missing or WooCommerce is inactive, and otherwise reports that it is functioning normally. A disabled module reports that it is disabled.

Known gaps​

  • Two admin surfaces exist for one module — the Empora tab and a separate top-level WordPress menu — with no cross-link between them, so an administrator can easily find one and never learn the other exists.
  • The settings prefix is aiowc_as_, which reads as "advanced shipping" rather than as this module. Nothing collides today because the Advanced Shipping Rules module stores no settings at all, but the name is a poor fit and would collide if that module ever gained a settings row under the obvious prefix.
  • free_shipping_threshold is stored as a setting rather than expressed as a rule, so it is configured in a different place from every other condition.
  • There is no condition filter, so a store cannot add its own condition type without modifying the module.