Skip to content

Commerce / Field note

When WooCommerce needs custom logic, and when it does not

A decision framework for shop owners weighing a plugin, more configuration or a few lines of custom checkout code, and the honest default for most shops.

Marko Stančić 7 minutes

Field note / Commerce decisions

Most shops should configure WooCommerce properly and lean on one well-maintained plugin. Custom code earns its place only when the rule is specific to how that particular business works and has to be correct on every single order. The deciding question is never “can this be coded?” but “is this a business rule that must never drift from what the site promises, or a presentation preference we could drop next season?”

The rest is arithmetic and honesty. What follows are the questions that actually settle the decision, in the order we ask them when a shop owner arrives with a rule WooCommerce doesn't handle out of the box.

Business rule or presentation preference?

A business rule decides money or eligibility: who pays for shipping, which orders need extra verification, which customers see which price, whether an order may be placed at all. A presentation preference decides how something looks: a badge on the product card, the order of the payment methods, one more line on the cart page.

The distinction matters because a business rule has to be stated once. The moment the same rule lives in two places, a sentence written on the shipping page and a threshold typed into a plugin setting, it begins to drift. Someone edits the page during a campaign, nobody touches the setting, and the shop is now promising one thing and charging another. The shop pays for every hour of support that follows, and the customer remembers the discrepancy rather than the apology.

Presentation preferences do not carry that risk. If a badge is wrong, a customer sees a wrong badge. Fix it in a template, a plugin or a theme option. Nothing about it justifies custom checkout logic.

Count the plugins, then count the years

The plugin route looks cheaper than it is, because the licence fee is the only number that appears on an invoice. The real cost is the licence, plus the hours spent evaluating and configuring it, plus one more moving part that can break on the next WooCommerce release, plus a permanent dependency on somebody else's roadmap. None of that makes plugins a bad idea. It makes them a decision with a price rather than a free default.

The number that actually predicts pain is how many plugins the rule takes:

  • One actively maintained extension covers the whole rule: buy it and move on.
  • Two, where the second exists mainly to correct the behaviour of the first: look closer before you commit.
  • Three or more, with settings that contradict each other and an outcome that depends on load order: the rule is now an emergent property of your plugin list, and nobody can predict it.
  • An extension whose latest release predates your WooCommerce version: that's not a solution, it's a scheduled incident.

Renewal is the second axis. A licence is a yearly decision you keep making for as long as the rule exists, and the renewal price is set by someone else. Custom code has a one-time build cost and a small permanent maintenance cost. Over three or four years those two lines cross more often than shop owners expect, particularly when the rule is stable and the plugin is not.

Working principle

Custom logic should encode a rule the business would keep even if it moved to a different platform tomorrow. If the rule would not survive that move, it does not deserve code.

Catalogue or checkout: where does the rule have to hold?

A rule that only shapes the catalogue is a display problem. Get it wrong and somebody sees the wrong filter, the wrong sort order, the wrong badge. A rule at checkout is a different kind of thing entirely: it decides totals, shipping, tax, eligibility and the permanent record of what the customer agreed to buy. That is the line where custom checkout logic stops being a convenience and becomes a correctness requirement.

Rules at that line belong on the server, at supported WooCommerce hooks. Not in JavaScript on the page, which any browser can be told to ignore. Not in a copied template file, which will quietly stop running the day the theme updates and take the rule down with it.

On the JC Jewelers WooCommerce store, free shipping above $1,999 and identity verification above $1,000 are commercial rules rather than page copy. They sit in the checkout logic, and the text on the site reads the same values, so the number a customer is shown and the number applied to the order cannot disagree.

// The thresholds are declared once, in one file with a name.
const MS_FREE_SHIPPING_FROM = 1999;
const MS_ID_CHECK_FROM      = 1000;

// Checkout enforces them on the server, at a supported hook.
add_action('woocommerce_checkout_process', function () {
    $subtotal = WC()->cart->get_displayed_subtotal();

    if ($subtotal >= MS_ID_CHECK_FROM && ! ms_customer_is_verified()) {
        wc_add_notice(__('This order requires identity verification.'), 'error');
    }
});

// The shipping notice reads the same constant, never a retyped number.
add_shortcode('free_shipping_from', fn () => wc_price(MS_FREE_SHIPPING_FROM));

A dozen lines like that are not a rebuild of WooCommerce. They are the place where a rule is written down once, so the shop, the shipping page and the order record all agree without anyone having to remember to keep them in step.

Who maintains this in two years?

A plugin arrives with a vendor, a changelog and a support address. Custom code arrives with whoever wrote it, and with whatever they bothered to write down. That asymmetry is the strongest honest argument for buying, and it's also what makes custom work defensible when it's done properly.

Custom code that survives a handover looks like this: a small dedicated plugin with an explicit name rather than another block bolted onto the theme's functions file; documented hooks rather than edits to core or copied templates; a short comment stating the business rule in business language, not only what the code does; and the rule listed somewhere the shop owner can read without opening an editor.

If nobody at the shop can say which of the rules are custom, the shop isn't maintained, it's haunted. Every future developer treats unknown code as load-bearing and refuses to touch it, which is exactly how a three-year-old workaround becomes permanent.

A rule nobody can name is a rule nobody can maintain.

What happens on the day WooCommerce updates?

Both routes carry update risk. They simply carry different kinds. With a plugin the risk is transferred: less work for you, less control, and if the vendor abandons the product you inherit the problem anyway, usually at the worst possible moment. With custom code the risk is owned: somebody has to read release notes, stay on documented extension points and accept that a deprecation is their problem the day it lands.

What makes both survivable is the same short routine. Keep a staging site that mirrors production, plugin list included. Keep a written list of the order rules with the expected outcome for each one. Then, before any release reaches customers, place test orders that cross every threshold from both sides: one just below, one just above, one with a coupon, one with the awkward shipping zone. A shop that has only ever been tested on the happy path hasn't really been tested.

The honest default

Configure first. Plugin second. Code third. For most shops the process stops at the second step: WooCommerce settings, shipping zones and one respected extension will cover the rule, and the remaining budget is better spent on photography, stock or ads.

Custom code becomes the right answer when four things are true at the same time. The rule is specific to how this business works. It has to be correct on every order rather than most of them. It lives at checkout, where money moves. And it would still exist if the shop changed platform next year. JC Jewelers is a clean example of all four. A catalogue of 527 pieces across five categories, priced from $745 to $20,295, does not behave like a shelf of identical products. The order value rules were written once instead of being repeated in copy, and the enquiry for bespoke work runs beside the standard cart, because a ring that does not exist yet cannot be added to it.

That is the entire test for when to customise WooCommerce. Everything else, and everything else is most things, is a configuration question wearing a development budget. If you're weighing a plugin against custom code for a rule of your own, our WooCommerce development work starts with exactly this conversation, and it often ends with the conclusion that nothing needs writing at all.

Practical takeaway

Write the rule down in one sentence of business language. If it decides money at checkout and would survive a change of platform, it deserves code. If not, it deserves a setting.

View journal index

Apply the thinking

Let's take the friction out of the checkout

If payments, order flow or an integration are costing you sales, bring the details. We can define what should change first.

Discuss your project