Changelog¶
What changed in each release of Product Bundles, in terms of what it means for you rather than which files moved.
1.6.1 — 3 October 2026¶
Corrections only. No setting was added or changed, nothing new is stored, and the API answers exactly the fields it did in 1.6.0.
- Status off now takes every bundle off sale, and an update leaves it that way until you switch it back on. Until now a bundle's carrier product stayed on sale whatever the switch said, and an update put every carrier back on sale while switching the module off. With the module off nothing priced the bundle, nothing refused one that could no longer be packed and nothing took its components off the shelf, so a bundle could sell as a plain product at a stale price with its components' stock never moving. The carriers now follow the switch: off, every bundle is off sale; on, each goes back on sale as its own Status says. Status comes back off after every update, this one included, so switch it on straight after updating. Status off says what else waits for the switch.
- What a shopper types into a bundle can no longer put markup on your order screens. A hand-crafted add-to-cart request could carry raw HTML in a bundle's free-text options past OpenCart's own cleaning, and the admin order, invoice and returns screens printed it as markup rather than as text. Every free-text choice is now escaped as it is read, however it arrived. Orders placed before this release keep what they stored.
- The API refuses an API user with an empty key. OpenCart's own form will not save one, but a row edited by hand in the database could hold one, and the API let in a caller who presented an empty key. This matters only if you switched the API on.
- Updating no longer adds to your permission lists. Each update appended another copy of the Catalog → Bundles and Reports → Bundle components sold entries to the installing group's permissions. Those entries are now granted only when the group lacks them. Copies earlier updates added stay, and change nothing.
- Uninstalling removes Product Bundles' two data-protection event rows. They stayed behind, naming files the uninstall had already removed.
1.6.0 — 2 October 2026¶
- A read-only JSON API, off until you switch it on. Your ERP or warehouse system can read what each order actually sold inside a bundle — every component and the options chosen on it, frozen as sold, which OpenCart's own order records nowhere — and what each bundle contains today. Nothing can be created or changed through it, and there is no money in it: prices stay on OpenCart's own order lines and products. Switch it on under API on the settings screen; a caller signs in as an OpenCart API user under System → Users → API. The API lists every field, and limits and guarantees says what it cannot do.
- Nothing to do on update. One new setting, the API switch, which arrives off — and, like the module switch, comes back off after every update, because this extension keeps no copy of its settings.
1.5.0 — 30 September 2026¶
- Bundles can now show on a component's own product page. Product Bundles has a layout module: place it on the Product layout at Design → Layouts and a product's page lists Bundles with this product, the bundles it is a component of. Placed on any other layout, such as Home, it is a shelf of your bundles in the Bundles page's own order; on a bundle's own page it leaves out the one being viewed. Each card is the Bundles page's own card, at the same price. With nothing to show it draws nothing, heading included. See the two guides and limits.
- One new setting, Bundles shown, under Layout module on the Product Bundles screen: how many cards the module shows, from 1 to 12, one number for every layout it is on. It starts at 4. It changes nothing until you place the module, and nothing is placed for you.
- Placing it no longer prints an error into your page. Earlier releases already offered Product Bundles in the Design → Layouts picker with nothing behind it, so a placement printed OpenCart's own error text, with a file path, where the module should have been.
- Reports → Bundle components sold is new: how many units of each product
left your store inside a bundle, and on how many orders, filtered by order
status and date, with a Download CSV button. Products Purchased counts the
bundle's own line, so a product sold only in bundles used to read nought there
while its stock drained. It never shows money, because the order never
recorded what one component cost. It needs Access on
extension/product_bundles/sale/component, which the user group that installs or updates Product Bundles is given; tick it for any other group that should see it. See permissions. - An update takes the module off your layouts. OpenCart's uninstall, which every update goes through, deletes a module's placements with it. Nothing is placed yet on a store coming from 1.4.0, so this first matters at the update after this one. See what an update keeps.
1.4.0 — 21 September 2026¶
- The floor moves up one release, from 4.1.0.0 to 4.1.0.1. 4.1.0.0 has the piece of OpenCart every verdict a bundle carries travels on, but declares the column behind it one byte wide, so OpenCart writes what the bundle says and the store keeps none of it. A bundle would have been charged at its carrier product's own price, its availability would have been OpenCart's answer rather than its components', and the checkout block on a bundle that could no longer be made would never have applied, with nothing on any screen saying so. A wrong charge on an order already paid is not acceptable as a documented limit, so Product Bundles now declines to install on 4.1.0.0 and says which version you need, exactly as it declines on 4.0.2.x. 4.1.0.1 widened the column. See limits.
- Nothing changes for a store on 4.1.0.1 or newer, which is every store the previous release's own tested list claimed.
1.3.0 — 21 September 2026¶
- OpenCart 4.1.0.4 is now a tested release. The full pass (archive, install, use, upgrade over itself, uninstall) has been through a 4.1.0.4 store, so the compatibility list ends at 4.1.0.4 and the settings screen stops calling that release untested. The floor did not move here; 1.4.0 moved it, and requirements says why.
- That release's broken scheduler costs Product Bundles nothing. See requirements. Every verdict a bundle carries is reached on the request that asks for it, and the bundles themselves are built from your own screen, so there was never anything here waiting on a schedule. Nothing else changes.
1.2.0 — 21 September 2026¶
- Product Bundles now publishes what it holds about a person, column by column, with what removes each one, for all nine of its tables, on what this holds about a person. Seven of them hold nothing about anybody: they are the bundles you built. The two that do are the order side, and the column that matters on them is the one holding whatever a customer typed against a bundle line.
- Customers > Personal Data answers what Product Bundles holds about one person and erases them from the same screen, alongside every other extension on your store that answers the same question. A person is found through their orders, because that is the only way this extension can reach anybody: it stores no name, no address and no customer id of its own.
- Remove everything held about a person is new, reached from the button on the Product Bundles settings screen. It empties the two order tables (what each bundle line contained, and what was chosen or typed for it) for every customer at once, without uninstalling. Your bundles, their prices, their contents and their reward bands are not read and not changed by it. It itemises what it will do, with a count beside each line, before you press it, and it is not reversible.
- Uninstalling still keeps everything, and the new screen says so where you will see it: an OpenCart upgrade is an uninstall followed by an install, so dropping tables on uninstall would destroy your data every time you upgraded.
Upgrade the way you installed. There is nothing to configure or switch on.
1.1.0 — 14 September 2026¶
Deleting an order now deletes what the shopper typed into its bundles. Where a component of a bundle carries an option a customer fills in (an engraving, a gift message, a name, as well as the sizes and colours they pick from a list), Product Bundles keeps its own copy, because that is what puts the contents on your order screen, your invoice and your packing slip. OpenCart's own order delete removes the order, its lines and its own copy of every option. It knows nothing about ours, so until now ours stayed behind, attached to an order number that no longer existed. That means it was on no screen you could find it on, and no customer request could reach it either, because the order that said whose it was had gone. It is now deleted with the order, along with the record of what each bundle line contained.
Your bundles are untouched by this. What goes is the record of one deleted order; the bundles you built, and every other order, are not read and not changed.
Upgrade the way you installed. There is nothing to configure or switch on.
1.0.1 — 14 September 2026¶
A cart holding a broken bundle stopped calling itself the Shopping Cart. It
was headed Bundle, and the line under it read - Product Code:: followed by
the bundle's model where your store prints - Model: followed by it. The same thing could reword a
product listing carrying a bundle card, and a bundle's review tab. Nothing was
stored wrongly and no price or total was affected. Only the words on those
screens changed, until the page was reloaded without a bundle on it.
The cause was a trap in OpenCart rather than a typo. OpenCart keeps every loaded language file's strings in one bucket and pours the whole bucket into whatever page it is drawing, and around a page's own controller it takes a copy first and puts it back afterwards. The three places Product Bundles writes into a screen OpenCart already built have no such boundary, so its own wording sat on top of your store's. Those three now load their strings under a name of their own, which nothing else can collide with.
1.0.0 — 11 September 2026¶
The first public release. There is no previous version to describe a change against, so this entry says what Product Bundles is rather than what moved.
It sells a set of existing products as one thing. A starter kit, a gift set, a camera and the lens that goes with it: you build the bundle out of products you already stock, give it one price, and it gets its own page in your storefront and its own row in your catalogue. When one sells, every component's stock comes down by what was in the box: a kit holding three straps takes three straps.
A bundle never has stock of its own. Whether it can be made is worked out from its components every time anybody asks, so a bundle whose components ran out last night says so this morning without you touching it. The arithmetic is harder than it looks. The same mug in two different bundles in one cart is one demand on one figure, so nobody is sold eleven of the ten you have.
Components can carry options. Where a component has a choice, such as a size, a colour or an upgrade, the bundle page asks for it, and the price it quotes includes what that choice costs. The cart is charged the number the page quoted, not a base price with the upgrade riding free.
Shipping and reward points are quoted on what is in the box, not on the carrier product the bundle hangs off.
A broken bundle is refused rather than sold. Take a component off sale, or delete it, and the cart says which line is the problem, the customer cannot check out holding it, and your bundle list badges it so you find out from your own admin rather than from a customer who could not pay.
It shows up where your customers already are. A bundle line shows what is in the box on the order page and, if you also run Returns Portal, on the customer's line picker, their confirmation screen, the RMA slip and your own request screen. There is nothing to switch on in either extension.
It needs OpenCart 4.1.0.0 or newer. This is the one extension sold here that does not go back to 4.0.2.0. Everything a bundle tells your cart (what the line costs, whether it can be made, what it weighs, what it earns) travels on one piece of OpenCart that only exists from 4.1 onwards, and on a 4.0.2.x store the worst consequence was that a customer could reach checkout holding a bundle you had no way to pack. Rather than ship that and write it down as a limit, Product Bundles declines to install below 4.1.0.0 and says which version you need. See the exception on the requirements page. 4.1.0.3 is the newest release a full pass has been run on; newer ones install and say on the screen that they are untested, including 4.1.0.4, whose scheduler bug costs this extension nothing because nothing here is scheduled.
It ships English and only English. Bundle names and descriptions are your own, per language, and always were.
Before 1.0.0¶
The versions below were never published. They are kept because the pages on this site refer to them.
0.3.0 — unreleased¶
- Product Bundles can now read a translation of its own strings once one exists. It works out which of the languages it ships a store should be served, rather than assuming the store's language code is spelled the way our directories are. It ships English and only English today, so that question has one answer.
- A store running more than one language gains one read-only card on the settings screen, saying which language each of theirs is served from. Bundle names and descriptions are unaffected. Those are the merchant's own, per language, and always were. See Limits and guarantees.
0.2.0 — unreleased¶
- A bundle line now shows what is in the box on Returns Portal's surfaces as well: the customer's line picker, their confirmation screen, the RMA slip and the merchant's request screen. There is nothing to switch on, and nothing changes if Returns Portal is not installed. The returns queue is deliberately left untouched. See limits.
What an update keeps¶
Nothing is lost: your bundles, their components, the options chosen on them and the record of what every past order had in its boxes all survive. Carriers that an uninstall disabled are re-enabled to match what their bundles say, so a store that had the module off for an afternoon does not come back to a storefront selling none of them. Edited language files are overwritten, which is the one thing an update always takes back.
The layout module's placements do not survive an update either. OpenCart's own uninstall step deletes every placement of a module along with the module, and Product Bundles keeps no copy of where you had put it, just as it keeps no copy of its settings. Place it again at Design → Layouts after updating.
What you built comes back; the settings below do not. An update is an uninstall and then an install, and OpenCart deletes an extension's settings at the uninstall step. Product Bundles keeps it in tables of its own and nothing here ever drops one — they hold your records rather than a copy of what you set, and Product Bundles keeps no copy of the settings themselves.
These are asked for again rather than put back:
module_product_bundles_status— Product Bundles keeps no copy of its settings, so OpenCart's own uninstall-then-install takes this with it and an update leaves the module switched off, with every bundle off sale. Switch it back on with the Status switch on this extension's settings screen; your bundles, their components and every order's history are untouched, and each carrier goes back on sale to match what its bundle says.module_product_bundles_surfaces— Kept nowhere but the setting table OpenCart deletes on an update, like the switch above, so an update puts every surface back on. Untick the ones you do not want again after updating.module_product_bundles_module_limit— Kept nowhere but the setting table OpenCart deletes on an update, so an update puts this back to 4. An update also removes the module from your layouts, because OpenCart's own uninstall deletes every placement of a module along with it: place it again at Design > Layouts after updating.module_product_bundles_diary_verbose_until— Detailed logging comes back off after an update, the way a fresh install does. An upgrade is an uninstall and a reinstall, and putting a diagnostic window back is how a store ends up verbose months after the support exchange that asked for it ended.module_product_bundles_api_enabled— The API comes back off after an update, the way a fresh install does: this extension keeps no copy of its settings, and an update is an uninstall and a reinstall. An integration that stops answering after an update is one its owner notices at once and switches back on; a store answering an API again that nobody switched on is not.
A setting a release adds does not change what your store does. Its default is what Product Bundles did before the setting existed, so an update never asks you to go and set something to get back the behaviour you already had.
What this cannot tell you is whether a release changed how a setting behaves, as against whether it survives. Nothing derives that from the code, so it is written by hand: a release that changes an answer you relied on says so in its own entry above, as its own paragraph and never among what is new.