Weight for Craft CMS

Troubleshooting

Start in the simulator. Almost every question below is answered faster by quoting the cart in Weight → Simulator and reading the rule trace than by reasoning about it, because the trace names the exact condition that failed and shows every number that went into the price.

The method doesn't appear at checkout

In roughly the order worth checking:

  1. Is the method enabled? A disabled method is never registered with Commerce.
  2. Did any rule match? With hideWhenNoRuleMatches on — the default, and what WooCommerce does — a method whose rules all missed is not offered at all. The simulator will show every rule and why each one missed.
  3. Is there a required rule that missed? One is enough to withdraw the method.
  4. Is there a disable rule that matched? "Nothing over 30 kg" does exactly what it says.
  5. Is the method restricted to certain sites?
  6. Is the cart's destination outside every destination condition? While the cart has no shipping address, destination conditions are judged against the customer's estimated address — and only if useEstimatedAddress is on. With it off, and no address yet, a destination-conditioned rule cannot match.
  7. Is the cart unpackable? With unpackable behaviour set to unavailable, an item that fits no box withdraws the method. The simulator flags the item.
  8. Is Commerce enabled? Weight registers nothing at all if Commerce is missing or disabled, and says so rather than fataling.

The price is higher than I expected

Nine times out of ten: rules do not OR. Every matching charge rule contributes. If you wrote

First 2kg   ≤ 2kg    flat 4.50
Above 2kg   ≥ 2kg    flat 4.50 + per-kilo

then a 2 kg package matches both and pays twice. Set the second band's minimum to exclusive (> 2kg) — the inclusivity switches at each end of a weight band exist for precisely this.

Other candidates:

  • A handling rule with no conditions is meant to be added to everything. If you intended it as an alternative, it needs a condition or a stop.
  • Whole steps round up. A 2.1 kg overage at a 0.5 kg step is five steps. That is the setting working; set the step to zero for continuous charging.
  • Per package rating multiplies every flat cost by the number of packages. That is the point of it, but it surprises people the first time packing splits a cart.
  • Box weight and packaging cost are real money and real weight. Each box adds its tare weight to the billable weight and its cost to the quote.
  • Dimensional weight bills the heavier of real and volumetric weight. A large light parcel is supposed to cost more.

The price is lower than I expected

  • A free rule matched and short-circuited everything below it. Check its subtotal condition against the cart's — remember that subtotal defaults to after discounts.
  • A stop rule matched before the rules you expected to charge.
  • The method's maximum cost clamped it. The simulator prints the clamp as its own line.
  • Non-shippable line items and items already carrying free shipping are excluded from packing, so they contribute no weight and no per-item charge.

Everything is free, or shipping is zero on a digital order

A cart with nothing shippable in it is quoted as available at zero deliberately — otherwise a digital-only order could not check out. It is not reported as free shipping: quote.isFree is false when nothing was packed, so a free-shipping banner won't fire on an empty basket.

Free-shipping progress shows nothing

craft.weight.progress() needs a free-shipping rule to make progress towards. It returns a Progress whose remaining is null when there isn't one, or when the rule's condition isn't of a kind you can be a measurable distance from — a destination, say. Progress is reported for a subtotal, a quantity or a weight.

If a store has several methods with free-shipping thresholds, progress reports the nearest one.

A condition-builder rule behaves oddly

A condition that throws is caught, logged, and fails closed — the rule does not match, and the reason is in the simulator's trace. That is on purpose: a broken condition must not take checkout down. Look for the reason in the trace, then in the Craft logs.

The quote is stale

It shouldn't be. Quotes and packing memoize on a full cart signature — line items, quantities, weights, prices, shipping categories, address, coupon — not on the order number, which survives a recalculation unchanged. If you are seeing a genuinely stale price, capture the cart and get in touch.

The backstop method shows up even when the carriers are working

Check the rule's Carrier rates setting is only when no carrier rate came back, and then check the simulator's trace for that rule — it names which of the three states applied.

The one that surprises people: before the cart has a shipping address, the carriers have not answered, and Weight treats that as no rate. So a backstop is offered during the estimate step and withdraws once Postie actually reports. That is deliberate — a checkout with one option too many is recoverable and a checkout with none is not.

A preset's rates are a thousand times too big or too small

The preset was written in different units to the store. royal-mail-uk and dhl-express-intl are in kilograms; ups-ground-us, fedex-home-us and usps-priority-us are in pounds. Nothing is converted on import.

weight/presets/import warns before it writes anything, but the warning is easy to skim past because the result looks plausible — every band populated, every number round. Print the ladder and read the unit in the column header:

php craft weight/rates/table <handle> 1 10 1

Turning on the log

Set Log quotes in the plugin settings and every quote is written out — the packing, the rules, the components, the clamps. It is verbose. It is also exactly what you want the afternoon a customer disputes a shipping charge from three weeks ago.

Getting a rate table out

Before going live, print the ladder rather than spot-checking:

php craft weight/rates/table standard 0.5 20 0.5 --country=GB --verbose

It is much easier to see a discontinuity in a column of numbers than to find it by guessing at weights.