I spent a few weeks last month building a WooCommerce plugin, and the most important decision I made wasn’t in the code. It was in the pricing page. I took the one feature every competitor charges for — conditional logic — and put it in the free tier.
Let me explain why that’s not generosity. It’s a wedge.
What “product options” even are
WooCommerce sells products. But a lot of real products aren’t a single fixed thing. A T-shirt with a name printed on it. A cake with a message and a delivery date. A made-to-order desk where the wood, the size, and the cable hole are all choices. A gift with optional wrapping for an extra five dollars.
WooCommerce, on its own, doesn’t give you a clean way to add those extra fields to a product and charge for them. So there’s a whole category of plugins — “extra product options”, “product add-ons” — that bolt fields onto the product page: text inputs, dropdowns, checkboxes, number fields, surcharges. My plugin, CoreLabs Product Options for WooCommerce, is one of them. It’s free on wordpress.org, with a paid Pro add-on I sell separately.
Conditional logic, in plain terms
The moment you have more than three or four fields, your product page gets ugly. You’re showing a customer an “engraving text” box even though they haven’t ticked “add engraving”. You’re asking for a delivery date on a digital download.
Conditional logic is the fix: rules that show, hide, or require one field based on the value of another.
- If “Add gift wrap” is Yes, show the “Gift message” field.
- If “Format” is not “Digital”, require the “Shipping address note” field.
- If “Size” is “Custom”, show the width and height inputs.
That’s it. It’s the difference between a form that feels like a thoughtful conversation and a form that dumps every possible question on every customer at once. Anyone who has actually run a store knows it isn’t a luxury feature. It’s the feature.
Why everyone gates it — and why I refused
Here’s the uncomfortable pattern across this category: the field types are free, the pricing is free, and then conditional logic is the thing behind the paywall. It’s the classic freemium bait. Give people enough to build a form, then charge them the moment that form needs to be usable.
I understand the temptation. Conditional logic is the feature with the clearest “I’d pay for that” reflex, so it’s the obvious lever to pull. WooCommerce’s own feature-request board has had an open ask for exactly this since 2019, with people piling on votes. The demand is not in question. That’s precisely why I think gating it is hostile. You’re not charging for something extra; you’re charging for the thing that makes the basic version make sense.
So I made a deliberate bet:
Free tier: single-condition logic — show / hide / require a field based on one other field, with is and is not. That covers the overwhelming majority of real stores. The gift-wrap-shows-the-message case. The custom-size case. The not-digital case.
Pro tier: the genuinely advanced extras — multi-condition rules with AND/OR, more operators (contains, greater-than, less-than), plus things that are real engineering: per-unit and percentage pricing, colour swatches, date fields.
The line I drew is: free gets you a form that works; Pro gets you a form that’s clever. Nobody should have to pay to make a four-field product page sane. People will pay to do something their competitors can’t.
This isn’t only ethics. It’s distribution. wordpress.org is a search engine. A free plugin that actually solves the problem earns installs, reviews, and trust — the organic funnel I never had selling inside a closed marketplace. A crippled free plugin earns one-star reviews that say “the useful part costs money.” Free conditional logic is the cheapest marketing I will ever buy.
The craft: one brain, two languages
The interesting engineering problem with conditional logic is that the same rules have to run in two completely different places.
WordPress is a PHP platform, and WooCommerce is built on it; that’s where the truth lives. When a customer adds to cart, the server has to re-evaluate every rule — you cannot trust the browser, because a hidden “required” field that the customer never saw must not block the order, and a hidden priced add-on must not be charged. So PHP is the source of truth for the cart and the money.
But the customer experiences the rules in the browser, instantly, as they click. That’s JavaScript. When you tick “gift wrap”, the message box should appear now, not after a page reload.
The trap is obvious: two implementations of the same logic drift apart, and you ship a bug where the page shows a field the server then ignores. My fix is to treat the evaluator as a single contract expressed twice. There’s a ConditionalLogic class in PHP and a mirror of it in JS, and they’re pinned together by a shared fixture file of input/output cases that both test suites read. If the PHP and the JS ever disagree on an answer, the tests go red. The fixture is the spec.
The part I’m quietly proud of is transitivity. Rules can chain: field C depends on B, and B depends on A. If you hide A, then B is gone, so C should be gone too — even though C’s own rule, read in isolation, might still “pass”. So instead of evaluating each field alone, I resolve an active-map across the whole group: a field is active only if its own rule passes and every field it points at is also active. It’s a small recursive resolver with a cycle guard so a misconfigured loop can’t hang the page. Both the PHP and the JS do this identically, against the same fixtures.
A: "Add engraving?" → checkbox
B: "Engraving text" → show if A is Yes
C: "Font" → show if B is not empty
Uncheck A and all three collapse, on the page and in the cart, the same way.
Classic and Block, because the platform moved
WordPress is in the middle of a long migration from the classic editor to the Block editor, and WooCommerce is dragging the cart and checkout along with it. A product-options plugin that only works in one of those worlds is half a plugin. So the rules have to render correctly whether the merchant is building on a classic product page or a block-based one, and whether the storefront uses the older cart or the newer block cart. That’s not a feature I get to charge for; it’s just the cost of being a serious citizen on a platform I don’t own. I build to it because WooCommerce and WordPress define the rules of the room — my job is to behave well inside them.
The model underneath
The whole thing is freemium: free plugin on wordpress.org as the front door, a paid Pro add-on for the advanced work, sold through my own channels. The free build is genuinely complete — a store owner can ship a real, conditional, priced product form without paying me a cent. Pro is a clean add-on that flips a single gate; the free codebase has extension points waiting for it, so the two stay in sync instead of forking.
If that sounds like I’m leaving money on the table by giving away the headline feature — I’m not. I’m buying the only thing that matters at the start of a plugin’s life: people who installed it, kept it, and told someone. You can monetize trust. You cannot monetize a one-star review that calls you a bait-and-switch.
Conditional logic, free. It’s the cheapest promise I could make and the most expensive one for a competitor to match.