11 min readOct 16, 2026by jakub

Changelog

Current version: 1.0.0

Every package in the suite is released together. Each version below lists the packages that changed in it.

1.0.0 — 2026-10-10

Free Gift

First release. Free gift campaigns for Magento 2 / Mage-OS.

Campaigns

  • Free gift rules with their own admin screen, separate from Cart Price Rules. They do not compete with other extensions over the salesrule table or its form, and campaigns can be scheduled, limited and scoped independently of your discounts.
  • Conditions use Magento's familiar condition builder — the same interface as a Cart Price Rule, so there is nothing new to learn. Nested combinations and exclusions are honoured wherever a campaign is evaluated, including the storefront badges.
  • Four ways to give, chosen per campaign:
    • Add the gift automatically — the gift arrives as soon as the basket qualifies.
    • Let the customer choose — offer a pool and let the customer pick, one gift or several.
    • Tiered by spend — thresholds that award more as the basket grows. The highest reached threshold wins and its quantity multiplies each pool row, so lower tiers are replaced rather than stacked.
    • One per N bought — buy-X-get-Y and same-SKU BOGO, counting paid parent lines that match the campaign's trigger SKUs. Earned quantity is floor(paid matching quantity / buy step) × gift quantity × pool row quantity; a gift never counts as a new purchase, so buying and receiving the same SKU produces separate paid and free lines, and reducing the purchase withdraws the excess gift.
  • Coupon-gated campaigns: the gift unlocks when a code is entered, and is advertised nowhere until it is.
  • Scheduling: campaigns with a start date are prepared in advance and begin on the day. No reindex on the morning of a launch.
  • Scoping by website, store view and customer group.
  • Limits: uses in total, uses per customer, and a maximum number of gift units per cart on both the campaign and the store.

What the customer sees

  • A badge on the product page and in category listings for gifts earned by a particular product, each using the wording the merchant wrote for that surface. Server-rendered, so it costs no JavaScript and does not break full-page cache. Starting or stopping a campaign drops the cached pages that show it, at the point the trigger index is rebuilt rather than before, so a campaign switched off stops being advertised at once instead of at the cache's next expiry.
  • A popup when a gift is earned, announced politely to screen readers, that costs no extra request — it rides the call the storefront already makes.
  • A cart section listing gifts earned and gifts still to choose, sitting directly beneath the items table.
  • Spend-tier progress in the cart and at checkout, measured the same way the campaign qualifies baskets, so the number a customer is working towards is the number that will award the gift. Amounts shown in another currency are converted for display only.
  • A campaign widget the merchant places from Content → Widgets, in any of eighteen containers including product-page and cart containers. It lists the campaigns earned by the basket, the campaigns earned by the product being viewed, or both, as a list or as a one-line banner — so a store that would rather show an inline list than the popup can, without touching layout XML.
  • The ability to decline a gift and have that stick, and to change their mind afterwards. Every gift affordance is a plain form post, so it works with JavaScript disabled.

Merchant controls

  • Surface visibility per campaign. A campaign chooses which storefront surfaces it may advertise itself on — the product-page badge, the category listing badge, the add-to-cart popup, the campaign widget — rather than appearing on all of them the moment it has any wording. One campaign can badge product pages and stay off the home page while another does the reverse. The cart is deliberately not offered: everything the cart panel shows is transactional rather than promotional, and a campaign that opted out of it would leave a customer qualifying for a choose-N gift with nowhere to choose it.
  • Gift tax basis per campaign: tax the gift on what the customer pays, or on its normal price. Jurisdictions differ; this module does not decide for you. Either basis is calculated with Magento's own tax algorithms and carried through cart, order, invoice and refund.
  • Gift affects shipping per campaign, so you decide whether the gift's weight reaches the carrier.
  • Qualifying merchandise value on a configured basis — before or after discount, including or excluding tax, following the store's own setting and inheriting through website and store view. Gifts and shipping are excluded; the measure is independent of the gift tax setting.
  • Maximum gifts per cart in two deliberate places: on the campaign, and store-wide in Stores → Configuration → Qoliber → Free Gift. Both count awarded gift units including multi-unit pool rows, zero means unlimited at that scope, a campaign cannot raise the store cap, and an oversized row goes unavailable without hiding the smaller options that still fit.
  • Out-of-stock behaviour for a gift that runs out while it is in someone's basket.
  • Fully translatable: every user-facing string ships in i18n/en_US.csv.

Campaign tools

  • Campaign preview (Marketing → Free Gift Campaign Preview) evaluates a saved campaign against sample SKU and quantity rows for a chosen store and customer group, and explains in words which of scope, condition, coupon, usage, stock or gift limit turned the gift down. It is read-only: no shopper cart is created, no selection or counter changes.
  • Duplicate as disabled draft, from a campaign's edit page. Settings, scope, wording, conditions, pool and tiers are copied to independent records — editing the copy never reaches back into the original — and campaign usage resets. The draft arrives disabled, to be reviewed before it goes live.
  • Starter templates (Marketing → Free Gift Starter Templates) create disabled spend, customer-choice, spend-tier, buy-X-get-Y and same-SKU BOGO drafts.
  • Campaign report (Reports → Free Gift Campaign Report) shows orders, gross and net gift units, and the gift catalogue value recorded at the moment each order was placed — changing a catalogue price later does not rewrite history. Cancellations and gift refunds reduce net quantities, influenced revenue counts an order once per campaign and subtracts order refunds, and figures are kept separate by store and by the base currency of the time. Distinct customers are counted from recorded campaign identities; neither the report nor the export exposes any customer detail.
  • CSV export over the same filters and metrics, with spreadsheet formulas neutralised. Filters take inclusive UTC dates up to 366 days.
  • Separate role permissions for report access, CSV export and preview, so reading a report and taking the data out of the building are different grants.

For developers and integrators

  • REST endpoints for the whole gift lifecycle, in all three families Magento authorises differently: /V1/carts/mine/... for a customer token, with the cart id forced from the token; /V1/guest-carts/{maskedId}/... for a guest; and an id-taking family for an integration. Reading a cart's offers, reading its selections, selecting, releasing, declining a campaign and restoring it are all available — including reading selections, so a chosen gift can be swapped rather than the whole campaign declined.
  • GraphQL through the companion qoliber/free-gift-graphql package.
  • Multi-Source Inventory through the companion qoliber/free-gift-msi package. Stock is asked through an interface: this package answers with Magento_CatalogInventory, so a single-source store never has to install or keep MSI.
  • Hyvä through qoliber/free-gift-hyva for the theme, and qoliber/free-gift-hyva-checkout for gift controls inside licensed Hyvä Checkout. Both are optional and hold no business logic.
  • Concurrency-safe by construction. Cart writes are rejected if the quote moved underneath them, gift lines are persisted under the cart lock, and a redemption batch is captured atomically under the order lock against a unique capture key — so two simultaneous requests cannot award the same gift twice, and an interrupted write can be retried without duplicating history.
  • Gifts survive reorder, invoice and credit memo correctly, and every give-away is recorded so it can be accounted for.
  • Works from any path that changes a cart: the storefront, the REST API, GraphQL, and an admin creating an order on a customer's behalf. Works on installations with a table prefix.

Requirements

PHP 8.1–8.5 on Magento Open Source 2.4.6–2.4.9. See the module's README for the runtime matrix. Native single-address checkout is supported; native multishipping is outside the support scope.

Known limitations

Documented in the module's MERCHANT.md. In short: release 1 gives away simple, virtual and downloadable products; configurable arrives in release 2, bundle and grouped in release 3. Basket-earned and coupon-gated campaigns show no product badge, by design.

Free Gift GraphQL

First release. GraphQL for headless and PWA storefronts, over the same engine Luma and REST use.

Features

  • Cart.qoliber_free_gifts — everything a storefront needs to render free gifts for a cart: gifts already earned, gifts still to choose, and which campaigns the customer has declined. Available on both cart(cart_id:) and customerCart.
  • selectFreeGift — take a gift the cart is offering.
  • releaseFreeGift — give one chosen gift back, freeing its slot. Keyed by selection rather than by gift, so a customer can return the medium and keep the large. FreeGiftEarned carries the selection_id the mutation needs, so a client with only the schema to go on can make the call.
  • declineFreeGiftRule / restoreFreeGiftRule — turn a campaign down, and change your mind.
  • Fully translatable: every user-facing string ships in i18n/en_US.csv.

How it behaves

Arguments are named in snake_case, matching Magento's own schemas (applyCouponToCart(cart_id:)) so this module is not the odd one out in a merchant's graph.

Every resolver is a thin adapter over the same service contracts the storefront uses, so a campaign behaves identically whichever way a cart is changed. A refusal from the engine reaches the client as a GraphQL input error carrying the engine's own message, rather than as an unhandled exception. Cart ownership is checked on every call: a masked cart id is not a password.

Free Gift Hyvä

First release. Hyvä templates for the Free Gift storefront.

Features

  • All five storefront surfaces in Hyvä markup: the product-page badge, the category listing badge, the cart gift panel, the add-to-cart popup on Alpine, and both campaign widget templates. No business logic — every template reads the same blocks and view models as the Luma frontend, so a campaign behaves identically on either theme.
  • Spend-tier progress in the cart panel, using the engine's own merchandise measurement and highest-reached-tier policy, so the figure a shopper sees on a Hyvä store is the figure that awards the gift.
  • Unit caps honoured in the chooser, including pools whose options carry different quantities, so an option that would exceed the campaign or store cap is shown unavailable rather than offered and then refused.
  • CSP-ready: the earned-gift popup's inline script and Alpine component are registered for Content Security Policy, merchant configuration is passed as escaped data attributes, and event handlers are CSP-compatible — the templates run on a store with CSP in restrict mode.
  • Tailwind built for two compilers. Hyvä 1.2–1.3 ships Tailwind 3 and 1.4+ ships Tailwind 4, and the two read different files: module.css for v4, tailwind.config.js plus tailwind-source.css for v3, with the rules in components/ as one source of truth. Colour tokens are declared in both @theme and theme.extend.colors, since each is version-only.
  • Registration for the Hyvä build (qoliber/hyva-module-registration), without which the theme build never discovers this module's Tailwind directory, and template fallback (hyva-themes/magento2-compat-module-fallback) for the widget templates, which layout cannot reach because a widget instance stores its template path in the database.
  • Fully translatable: every user-facing string ships in i18n/en_US.csv.

Requirements

Needs a Hyvä theme: vendor/hyva-themes must be present for the templates to build or run. Validated against Hyvä Theme 1.5.2. Install alongside qoliber/free-gift, which holds the blocks and view models these templates read. This companion installs no checkout; gift controls inside licensed Hyvä Checkout are a separate package, qoliber/free-gift-hyva-checkout. Rebuild the theme's Tailwind CSS after installing.

Free Gift Hyvä Checkout

First release. Gift controls inside licensed Hyvä Checkout.

Features

  • Gift selection without leaving checkout. A Magewire component lets a shopper choose a gift, remove one, decline a campaign and restore it from the checkout panel, so a customer who reached checkout before noticing the offer does not have to go back to the cart.
  • Spend-tier progress at checkout, on the same merchandise value and highest-reached-tier policy as the engine — the same number the cart shows.
  • Cart reconciled before checkout initialises, so a basket whose gifts changed elsewhere arrives at checkout already correct rather than correcting itself under the shopper.
  • Checkout step preserved when a campaign gift is withdrawn, instead of resetting the shopper to the start. Removing a paid item keeps Hyvä Checkout's normal navigation reset.
  • No business logic. The core engine owns qualification, stock, caps, pricing, taxes and redemption usage; this package is an adapter over the same service contracts the storefront and the REST API use.
  • The loading overlay toggles immediately, which avoids orphaned Alpine transition promises during rapid updates.

Requirements

PHP 8.1–8.5 on Magento Open Source 2.4.6–2.4.9, qoliber/free-gift and qoliber/free-gift-hyva 1.0.x, Hyvä Checkout 1.3.10.1 and Magewire 1.13.3. Validated on Magento 2.4.9 with Hyvä Theme 1.5.2 and Hyvä Checkout 1.3.10.1; other checkout and theme versions, and third-party payment methods, need validation. Also requires hyva-themes/magento2-legacy-modal-compatibility for address dialogs — enable Hyva_LegacyModalCompatibility alongside this companion, and rebuild the theme's Tailwind CSS.

A Hyvä Checkout licence and its Composer access are required separately. The Theme companion and the Free Gift Suite remain fully usable without licensed Checkout. Native multishipping checkout is outside the supported paths.

Free Gift MSI

First release. Multi-Source Inventory support for qoliber/free-gift.

Features

  • MsiStockFilter, bound to Qoliber\FreeGift\Api\GiftStockFilterInterface by this module's di.xml, so gift availability is answered per sales channel through MSI. Installing the package is the whole configuration — there is nothing to switch on.
  • Quantity-aware answers. The complete gift quantity is checked, and demand for the same SKU across the whole cart is aggregated, against reservation-aware salable stock — so a cart does not qualify for three of a gift when only two can ship.
  • Native restrictions respected: a product's requested-quantity rules and the campaign's explicit gift backorder policy both apply, and a negative stock threshold is read as backorder allowance when gifts must ship from stock on hand.

Why it is a separate package

Stock is asked through an interface. qoliber/free-gift answers it with Magento_CatalogInventory; this package answers it with Multi-Source Inventory. A single-source store installs neither this package nor MSI and keeps working, and a multi-source store gets the MSI answer by installing this one. Uninstalling it falls back rather than breaking.

Free Gift Suite

First release of the metapackage.

Features

  • Installs qoliber/free-gift and qoliber/free-gift-graphql.
  • Suggests qoliber/free-gift-msi, qoliber/free-gift-hyva and qoliber/free-gift-hyva-checkout, which stay opt-in: MSI is only worth its seventy-odd modules on a multi-source store, the Hyvä templates are only worth installing on a Hyvä theme, and the Checkout companion needs a Hyvä Checkout licence.
Changelog — Free Gift — Marketing — Extensions | qoliber Docs