=== Advanced Shipping Rate Builder – Table Rate, Conditional & Weight Based Shipping ===
Contributors: actpro, freemius
Tags: table rate shipping, conditional shipping, flat rate shipping, weight based shipping, woocommerce shipping
Requires Plugins: woocommerce
Requires at least: 6.2
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.9.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Table rate shipping for WooCommerce. Conditional, weight based and flat rate shipping rules, a visual builder, cart simulator and free shipping bar.

== Description ==

**Advanced Shipping Rate Builder** is a table rate shipping plugin for WooCommerce. It lets you build exactly the rates your store needs — table rate shipping, conditional shipping, weight based shipping, flat rate shipping and free shipping — and *see* what customers will pay before they do.

[**Try the live demo**](https://demo.wpactpro.com/advanced-shipping-rate-builder/) — a full WooCommerce store with the plugin installed. No signup, nothing to install.

Set up **table rate shipping** by cart total, weight or item count. Add **conditional shipping** rules that only apply to certain products, categories or shipping classes. Charge **weight based shipping** per kilogram, a flat rate per order, a cost per item, or a percentage of the order. All from one visual rule builder, with no code.

Every rule reads as a sentence: **WHERE** (which WooCommerce zones) → **WHEN** (conditions) → **THEN** (what to charge) → **SHOW AS** (the label at checkout). A live plain-language summary restates the whole rule as you edit, and the built-in **Simulator** runs any test cart through the real engine, showing which rules matched, which were skipped and exactly why.

= Why merchants choose it =

Most shipping plugins make you guess. This one shows you the answer before your customer sees it: a live checkout preview while you edit, and a simulator that runs your real rules against any test cart. "Why didn't my rule apply?" stops being a support ticket.

= Shipping scenarios you can build =

* **Free shipping over an amount** — free once the cart reaches $50, with a progress bar telling shoppers how much more to add
* **Weight based shipping** — $5 up to 5 kg, $9 to 20 kg, $15 above, as a proper weight table
* **Flat rate shipping per order** — one price for everything, or one price per item
* **Bulky item shipping** — a higher rate whenever the cart contains a shipping class or category you choose
* **Conditional shipping by product** — a rate that only appears when a specific product is in the cart
* **Percentage-based shipping** — charge shipping as a percentage of the order subtotal
* **Tiered shipping rates** — add an amount for every extra 5 kg, 10 items or $100 of subtotal
* **Local pickup or courier choice** — offer several rates at once and let the customer choose
* **One rate only** — hide the other shipping methods when your rule applies

= Build rates from =

* Flat cost, cost per item, cost per weight, or percentage of the cart subtotal
* Tiered extras — add amounts per quantity, weight or subtotal range (up to 5 tiers)
* A free-shipping threshold on any rule ("free when the cart total reaches …")

= Target rules by =

* Your existing **WooCommerce shipping zones** — no duplicate location setup, ever
* Cart subtotal, cart weight, item quantity
* Products, product categories, shipping classes

= Merchant-friendly by design =

* **Goal-first creation** — pick what you want ("free shipping over an amount", "weight-based rate", …) and get a working rule to adjust
* **Rule simulator** — answer "why didn't my rule apply?" in seconds, not support tickets
* **Free-shipping progress bar** on cart and checkout ("Add €12.50 more for free shipping"), classic and block carts alike
* Clear resolution: show all matching rates (customer picks) or highest-priority only — stated in plain words on the dashboard
* Rules never break checkout: a misconfigured rule is skipped and flagged in the dashboard, never fatal

= Lightweight & modern =

* Rules live in one indexed table — no post-meta bloat, one query per checkout calculation
* Zero frontend assets unless the progress bar is shown
* HPOS compatible, works with classic and Block cart/checkout
* REST API and WP-CLI (`wp wpactpro-sr rules …`) included

= Free vs Pro =

**Everything in the free plugin**, with no limits on how many rules you create:

* Cost types: flat rate, per item, per weight, percentage of subtotal
* Tiered rates by quantity, weight or subtotal — up to 5 tiers per rule
* Free-shipping threshold on any rule, and the free-shipping progress bar
* Conditions: cart subtotal, cart weight, item quantity, cart contains product, cart contains category, cart contains shipping class
* Targeting by your existing WooCommerce shipping zones
* The visual rule builder, the plain-language rule summary and the live checkout preview
* The Simulator, showing which rules matched a test cart and why the rest did not
* Hide other shipping methods, rule priority and resolution modes
* REST API, WP-CLI, HPOS and Block cart/checkout support

[**Advanced Shipping Rate Builder Pro**](https://wpactpro.com/shipping-rate-builder/) adds eleven more conditions and five workflow features:

* **Destination postcode** and **destination city** — charge differently inside a single zone, so "£5 to mainland UK, £15 to the Highlands" no longer needs a second shipping zone. Same wildcard (`CB2*`) and range (`90210...99000`) syntax as WooCommerce zones.
* **Dimensional weight**, **cart volume** and **longest side in cart** — price bulky-but-light parcels the way couriers actually bill them.
* **Customer role** — wholesale and B2B shipping rates.
* **Specific customer** — one named account's own negotiated rate.
* **Date range**, **day of week** and **time of day** — seasonal, holiday and cut-off-time rates.
* **Coupon applied** — a shipping rate that responds to a promotion.
* **OR condition groups** — one rule that matches several different carts.
* **Shipping decisions log** — open any order and see which rule set the rate, and why every other rule did not apply. Answers "why was I charged this?" without reproducing the cart.
* **Shadow mode** — run a price change against real traffic, recorded but charging nobody, before it reaches a customer.
* **Surcharge rules** — add a handling fee on top of every rate instead of competing with them as another option.
* **Rule warnings** — told when a rule can never apply because another always wins first, or when it targets a shipping zone that has been deleted.

Every rule you build in the free version keeps working if a licence lapses — you can still edit, simplify and delete them.

== Installation ==

1. Install and activate **WooCommerce** first — this plugin extends it and will not activate without it.
2. Upload the plugin through **Plugins → Add New → Upload Plugin**, or install it from the WordPress plugin directory.
3. Activate it through the **Plugins** screen.
4. Go to **WooCommerce → Shipping Rate Builder** and pick a goal to create your first rule.

No shipping zone setup is required. Rules use the WooCommerce shipping zones you already have, so your countries, states and postcodes stay where you configured them.

= Building from source =

The admin interface in `build/` is compiled from the React source in `client/`, both of which ship with the plugin. To rebuild it:

`npm install && npm run build`

== Frequently Asked Questions ==

= Is there a demo I can try before installing? =

Yes — there is a [live demo store](https://demo.wpactpro.com/advanced-shipping-rate-builder/) with the plugin already set up. You can build rules, run the Simulator and see rates at checkout without installing anything.

= Can I set up table rate shipping in WooCommerce? =

Yes. Build a table rate by adding tiers to any rule — different prices for each cart total, weight or quantity range (for example 0–5 kg, 5–20 kg, 20 kg and up). Tiers can add a flat amount once, or multiply per item, per kilogram or per unit of subtotal.

= Does it support weight based shipping? =

Yes. Charge a cost per weight unit, add weight-range tiers, or use cart weight as a condition so a rule only applies above or below a given weight. The weight unit follows your WooCommerce settings.

= How do I create conditional shipping rules? =

Add conditions to a rule and it only applies when they all match. You can condition on cart subtotal, cart weight, item quantity, and whether the cart contains particular products, product categories or shipping classes.

= How do I offer free shipping over a certain amount? =

Set a free-shipping threshold on any rule — "free when the cart total reaches …". Turn on the progress bar and shoppers see "Add $12.50 more for free shipping" on the cart and checkout, updating live as they shop.

= Can I hide other shipping methods when my rule applies? =

Yes. Any rule can hide the other shipping methods a customer would otherwise see, so a matching rate becomes the only option. It never leaves a customer with no shipping option at all — if no rate from this plugin applies, the others stay.

= How does this relate to WooCommerce shipping zones? =

Rules target your existing zones ("All zones" or a selection). Destination matching — countries, states, postcodes — stays in WooCommerce where you already configured it. This plugin never re-implements geography.

= What happens when several rules match the same cart? =

Your choice, stated on the dashboard: show every matching rate so the customer picks (default), or apply only the highest rule in your list. The Simulator always shows the final outcome.

= Does it work with the Cart and Checkout Blocks? =

Yes — rates flow through the Store API automatically, and the progress bar renders on block carts with live updates. The classic cart and checkout are equally supported.

= Will it slow my store down? =

No. Rules load in a single indexed query, results are object-cached, and the frontend ships zero JavaScript/CSS unless the progress bar is actually displayed.

= Can I charge different shipping rates per product or category? =

Yes. Condition a rule on the cart containing particular products, product categories or shipping classes, then set the rate for that rule. A common setup is a shipping class for bulky items with its own higher rate.

= Can I offer multiple shipping rates for one order? =

Yes. By default every matching rule offers its rate and the customer picks at checkout. Switch to highest-priority-only if you would rather present a single option.

= Does it replace the WooCommerce flat rate shipping method? =

No, it sits alongside it. Your existing flat rate, free shipping and local pickup methods keep working. If you want a rule to be the only option a customer sees, turn on "hide other shipping methods" for that rule.

= Can I set a maximum or minimum order weight for shipping? =

Yes. Use cart weight as a condition — "at least" or "at most" a given weight — so a rule only offers its rate inside that range. Carts outside it simply do not get that rate.

= Can I set shipping rates by postcode or ZIP code? =

Yes, with Pro. The destination postcode condition matches the customer's postcode using the same wildcard (`CB2*`) and range (`90210...99000`) syntax as WooCommerce shipping zones, so you can charge more for remote areas without building a second zone for them. There is a destination city condition too.

= Can I charge different shipping rates per country? =

Yes. Countries live in your WooCommerce shipping zones, and every rule targets those zones — so a rule aimed at your "Europe" zone charges its rate only to European customers. You never re-enter countries in this plugin.

= Can I set up wholesale or B2B shipping rates? =

Yes, with Pro. The customer role condition applies a rule only to customers in the roles you choose, so wholesale accounts get their own rates while retail customers see yours. For a single negotiated contract price, the specific customer condition targets one named account.

= Does it support dimensional or volumetric weight shipping? =

Yes, with Pro. Dimensional weight, cart volume and longest side in cart let you price bulky-but-light parcels the way couriers actually bill them, using your products' existing WooCommerce dimensions.

= Why didn't my shipping rule apply? =

Open the Simulator, enter the cart that behaved unexpectedly, and it lists every rule with the exact condition that failed. The most common causes are a rule that is inactive, a zone that does not cover the address, and a higher-priority rule winning first. Pro also records the same breakdown on every real order.

= Can I manage rules from the command line? =

Yes: `wp wpactpro-sr rules list|create|delete`.

== Screenshots ==

1. Settings — show every matching rate and let the customer pick, or apply only the highest rule
2. Rule builder — WHERE / WHEN / THEN / SHOW AS, with a live plain-language summary of the rule
3. Free shipping over an amount — set the threshold and the rate becomes free above it
4. Category surcharge — charge extra when the cart contains the products or categories you choose
5. Cart — the free-shipping progress bar tells shoppers exactly how much more to add
6. Checkout — your rule's label and rate, as the customer sees them
7. Simulator — every rule run against a test cart, showing which matched and why the rest did not
8. Conditions — stack cart subtotal, weight, item count, products, categories and shipping classes
9. Operators — includes or excludes, at least or at most, so one condition covers either direction

== Changelog ==

= 1.9.0 - 2026-09-12 =
* New: **Stale zone warnings** (Pro) — flags rules that target shipping zones which no longer exist, or that are limited to selected zones with none selected.
* Deleting a zone in WooCommerce tells you nothing about the rules that pointed at it. They stay active, stay correct on their own terms, and never fire again. Now the Rules screen says so.
* A rule that still works but carries one stale reference is explained rather than marked dead — a false warning is worse than none.

= 1.8.0 - 2026-09-08 =
* New: **Surcharge rules** (Pro) — mark a rule as a surcharge and its cost is added to every rate that applies, rather than competing with them as another option.
* Base rate plus handling fee is now one shipping price built from two rules. Standard £5 and Express £15 with a £2 handling surcharge give £7 and £17 — two choices, not a single £22 rate.
* A surcharge with nothing to attach to charges nobody: it is part of a price, so with no price there is nothing to add to.

= 1.7.0 - 2026-09-08 =
* New: **Specific customer** condition (Pro) — give one named account its own negotiated rate. Customer role covers "all wholesale buyers pay this"; this covers the case a role cannot express, without inventing a role per customer.
* Guests match no specific-customer rule under either comparison, so an "everyone except Acme" rule never fires on a shopper who is not signed in.
* The Simulator gains a customer field whenever a rule reads one.

= 1.6.0 - 2026-09-08 =
* New: **Shadow mode** (Pro) — a third rule status. The rule is evaluated and recorded on every checkout but never charges anyone, so you can try a pricing change against real traffic before it reaches a customer.
* Shadow rules show in the Simulator and the shipping decisions log with what they *would* have charged.
* A shadow rule never blocks a live rule, and is never reported as unreachable — it is not meant to fire.

= 1.5.0 - 2026-09-08 =
* New: **Unreachable rule detection** (Pro) — warns when a rule can never apply because a rule above it matches every cart and always wins first. A silent failure until now: the rule below stays active, stays correct, and never runs.
* Shown only under *Only the highest rule applies*, since with every matching rate shown no rule is shadowed.
* The warning names the rule doing the shadowing, so you know whether to reorder or narrow it.

= 1.4.0 - 2026-09-06 =
* New: **Shipping decisions log** (Pro) — open any order and see which rule set the shipping rate, what it cost, and for every rule that did not apply, exactly which condition failed.
* Answers "why was this customer charged this?" from the order screen itself, instead of asking you to rebuild the cart in the Simulator and hope it matches.
* Records which rule the customer actually chose — not just which ones matched — so it stays accurate when you offer several rates and they pick one.
* Stored as order data: removed when the order is deleted, and covered by WooCommerce's own personal-data erasure.

= 1.3.0 - 2026-09-01 =
* New: Destination postcode and destination city conditions (Pro) — charge differently inside a single shipping zone without building a second zone just to hold one postcode.
* Postcode patterns use exactly the same syntax as WooCommerce shipping zones: an exact postcode, a wildcard such as CB2*, or a range such as 90210...99000. Separate several with commas.
* Until a shopper has entered an address, a destination rule matches nothing — including "does not include" rules, so an "everywhere except" rule never fires on a blank address and quotes the wrong price.
* The Simulator gains postcode and city inputs whenever a rule reads them, so destination rules can be tested before going live.

= 1.2.0 - 2026-08-31 =
* New: Dimensional weight, cart volume and longest-side conditions (Pro) — price bulky-but-light items the way couriers actually charge for them.
* New: Dimensional weight divisor setting under Settings → Units, so the divisor matches your courier contract (5000 for cm/kg, 139 for in/lb).
* If any item in the cart has no dimensions set, these three conditions are skipped rather than pricing the order on incomplete measurements, and the Simulator names the product that needs dimensions.

= 1.1.0 - 2026-08-26 =
* Initial release.
* Rule engine with zone-aware shipping method — table rate, conditional, weight based and free shipping rules.
* Visual rule builder: WHERE / WHEN / THEN / SHOW AS, with a live plain-language summary and 10 goal templates.
* Rules dashboard with drag-to-reorder priority, live checkout preview and global save.
* Simulator — run any test cart through the real engine and see which rules matched, which were skipped and why.
* Condition groups: a rule can match on any of several groups — for example, "cart weight over 10 kg" OR "contains the Fragile category" — instead of only every condition at once. Adding a second group is a Pro feature; everything else here is free.
* Tiered extras (up to 5 tiers per rule) by quantity, weight or subtotal range.
* Free-shipping progress bar on cart and checkout, classic and block alike.
* Conditions on cart subtotal, cart weight, item quantity, products, product categories and shipping classes.
* Extension API: add-ons can register condition types, resolution modes and lookup sources, and the builder renders text, dropdown, multi-select, date and time conditions straight from their schema.
* REST API and WP-CLI (`wp wpactpro-sr rules …`).
* HPOS compatible; works with the classic and Block cart/checkout.
