Introducing Discount & Coupons for Solidshop — promotions with real rules

Buy-one-get-one, tiered pricing, conditional free shipping, a visual rule builder and bulk coupon codes — the promotions your marketing plan actually asks for, without a developer.

Every store owner eventually writes the same sentence in an email to their developer: “Can we do free shipping over $75, but only for newsletter subscribers, and not on the clearance rack?” The answer is usually yes, and the cost is usually a week and a custom plugin nobody wants to maintain after the campaign ends.

Today we are releasing the Solidshop Discount & Coupons plugin so that sentence becomes a form you fill in. It extends the discount engine that ships free in Solidshop core — percentage and fixed-amount discounts triggered by a cart total or a coupon code — with seven new conditions, five new actions, an AND/OR rule builder, stacking controls and a bulk coupon generator. Nothing in core is replaced; the plugin registers its pieces through the same events any third-party plugin could use.

Conditions you can nest

The heart of the plugin is a rule builder on a new Advanced Conditions tab of the discount editor. A rule tree starts with one group, each group has an AND/OR switch, and groups nest. That is enough to express things like “10% off for VIP members ordering at least three Accessories, or for anyone placing their first order” as two sub-groups under an OR — no code, no expression syntax to learn.

The conditions inside a group are the ones merchants keep asking for:

  • Customer group — match against the shopper’s Joomla user groups, so a loyalty tier is just a group.
  • Purchase history — first order ever, lifetime spend above an amount, or has previously bought a specific product. Win-back and loyalty campaigns in one place.
  • Product category, SKU and SKU quantity — require the right items, or the right number of the right items, before the discount fires. SKU quantity counts only the listed SKUs, so one matching unit plus one unrelated unit does not satisfy a threshold of two.
  • Cart quantity — total units across the cart.
  • Location — country or country-state codes, checked against the shipping address.

Location has a subtlety worth knowing: on the cart page no address exists yet. Rather than rejecting a perfectly good coupon, the cart accepts it and labels it Confirmed at checkout, then re-evaluates it against the real address once the shopper gets there. The rules still apply to the core conditions too — a discount must pass its minimum cart total and usage limits and the rule tree.

Actions beyond “percent off”

The Action tab gains five new types, each with its own settings that appear when you pick it:

  • Buy X get Y (BOGO) — set the buy quantity, the get quantity and how much the “get” units are discounted (100% makes them free, 50% halves them). The cart is split into complete groups and each group discounts its cheapest units, so a buy-2-get-1 on seven units makes two units free and charges full price for the seventh.
  • Tiered by cart total — a table of thresholds, each with its own percentage or fixed amount. The highest tier the cart reaches wins.
  • Fixed price per unit — sell chosen products, variants or whole categories at a set price. Items already cheaper than that price are never marked up.
  • Free item — take the price of a chosen product (or variant) off the order once the shopper adds it. Pair it with a minimum cart total for “free tote bag with every order over $75”.
  • Shipping discount — a percentage or fixed amount off the shipping cost rather than the subtotal. Conditional free shipping, done properly.

For percentage, fixed and tiered discounts there is also a new Scope selector. Left at Cart total, the discount is calculated on the whole order, exactly as core does. Switched to Product level, the base is limited to the items that match your category and SKU rules. “20% off all T-shirts” is therefore a category rule plus product-level scope — and not 20% off the entire order the moment one T-shirt lands in the cart.

Shipping discounts that show up everywhere

Shipping discounts deserve their own paragraph, because half the work was making them visible. The discount never exceeds the rate the shopper picked, so $10 off a $6.50 rate takes $6.50 and an order that already ships free gets nothing off. Checkout shows the original cost struck through beside the reduced one, and the order, the confirmation email, the customer’s account page and the invoice all carry a separate Shipping discount line that is deducted from the grand total next to the regular discount.

Because no shipping rate is known on the cart page, a coupon whose only effect is a shipping discount gets the same Confirmed at checkout treatment as a location-restricted code. The mini-cart and cart summary do not guess at it; it appears once a rate is selected.

Stacking you can reason about

Core already resolves stacking with Priority and Combinable: combinable discounts add up, and among the non-combinable ones only the highest priority survives. The plugin adds two controls on top.

An Exclusive switch on a discount means that when it qualifies, it is the only discount on the order — every other one, combinable or not, is dropped. It is the setting for a clearance sale that must never meet a coupon. If two exclusive discounts qualify at once, priority decides.

A single plugin option, Maximum Discounts Per Order, caps how many discounts can apply at all. After exclusivity is resolved, the survivors are cut to that number, highest priority first. Leave it blank and there is no cap, as before.

Hundreds of single-use codes in one click

Influencer campaigns, magazine inserts and partner referrals all want the same thing: many unique codes, each usable once, each traceable. Build one coupon-code discount as a template — conditions, action, dates, usage limits — save it, and a Bulk Generate Codes tab appears. Pick an optional prefix and a quantity up to 500 per run, and each generated code (SPRING3F9A1C7B, say) becomes a standalone discount with a full copy of the template’s settings, including the rule tree and the exclusive flag.

The codes are listed with Copy All and Download CSV buttons — a single column, ready for a mail-merge. Set a usage limit of 1 on the template before generating and every code is single-use; the limits are copied rather than shared, so redeeming one code never counts against another. Generated codes are ordinary discounts in the Discounts list, searchable by prefix and unpublishable in bulk when the campaign ends.

What happens when the plugin is off

A promotion that silently does nothing is worse than one that is switched off, so the engine fails closed. Disable the plugin and a discount that depends on a rule-builder condition or a plugin action type simply stops applying; discounts built from core conditions and actions keep working. Open one of those discounts in the editor while the plugin is disabled and saving leaves its plugin-owned action untouched rather than overwriting it with a percentage — enable the plugin again and nothing is lost.

Uninstalling drops only the plugin’s own table. The discounts themselves are merchant data in core and stay put; any that could never apply without the plugin are unpublished during uninstall so they do not sit in the list pretending to work.

Setting it up

  1. Install plg_solidshop_discount.zip through System → Install → Extensions.
  2. Enable Solidshop - Discount (Advanced) in the Plugin Manager.
  3. Open Solidshop → Discounts, edit or create a discount, and the Advanced Conditions tab, the new action types and the Scope selector are there.

Every condition, action and operator is described, with a worked example, in the Discount plugin documentation.

Requirements & availability

Discount 1.0.1 needs Solidshop 1.3.2 or later, Joomla 6.0+ and PHP 8.4+ — the installer checks first and refuses to run against an older core. Core 1.3.2, released yesterday, is the release that stores the plugin’s action-type settings and records a shipping-only discount on the order, so the Shipping discount action survives checkout, shows on the order and counts against usage limits. Twenty-three admin locales ship in the package.

It is $59, one-time, per domain, with 12 months of updates and support included; renewals thereafter are 30% off. The code is GPL-3, and it runs entirely on your own server — there is no promotion service to subscribe to and no per-order fee.