#hwtcs-docs { --hwd-ink: #0b3c44; --hwd-ink-deep: #082e35; --hwd-amber: #f4a938; --hwd-amber-soft: #fde9c4; --hwd-text: #1d2e31; --hwd-muted: #52666a; --hwd-line: #d6e1e2; --hwd-tint: #eef4f4; --hwd-link: #0b6875; --hwd-cream: #f7f1e6; --hwd-sticky-top: 96px; --hwd-mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace; container: hwd / inline-size; box-sizing: border-box; width: 100%; max-width: min(1180px, calc(100vw - 40px)); margin: 0 auto; padding: 24px 0 72px; color: var(--hwd-text); font-family: "Archivo", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; font-size: 17px; font-stretch: 100%; font-weight: 400; line-height: 1.65; text-align: left; -webkit-font-smoothing: antialiased; } #hwtcs-docs *, #hwtcs-docs *::before, #hwtcs-docs *::after { box-sizing: border-box; } #hwtcs-docs :where(h1, h2, h3, h4, p, ul, ol, dl, dd, figure, pre, table, blockquote) { margin: 0; padding: 0; } #hwtcs-docs :where(h1, h2, h3, h4) { color: var(--hwd-ink); font-family: inherit; letter-spacing: normal; text-transform: none; } #hwtcs-docs a { color: var(--hwd-link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; } #hwtcs-docs a:hover { color: var(--hwd-ink); text-decoration-thickness: 2px; } #hwtcs-docs a:focus-visible, #hwtcs-docs summary:focus-visible { outline: 3px solid var(--hwd-amber); outline-offset: 3px; border-radius: 4px; } #hwtcs-docs strong { font-weight: 650; color: var(--hwd-ink); } #hwtcs-docs code { font-family: var(--hwd-mono); font-size: 0.86em; background: var(--hwd-tint); color: var(--hwd-ink); padding: 0.12em 0.4em; border-radius: 5px; white-space: nowrap; } #hwtcs-docs .hwd-path { font-weight: 600; color: var(--hwd-ink); } #hwtcs-docs .hwd-main p code, #hwtcs-docs .hwd-main li code { white-space: normal; overflow-wrap: anywhere; } /* Hero */ #hwtcs-docs .hwd-hero { display: grid; grid-template-columns: minmax(0, 1fr); gap: 40px; padding: 44px 28px; border-radius: 28px; background: radial-gradient(120% 90% at 100% 0%, #13606b 0%, transparent 60%), linear-gradient(160deg, #11505a 0%, var(--hwd-ink-deep) 100%); color: var(--hwd-cream); } #hwtcs-docs .hwd-hero h1 { color: #fff; font-size: clamp(1.7rem, 9.5cqi, 3.6rem); font-stretch: 122%; overflow-wrap: break-word; hyphens: manual; font-weight: 780; line-height: 1.02; letter-spacing: -0.01em; max-width: 12ch; } #hwtcs-docs .hwd-hero .hwd-for { display: block; margin-top: 10px; color: var(--hwd-amber); font-size: 0.42em; font-stretch: 110%; font-weight: 600; letter-spacing: 0; line-height: 1.2; } #hwtcs-docs .hwd-lede { margin-top: 22px; max-width: 34em; font-size: 1.12rem; line-height: 1.6; color: #e3ebe9; } #hwtcs-docs .hwd-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; } #hwtcs-docs a.hwd-btn { display: inline-flex; align-items: center; min-height: 48px; padding: 12px 22px; border-radius: 999px; font-size: 1rem; font-weight: 650; line-height: 1.2; text-decoration: none; transition: background-color 0.15s ease, color 0.15s ease; } #hwtcs-docs a.hwd-btn-primary { background: var(--hwd-amber); color: var(--hwd-ink-deep); } #hwtcs-docs a.hwd-btn-primary:hover { background: #ffc35e; color: var(--hwd-ink-deep); } #hwtcs-docs a.hwd-btn-ghost { box-shadow: inset 0 0 0 2px rgba(247, 241, 230, 0.55); color: #fff; } #hwtcs-docs a.hwd-btn-ghost:hover { background: rgba(247, 241, 230, 0.12); color: #fff; } #hwtcs-docs .hwd-reqs { display: flex; flex-wrap: wrap; gap: 8px 22px; margin-top: 30px; font-size: 0.92rem; color: #c9d8d6; list-style: none; } #hwtcs-docs .hwd-reqs li { margin: 0; } #hwtcs-docs .hwd-reqs b { color: #fff; font-weight: 650; } /* The parcel label in the hero */ #hwtcs-docs .hwd-label { position: relative; align-self: start; background: #fff; color: var(--hwd-text); border-radius: 16px; padding: 22px 22px 18px; box-shadow: 0 18px 50px -20px rgba(0, 0, 0, 0.55); } #hwtcs-docs .hwd-label::before { content: ""; position: absolute; left: 18px; right: 18px; top: -6px; height: 12px; background: radial-gradient(circle at 6px 6px, var(--hwd-ink-deep) 5px, transparent 5.5px) 0 0 / 18px 12px space no-repeat; opacity: 0.9; } #hwtcs-docs .hwd-label-head { display: flex; justify-content: space-between; gap: 16px; align-items: flex-start; } #hwtcs-docs .hwd-label-to { font-size: 0.82rem; color: var(--hwd-muted); line-height: 1.4; } #hwtcs-docs .hwd-label-to b { display: block; margin-bottom: 2px; color: var(--hwd-ink); font-size: 1.05rem; font-stretch: 112%; font-weight: 700; } #hwtcs-docs .hwd-label-method { flex: none; border: 2px solid var(--hwd-ink); border-radius: 8px; padding: 4px 9px; color: var(--hwd-ink); font-size: 0.78rem; font-weight: 700; line-height: 1.3; text-align: center; } #hwtcs-docs .hwd-label-facts { display: flex; gap: 20px; margin-top: 14px; padding-bottom: 14px; border-bottom: 2px dashed var(--hwd-line); font-size: 0.82rem; color: var(--hwd-muted); } #hwtcs-docs .hwd-label-facts b { display: block; color: var(--hwd-text); font-size: 0.98rem; font-weight: 650; } #hwtcs-docs .hwd-trace { list-style: none; margin: 12px 0 0; padding: 0; } #hwtcs-docs .hwd-trace li { display: grid; grid-template-columns: 26px 1fr auto; gap: 10px; align-items: center; margin: 0; padding: 7px 0; font-size: 0.9rem; line-height: 1.3; } #hwtcs-docs .hwd-mark { display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; font-size: 0.75rem; font-weight: 700; } #hwtcs-docs .is-matched .hwd-mark { background: var(--hwd-ink); color: #fff; } #hwtcs-docs .is-missed .hwd-mark { box-shadow: inset 0 0 0 2px #b9c7c9; color: #7b8c8f; } #hwtcs-docs .is-skipped .hwd-mark { border: 2px dashed #b9c7c9; color: #9aa9ab; } #hwtcs-docs .is-missed .hwd-rule, #hwtcs-docs .is-skipped .hwd-rule { color: var(--hwd-muted); } #hwtcs-docs .hwd-what { font-size: 0.82rem; color: var(--hwd-muted); text-align: right; white-space: nowrap; } #hwtcs-docs .is-matched .hwd-what { color: var(--hwd-ink); font-weight: 650; } #hwtcs-docs .hwd-stop { display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px; background: var(--hwd-ink); color: #fff; font-size: 0.72rem; font-weight: 650; } #hwtcs-docs .hwd-total { display: flex; justify-content: space-between; align-items: baseline; margin-top: 10px; padding-top: 14px; border-top: 2px dashed var(--hwd-line); } #hwtcs-docs .hwd-total span { color: var(--hwd-muted); font-size: 0.88rem; } #hwtcs-docs .hwd-total b { color: var(--hwd-ink); font-size: 2rem; font-stretch: 115%; font-weight: 780; line-height: 1; } #hwtcs-docs .hwd-gap { margin-top: 14px; padding: 9px 12px; border-radius: 10px; background: var(--hwd-amber-soft); color: #5c3b00; font-size: 0.86rem; font-weight: 600; } #hwtcs-docs .hwd-hero-note { margin-top: 14px; font-size: 0.88rem; line-height: 1.5; color: #c9d8d6; } /* Body: contents rail and the guide */ #hwtcs-docs .hwd-body { display: grid; grid-template-columns: minmax(0, 1fr); gap: 32px; margin-top: 56px; } #hwtcs-docs .hwd-toc-wide { display: none; } #hwtcs-docs .hwd-toc-narrow { border: 1px solid var(--hwd-line); border-radius: 14px; padding: 4px 18px; } #hwtcs-docs .hwd-toc-narrow summary { cursor: pointer; padding: 12px 0; font-weight: 650; color: var(--hwd-ink); list-style: none; } #hwtcs-docs .hwd-toc-narrow summary::-webkit-details-marker { display: none; } #hwtcs-docs .hwd-toc-narrow summary::after { content: "+"; float: right; font-weight: 500; font-size: 1.3rem; line-height: 1; } #hwtcs-docs .hwd-toc-narrow[open] summary::after { content: "\2212"; } #hwtcs-docs .hwd-toc-narrow ol { padding-bottom: 12px; } #hwtcs-docs .hwd-toc ol { list-style: none; } #hwtcs-docs .hwd-toc li { margin: 0; } #hwtcs-docs .hwd-toc a { display: block; padding: 6px 0; color: var(--hwd-muted); font-size: 0.94rem; line-height: 1.35; text-decoration: none; } #hwtcs-docs .hwd-toc a:hover { color: var(--hwd-ink); } #hwtcs-docs .hwd-toc-title { margin-bottom: 8px; color: var(--hwd-ink); font-size: 0.95rem; font-weight: 700; } #hwtcs-docs .hwd-main { min-width: 0; max-width: 46rem; } #hwtcs-docs .hwd-section { scroll-margin-top: var(--hwd-sticky-top); padding-top: 8px; } #hwtcs-docs .hwd-section + .hwd-section { margin-top: 64px; } #hwtcs-docs .hwd-section h2 { font-size: clamp(1.6rem, 3.6cqi, 2rem); font-stretch: 116%; font-weight: 750; line-height: 1.15; margin-bottom: 18px; } #hwtcs-docs .hwd-section h3 { margin: 34px 0 10px; font-size: 1.2rem; font-stretch: 108%; font-weight: 700; line-height: 1.3; } #hwtcs-docs .hwd-main p { margin: 0 0 16px; max-width: 70ch; } #hwtcs-docs .hwd-main ul { margin: 0 0 18px; padding-left: 1.25em; } #hwtcs-docs .hwd-main ul li { margin: 6px 0; padding-left: 4px; } #hwtcs-docs .hwd-main ul li::marker { color: var(--hwd-amber); } /* Quick start: a real sequence */ #hwtcs-docs .hwd-steps { list-style: none; counter-reset: hwd-step; margin: 8px 0 0; padding: 0; } #hwtcs-docs .hwd-steps > li { counter-increment: hwd-step; position: relative; margin: 0; padding: 0 0 26px 62px; } #hwtcs-docs .hwd-steps > li::before { content: counter(hwd-step); position: absolute; left: 0; top: -2px; display: grid; place-items: center; width: 42px; height: 42px; border-radius: 50%; background: var(--hwd-ink); color: #fff; font-size: 1.05rem; font-stretch: 115%; font-weight: 750; } #hwtcs-docs .hwd-steps > li:not(:last-child)::after { content: ""; position: absolute; left: 20px; top: 44px; bottom: 4px; width: 2px; background: var(--hwd-line); } #hwtcs-docs .hwd-steps h3 { margin: 6px 0 6px; } #hwtcs-docs .hwd-steps p { margin-bottom: 0; } /* Tables */ #hwtcs-docs .hwd-table { margin: 6px 0 24px; overflow-x: auto; border: 1px solid var(--hwd-line); border-radius: 14px; } #hwtcs-docs table { width: 100%; border-collapse: collapse; border: 0; background: none; font-size: 0.94rem; line-height: 1.5; } #hwtcs-docs th, #hwtcs-docs td { padding: 12px 16px; border: 0; border-bottom: 1px solid var(--hwd-line); background: none; text-align: left; vertical-align: top; } #hwtcs-docs tbody tr:last-child > * { border-bottom: 0; } #hwtcs-docs thead th { background: var(--hwd-tint); color: var(--hwd-ink); font-size: 0.86rem; font-weight: 700; } #hwtcs-docs tbody th { color: var(--hwd-ink); font-weight: 650; white-space: nowrap; } #hwtcs-docs td code { white-space: nowrap; } /* Notes */ #hwtcs-docs .hwd-note { margin: 4px 0 22px; padding: 14px 18px; border-left: 4px solid var(--hwd-amber); border-radius: 0 12px 12px 0; background: #fff8ec; font-size: 0.96rem; } #hwtcs-docs .hwd-note p:last-child { margin-bottom: 0; } /* A rule written the way the builder shows it */ #hwtcs-docs .hwd-sentence { margin: 4px 0 22px; padding: 16px 18px; border: 1px solid var(--hwd-line); border-radius: 14px; font-size: 0.98rem; } #hwtcs-docs .hwd-sentence b { display: block; color: var(--hwd-ink); font-weight: 700; } #hwtcs-docs .hwd-sentence span { color: var(--hwd-muted); } /* Templates */ #hwtcs-docs .hwd-regions { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0 22px; padding: 0; list-style: none; } #hwtcs-docs .hwd-regions li { margin: 0; padding: 6px 14px; border-radius: 999px; background: var(--hwd-tint); color: var(--hwd-ink); font-size: 0.92rem; font-weight: 600; } /* Code */ #hwtcs-docs pre { margin: 4px 0 24px; padding: 18px 20px; overflow-x: auto; border-radius: 14px; background: var(--hwd-ink-deep); color: #e6efed; font-family: var(--hwd-mono); font-size: 0.86rem; line-height: 1.6; white-space: pre; tab-size: 4; } #hwtcs-docs pre code { padding: 0; background: none; color: inherit; font-size: inherit; white-space: inherit; } /* Questions */ #hwtcs-docs .hwd-faq details { border-bottom: 1px solid var(--hwd-line); } #hwtcs-docs .hwd-faq details:first-of-type { border-top: 1px solid var(--hwd-line); } #hwtcs-docs .hwd-faq summary { position: relative; cursor: pointer; padding: 16px 40px 16px 0; color: var(--hwd-ink); font-weight: 650; line-height: 1.4; list-style: none; } #hwtcs-docs .hwd-faq summary::-webkit-details-marker { display: none; } #hwtcs-docs .hwd-faq summary::after { content: ""; position: absolute; right: 6px; top: 50%; width: 10px; height: 10px; margin-top: -7px; border-right: 2px solid var(--hwd-ink); border-bottom: 2px solid var(--hwd-ink); transform: rotate(45deg); transition: transform 0.2s ease; } #hwtcs-docs .hwd-faq details[open] summary::after { transform: rotate(-135deg); margin-top: -2px; } #hwtcs-docs .hwd-faq .hwd-answer { padding: 0 0 18px; } #hwtcs-docs .hwd-faq .hwd-answer p:last-child, #hwtcs-docs .hwd-faq .hwd-answer ul:last-child { margin-bottom: 0; } /* Help */ #hwtcs-docs .hwd-help { display: grid; gap: 18px; align-items: center; margin-top: 72px; padding: 30px 28px; border-radius: 22px; background: var(--hwd-tint); } #hwtcs-docs .hwd-help h2 { font-size: 1.5rem; font-stretch: 116%; font-weight: 750; line-height: 1.2; } #hwtcs-docs .hwd-help p { margin: 8px 0 0; color: var(--hwd-muted); } #hwtcs-docs .hwd-help a.hwd-btn-primary { background: var(--hwd-ink); color: #fff; justify-self: start; } #hwtcs-docs .hwd-help a.hwd-btn-primary:hover { background: var(--hwd-ink-deep); color: #fff; } @container hwd (min-width: 860px) { #hwtcs-docs .hwd-hero { grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); padding: 60px 56px; gap: 56px; align-items: center; } #hwtcs-docs .hwd-hero h1 { font-size: clamp(2.4rem, 4.9cqi, 3.6rem); } #hwtcs-docs .hwd-help { grid-template-columns: 1fr auto; padding: 36px 40px; } #hwtcs-docs .hwd-help a.hwd-btn-primary { justify-self: end; } } @container hwd (min-width: 980px) { #hwtcs-docs .hwd-body { grid-template-columns: 210px minmax(0, 1fr); gap: 72px; margin-top: 72px; } #hwtcs-docs .hwd-toc-narrow { display: none; } #hwtcs-docs .hwd-toc-wide { display: block; position: sticky; top: var(--hwd-sticky-top); align-self: start; max-height: calc(100vh - var(--hwd-sticky-top) - 24px); overflow-y: auto; } } @container hwd (max-width: 520px) { #hwtcs-docs .hwd-hero { padding: 34px 20px; border-radius: 22px; } #hwtcs-docs .hwd-hero h1 { font-stretch: 106%; } #hwtcs-docs .hwd-label-facts { gap: 16px; } #hwtcs-docs .hwd-label { padding: 20px 16px 16px; } #hwtcs-docs .hwd-steps > li { padding-left: 54px; } #hwtcs-docs .hwd-steps > li::before { width: 38px; height: 38px; } #hwtcs-docs .hwd-steps > li:not(:last-child)::after { left: 18px; } } @container hwd (max-width: 640px) { #hwtcs-docs .hwd-table { overflow: visible; } #hwtcs-docs .hwd-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; } #hwtcs-docs .hwd-table tbody tr { display: block; padding: 14px 16px; border-bottom: 1px solid var(--hwd-line); } #hwtcs-docs .hwd-table tbody tr:last-child { border-bottom: 0; } #hwtcs-docs .hwd-table tbody th, #hwtcs-docs .hwd-table tbody td { display: block; padding: 0; border: 0; white-space: normal; } #hwtcs-docs .hwd-table tbody th { margin-bottom: 6px; font-size: 1rem; } #hwtcs-docs .hwd-table tbody td + td, #hwtcs-docs .hwd-table tbody th + td { margin-top: 6px; } #hwtcs-docs .hwd-table td[data-label]::before { content: attr(data-label); display: block; color: var(--hwd-muted); font-size: 0.8rem; font-weight: 600; } #hwtcs-docs .hwd-table td code, #hwtcs-docs .hwd-table th code { white-space: normal; overflow-wrap: anywhere; } } @container hwd (max-width: 360px) { #hwtcs-docs .hwd-trace li { grid-template-columns: 26px 1fr; row-gap: 2px; } #hwtcs-docs .hwd-trace .hwd-what { grid-column: 2; text-align: left; } #hwtcs-docs .hwd-total b { font-size: 1.6rem; } #hwtcs-docs .hwd-label-facts { gap: 12px; } } @media (prefers-reduced-motion: reduce) { #hwtcs-docs *, #hwtcs-docs *::after { transition: none !important; } }

HaywoodTech Conditional Shipping for WooCommerce

Table rate and conditional shipping from one rules engine. Write rules that read like sentences, test them on real carts before you save, and see exactly why every order paid what it did.

  • Free, GPL licensed
  • WordPress 7.0+
  • WooCommerce 11.0+
  • PHP 7.4+
Belfast, 5 kg planterBT1 5GS, United Kingdom
Standard
delivery
Subtotal£20.00
Weight5 kg
Items1
  1. 1Free shipping from £50£30.00 short
  2. 2Northern Ireland, Highlands and islands+£10.00
  3. 3Up to 2 kgNo match
  4. 4Up to 10 kg Stop here+£6.95
  5. 5Up to 30 kgNot reached
Customer pays£16.95
Add £30.00 more for free shipping

The UK region template pricing a test cart. Every rule that matches adds its cost, until one marked Stop here matches.

On this page
  1. Quick start
  2. How rules work
  3. Conditions
  4. Actions
  5. Rule set settings
  6. Region templates
  7. Test carts and the simulator
  8. Why an order paid what it did
  9. Free-shipping notice
  10. Postcode patterns
  11. Editing rules as JSON
  12. For developers
  13. Troubleshooting
  14. Privacy and uninstalling

Quick start

From a fresh install to tested shipping rates in six steps.

  1. Install the plugin

    With WooCommerce active, go to Plugins › Add New Plugin, search for HaywoodTech Conditional Shipping, then click Install Now and Activate.

  2. Add the method to a shipping zone

    Go to WooCommerce › Settings › Shipping, open a zone (or add one), click Add shipping method and choose HaywoodTech Conditional Shipping.

  3. Name it

    Click Edit on the new method. The name is what customers see at checkout, such as “Standard delivery”. Set its tax status too.

  4. Start from a template, or from scratch

    A new method shows region templates, with the ones for your zone first. Pick one, type your amounts and click Add these rules. Or click Add your first rule.

  5. Try it on a test cart

    In the cart simulator beside your rules, click New cart, add products from your store and an address. You see what that cart pays, and why, straight away.

  6. Save changes

    Click Save changes to put the rules live. Rules with errors are never saved, so checkout keeps using the rules it had.

Standard and Express in one zone? Add the method to the zone once for each option. Each has its own name and rules, and they share the same test carts.

How rules work

A method holds a list of rules. Each rule has conditions (when it applies) and actions (what it charges). At checkout the rules run from top to bottom:

  • Every rule that matches adds its cost.
  • A rule marked Stop here ends the list when it matches. That’s how weight bands work: the first band that fits wins.
  • A free-shipping threshold that the cart reaches also ends the list, and the cost is zero.
  • If no rule matches, the method isn’t offered. A gap in your rules never means free shipping by accident. You can choose to offer it free instead.

So a remote-area surcharge sits above the weight bands without Stop here, and adds to whichever band matches below it. Each rule reads as a sentence in the builder:

Northern Ireland, Highlands and islands If postcode is BT*, HS*, ZE* and 7 more and weight is at most 30 kg, add £10

And, or

All the conditions in a group must be true. Click Or another group to add a second group: the rule matches when any one group is true. A rule with no conditions always matches, which makes it a good last rule for “everywhere else”.

Order, on and off

Drag a rule by its handle to move it, or use Move up and Move down in its menu. The switch on each rule turns it off without deleting it.

The final cost

After the rules run, the cost is kept within any minimum and maximum a matching rule set, rounded to your store’s price decimals, and never goes below zero.

Conditions

ConditionCompares withGood to know
Cart subtotalmore than, at least, less than, at most, exactly, betweenWith or without tax, before or after coupons, as the rule set settings say.
Cart weightmore than, at least, less than, at most, exactly, betweenIn the rule set’s unit. Product weights are converted from your store’s unit.
Number of itemsmore than, at least, less than, at most, exactly, betweenCounts quantities, so 3 mugs are 3 items.
Shipping classany item is in, every item is in, no item is inA variation set to “Same as parent” uses the parent’s class.
Product categoryany item is in, every item is in, no item is inIncludes subcategories unless you switch that off.
Postcodeis one of, is not one ofExact postcodes, wildcards and ranges. See postcode patterns.

Actions

ActionWhat it does
Flat costAdds a fixed amount.
Cost per weight or itemAdds an amount for every step of weight or items over a starting point, such as £2 for every 1 kg over 2 kg. It can count every item, or only items in some shipping classes or categories. Part steps are charged in full or pro rata.
Free shipping over an amountMakes shipping free when the subtotal reaches the amount, and stops the rules below it. Until then, the cart can tell customers how much more they need.
Minimum costCharges at least this much. When several matching rules set one, the earliest wins.
Maximum costCharges at most this much. When several matching rules set one, the earliest wins.

A rule can have several actions. They apply in order, so a rule can add a flat £40 and then £20 for every 0.5 kg over 0.5 kg.

Rule set settings

Above the rules, Rule set settings opens the options that apply to every rule in the method:

  • Weights in: kg, g, lbs or oz. Changing it converts every weight in your rules, so “over 10 kg” doesn’t quietly become “over 10 lbs”.
  • Subtotal: including or excluding tax, before or after coupons. Subtotal conditions and free-shipping thresholds both use it.
  • When no rule matches: Hide this method (the default) or Offer it free.
  • Advanced: the rule set’s name and ID, and its currency. Amounts are in your store’s base currency, and the builder warns you if they don’t match.

Region templates

A method with no rules offers starter rules for nine regions. Templates for your zone’s countries come first, marked as suggested.

  • United States
  • United Kingdom
  • European Union
  • Australia
  • Russia
  • Gulf states
  • India
  • Asia
  • Africa

Each template sets out the rules stores in that region usually start with: weight bands, a surcharge for remote postcodes, and free shipping over an order value. You type the amounts in your own currency. Suggested amounts appear when your store uses the template’s currency.

  • Leave the free-shipping amount empty to leave that rule out.
  • Nothing goes live until you click Save changes, and the simulator prices the new rules straight away.
  • The remote-area postcode lists are a starting point. Add the areas your carrier also surcharges.

Test carts and the simulator

The cart simulator sits beside your rules and prices every test cart again each time you change something, before anything is saved.

Building a test cart

  • Add products and variations from your store with a quantity. They’re measured exactly as checkout measures them: weights, shipping classes, categories and tax.
  • Or add a custom item with a name, quantity, price, weight, shipping class and categories, to test a case your catalogue doesn’t have yet.
  • Set the address (country, state and postcode) and an optional discount.

Reading the result

The selected cart shows what the rules measured (subtotal, weight, items and postcode), what the customer pays, the “Add X more for free shipping” amount when there is one, and a line for every rule saying whether it matched and why. Each rule card in the builder also shows what it did for that cart.

If the cart’s address is outside the method’s zone, the simulator says so: checkout wouldn’t offer the method there at all.

Test carts save by themselves and every HaywoodTech Conditional Shipping method on your store shares them. You can keep up to 20 carts with up to 50 lines each, so the simulator stays quick.

Why an order paid what it did

On the order screen

Under each shipping line the plugin priced, you see the rules that matched and a link to edit them. Open How this cost was worked out to see what the rules measured and what every rule did, exactly as they were when the order was placed, even if you’ve changed the rules since.

On your own cart

Turn on Debug panel for shop managers under WooCommerce › Settings › Shipping › Shipping options. While you’re logged in as a shop manager, a panel on the cart and checkout pages shows:

  • where the cart ships to and which zone WooCommerce matched;
  • every rate offered, and which one is chosen;
  • for each HaywoodTech Conditional Shipping method in the zone, its answer and the reason for every rule.

Customers never see the panel. It’s off by default.

Free-shipping notice

When a rule offers free shipping over an amount and the cart hasn’t reached it, the cart tells the customer how much more to add: Add £30.00 more for free shipping. It appears in both the classic cart and the Cart block, and updates as the cart changes.

If several methods have a threshold, the smallest amount is shown. Turn it off with Free-shipping notice in the cart under WooCommerce › Settings › Shipping › Shipping options.

Postcode patterns

Postcode conditions take a list of patterns. Paste a list to add several at once. Matching ignores upper and lower case.

PatternExampleMatches
Exact90210That postcode. Spaces and hyphens are ignored, so SW1A1AA matches SW1A 1AA.
WildcardSW1A*Every postcode starting with SW1A.
Range90200...90299Postcodes made of digits from the first number to the second, both included. A postcode with a different number of digits doesn’t match.
With a spaceKW15 *Compared with the postcode as it’s written locally, so it matches KW15 1AB but not KW1 5AB.

The builder’s help text shows examples in your store’s own country format.

Editing rules as JSON

The Rules and JSON switch above the rules shows the same rules as text. Use Copy JSON to send them to a developer or support, or paste a rule set in. If the JSON doesn’t parse, the builder shows where and stays on the JSON view.

If the builder can’t load in your browser, the settings page shows the JSON editor instead, so you can always edit your rules. Rules with errors are never saved, from either view.

For developers

Checkout, the cart, the simulator and the debug panel all price through the same rules engine, so they always agree. These hooks let you adjust it:

HookArgumentsUse it to
hwtcs_cart_context
filter
array $cart, array $package, ShippingMethod $methodChange what the rules see before a cart is priced, for example to convert amounts back to the base currency when a currency switcher has converted them.
hwtcs_free_shipping_notice
filter
string $message, float $remainingChange the notice, or return an empty string to hide it. The amount is in the base currency.
hwtcs_register_types
action
Registry $registryAdd your own condition and action types.

For example, to change the wording of the notice:

add_filter( 'hwtcs_free_shipping_notice', function ( $message, $remaining ) {
	return sprintf( 'Spend %s more and shipping is on us.', wc_price( $remaining ) );
}, 10, 2 );

The plugin works with High-Performance Order Storage and with the cart and checkout blocks. Each order’s shipping line keeps what priced it as hidden order item meta.

Troubleshooting

The method doesn’t show at checkout
  • No rule matched the cart. By default the method is then hidden. Add a last rule with no conditions for “everywhere else”, or set When no rule matches to Offer it free.
  • The address is in another zone. WooCommerce picks one zone per address, and only that zone’s methods are offered. The simulator warns you when a test cart is outside the method’s zone.
  • Your last change wasn’t saved. Rules with errors are turned away with the problems listed, and checkout keeps the rules it had.
  • Another plugin removed the rate. The debug panel says so when the rules offer the method but it isn’t among the cart’s rates.
A cart pays a different amount from what I expected

Open the cart with the debug panel on, or rebuild it as a test cart. The reason for every rule shows which condition didn’t fit. Check the subtotal setting (tax and coupons) and the rule set’s weight unit first: they cause most surprises.

Does it work with the cart and checkout blocks?

Yes. The blocks and the classic cart and checkout get the same rates, and the free-shipping notice appears in both carts.

Does it work with currency switchers?

Rule amounts are in your store’s base currency, and most currency switchers convert shipping rates themselves. If yours also converts cart totals, use the hwtcs_cart_context filter to convert them back before the rules run, and hwtcs_free_shipping_notice for the notice.

Does it work in my country, currency and units?

Yes. Rules remember the weight unit they were written in, amounts are in your store’s currency, and postcode rules follow your country’s format. Nothing assumes a country.

Privacy and uninstalling

The plugin doesn’t contact any external service. Your rules, test carts and settings stay in your WordPress database.

Deleting the plugin from Plugins › Installed Plugins removes its two settings and the test carts. Your shipping methods stay in their zones with their rules, as WooCommerce’s own methods do, so reinstalling brings your setup back. Deactivating removes nothing.