Holio Shipping - full changelog

The plugin page on wordpress.org shows only the most recent release, because that
section of a readme is truncated. Every release is listed here instead, newest first.


= 1.2.2 - 2026-09-23 =
* New: A bulky order is now divided into several parcels when it is too big for one, not only when it is too heavy. Automatic package splitting only ever watched the weight, so an order of light but bulky goods - garden furniture, packaging, anything that stacks - kept growing until it passed what the carrier accepts, and the delivery method then vanished from the checkout with nothing said. The order is now divided into parcels that each fit, and the method stays available. Splitting is only attempted where dividing can actually help: a single item too long or too wide for the carrier stays too long however it is packed, and the method is still withheld. Requires "Enable automatic package splitting", and only applies to carriers that accept more than one parcel
* Fix: Parcels produced by a split are now measured the way the price quote measures them. Which of the three boxes a shop typed a measurement into decided how the parcels were stacked, so a shop that entered a box as 15x35x54 rather than 54x35x15 had its parcels measured along the wrong side - up to three times the volumetric weight the customer was quoted, and parcels the carrier could refuse. Both now take the largest side as the length and the smallest as the height, whichever field it was typed in
* Fix: Orders shipped under a fallback rule can be divided by size as well. The rule's parcel size limits were read when the rule was chosen and then thrown away, so by the time the shipment was created only the weight limit was left and an oversized parcel went out whole
* Dev: With debug mode on, the log now says why a delivery method was not offered - the carrier's own words when it declined, together with the size and weight of the package, and the reason whenever the plugin's own filters withheld a method. Previously a method could disappear from the checkout leaving no trace anywhere

= 1.2.1 - 2026-09-22 =
* Fix: The pickup point the customer chose no longer goes missing on checkouts that complete the order through their own callback. Every delivery method offering pickup points rendered its own copy of the hidden fields that carry the choice, and all of them shared a single name, so the browser sent one copy per method and only the last one counted - which was empty unless the customer happened to pick the last method in the list. The order then went out with no pickup point and was delivered as an ordinary parcel. Only the chosen method's fields are submitted now. The standard checkout was never affected, because it remembers the choice separately; an embedded checkout such as Svea paid with Vipps or card had nothing else to fall back on

= 1.2.0 - 2026-09-18 =
* New: Checkouts that have their own pickup point selector can now use it. Dintero and Qliro both include one, with a map and a search box, but it only appears if the shipping plugin hands them the list of pickup points - and we handed them nothing, so on those checkouts there was no way to choose a pickup point at all. A new setting on the Setup tab passes the list across, the customer chooses inside the checkout, and the point they pick is saved onto the order exactly as before. Only one of the two pickup point settings can be on at a time, and ticking one unticks the other. Leave it off for the standard WooCommerce checkout and for Svea, where our own selector is better, and for Klarna/Kustom, which has no selector to show - the setting above it covers those
* New: The carrier now travels with each delivery option, so a checkout that draws its own list can show the carrier's logo beside it. On Dintero every option previously arrived with no carrier at all and was given a grey placeholder icon, whichever carrier was actually carrying the parcel
* Fix: The estimated delivery time is no longer printed on the cart page. The checkout's stylesheet is not loaded there, so the line arrived with none of its styling - not the small grey note it is meant to be, but the theme's ordinary body text wedged under the delivery method's name
* Fix: The delivery method the customer chose is no longer replaced by another one. The carrier's price service returns the same methods in a different order from one request to the next, and WooCommerce reads a reordered list as a changed list - so it threw the choice away and fell back to whichever method happened to be first that time. The methods now keep a fixed order. On Klarna and Kustom this surfaced as an order that could not be completed at all, because the checkout still held the pickup point the customer had picked and the two sides no longer agreed; on the ordinary checkout nothing was reported and the parcel was simply sent by a method other than the one chosen

= 1.1.9 - 2026-09-16 =
* Fix: The pickup point selector now appears on shops whose checkout prints the delivery list more than once. Some themes have a second copy for the mobile order summary, and some shops add a snippet that moves the delivery options around, which can leave three copies on the page. Only one selector can be kept, and the wrong one was being kept - a copy inside a panel the customer never sees - so there was nothing to choose a pickup point with. Worse, that hidden copy was still filled in, and the first point on the list was quietly saved onto the order, so the parcel went somewhere the customer had not asked for and nothing on screen said so. The copy the customer can actually see is now the one that is kept
* Fix: The pickup point selector is also drawn more reliably when a theme rebuilds the delivery list. Having been asked to draw the selector for a delivery option, it went looking for that option all over again, which finds nothing once the list has been rebuilt. It now reads what it needs from the option it was handed

= 1.1.8 - 2026-09-16 =
* New: Pickup points can be shown as separate delivery options, for checkouts that will not display our selector. Some embedded checkouts - Klarna/Kustom among them - draw the delivery list themselves and take only a name and a price from each option, so our pickup point selector never appears and the customer cannot choose where to collect the parcel. A new setting on the Setup tab lists each pickup point as its own line in the delivery list instead, so choosing the line is choosing the point. Five points are listed for each shipping method, or as many as that method's own Pickup Point Limit allows, up to ten. The setting is off by default and nothing changes for anyone who leaves it off - on the standard WooCommerce checkout, and on Svea, choosing a pickup point already works better as it is
* Fix: Changes to the shop settings now show up at the checkout straight away. Saving a setting that affects delivery - the environment, the fallback weight, multi-warehouse, auto-split, or the fallback rules - left the checkout showing the delivery options it had already calculated, so the change looked as if it had not been saved until the cart changed or the customer's session expired
* Security: The two public web addresses for fetching shipping rates and pickup points are no longer registered. They could be called by anyone without signing in, and each call made several requests to the carrier and to our servers on the shop's behalf. They were never used by the checkout, which has its own path, so shops are unaffected

= 1.1.7 - 2026-09-14 =
* Fix: Adding your first warehouse location no longer stalls on a large catalogue. Marking a location as the default assigns it to every product that does not have one yet, and that was done one product at a time - fine for a few hundred, but on a catalogue of tens of thousands the request ran out of time partway through, leaving the location created and only some of the products assigned, while the screen reported a failure. The same applied to setting a location on a product category, which assigns it to everything in that category. Both are now written in batches, and a catalogue that took minutes is done in seconds
* Fix: The admin stays usable when our servers are slow to answer. The subscription notice at the top of the screen checked the subscription on every single page of wp-admin, and when the check could not be answered it waited the full timeout each time - so a brief outage on our side made every page in the admin, including pages that have nothing to do with shipping, take half a minute to load. The check now gives up quickly and remembers for a minute that it could not be answered. Shipping itself was never blocked by this, and still is not
* Fix: Fewer repeated calls to the carrier and to our servers while you work. Opening the settings screen asked for the printer list twice, and asked again every time a location was saved or deleted; a shipping calculation looked up the same warehouse twice. The answers are now reused within the page, so the list is fetched once and refreshed when it can actually have changed - after entering a new API key, or when you are about to pick a printer
* New: When a subscription payment fails, the notice now links straight to the invoice. Previously it sent you to the Subscription tab, which restates the problem without offering a way to settle it. The notice now names the outstanding amount and links to a payment page where the invoice can be paid with any card, whether or not it is the card we have on file. Where no such link is available the previous wording is kept
* Fix: Bulk fulfilment no longer offers orders that are missing a required pickup point. Selecting a batch of orders and fulfilling them would attempt orders whose shipping method requires a pickup point the customer never chose, and each of those failed at the carrier. They are now reported as needing attention instead of being attempted
* Fix: A zero entered in a shipping option form is kept. Fields such as a price or a threshold treated zero as "nothing entered", so a deliberate zero was dropped on save and the field came back empty
* Fix: Four labels in the admin were left in English on a translated shop

= 1.1.6 - 2026-09-10 =
* Fix: The plugin is translated again on WordPress 6.4 and older. The compiled translation files carried a zero where the header must point at the end of the translation table, and while WordPress 6.5 and newer read them anyway, every older version rejected the file outright - so a Norwegian or Swedish shop on 6.4 saw an entirely English admin no matter how complete the translation was. The tabs across the top of the settings screen were a second, separate case of the same symptom: their labels were resolved before the translations had loaded, so they stayed English even where everything else came out translated
* Fix: Deleting a warehouse location or a shipping option no longer reads every unfulfilled order in the shop. The check that stops you deleting configuration still in use loaded each order in turn, which is bearable on a small shop and fatal on a large one - on a shop with a hundred thousand orders in processing the request ran out of time or memory before it had decided anything, and pressing Delete was enough to trigger it whether or not the deletion would have been allowed. The same question is now answered with a single indexed query, and the protection itself is unchanged
* Fix: An interrupted plugin update no longer takes the whole site down. If an update failed partway - most often because the host would not let WordPress overwrite the files - the plugin was left with its main file in place and the classes it loads missing, which raised a fatal error on every request, storefront included. It now stops and says so in the admin instead, and the shop keeps serving
* Change: A failed subscription payment no longer switches shipping off on the spot. A declined card is retried for a few days before the subscription is cancelled, and shipping now keeps working for that window, with a notice in the admin asking for the payment method to be updated. Access stops only once the subscription is actually cancelled
* Change: A shipping option can now cover up to 50 postcode ranges instead of ten. A shop that delivers across a city needs one range per cluster of postcodes, and the old limit was reached long before the map was covered - Bergen alone takes 31 ranges once neighbouring codes are merged. Pricing rules, price ranges and weight ranges are still capped at ten, where the number reflects how many rules stay comprehensible rather than any technical limit

= 1.1.5 - 2026-09-07 =
* New: "Edit shipment" now says why a shipping method is missing from the list. A method the carrier refuses to price cannot be offered, and until now that was all the operator saw - a list quietly missing most of its entries, with nothing to say whether the parcel was the reason or something was broken. The panel now reports how many of the methods tried could be priced, and the carrier's own reason for each one that could not, folded away so the normal case stays quiet. Where nothing at all could be priced, the reason is stated outright instead of "No shipping methods available"
* Fix: The pickup point selector in block checkout is translated. "Select pickup point", "Loading pickup points...", "Opening hours:" and the carrier label were written into the markup in English, so they stayed English on a Norwegian or Swedish shop however complete the translation was
* Fix: The delivery time selector no longer loses its labels. The block checkout's strings were being sent to the browser from two places at once, and WordPress keeps only the last - the copy that happened to win carried none of the delivery-time labels, so whether the Porterbuddy selector had any text on it came down to load order
* Fix: The upgrade prompt no longer quotes a price the shop would never be charged. On reaching the location limit it advertised "Plus Plan", five locations and $59 a month with a $0.05 per-order fee - figures from an early draft, in a currency the plans are not sold in. The prompt is now built from the plans actually on offer, with their real names, limits and prices in kroner, and follows the order the plans are listed in rather than picking the cheapest, so a plan reserved for particular clients is not offered as the next step up

= 1.1.4 - 2026-09-04 =
* Fix: "Edit shipment" offers every carrier again on an order whose parcels have been edited. The parcel type saved with the order was being applied to each method being priced, so an order sent as a letter asked every carrier to quote a letter - and each one that does not carry letters refused and dropped out of the list, leaving only the letter products. The saved type is now kept only where the method being priced accepts it. Nothing on screen explained the short list, which is why it looked as though no shipping options existed at all
* Fix: Changing the shipping method no longer leaves the previous method's limits behind. A method with no parcel cap inherited the cap of the one before it, so the order went on claiming it allowed only one parcel and "Edit Parcels" kept refusing a second - while telling the operator the carrier was to blame. The same applied to the maximum weight and dimensions
* Fix: The parcel type can now be corrected wherever it decides the shipment. It is offered on the order panel for a method chosen in "Edit shipment", where the row used to disappear entirely; it is editable on the first parcel in "Edit Parcels", where it used to be locked to whatever the order was placed with; and it is no longer shown on the panel once the parcels carry their own, where changing it had no effect
* New: Customs data can be filled in for the whole catalogue at once, from the Customs tab. Export a spreadsheet of your products - name, category, price, weight, dimensions - alongside the customs columns, fill in commodity codes and countries of origin in Excel or Google Sheets, and upload it back. A cell left empty changes nothing, so a file can be worked through a few products at a time, and the upload is checked and summarised before anything is saved. Product weight and dimensions are only written when you ask for it with a checkbox
* New: The plugin is now fully translated into Norwegian and Swedish - every admin screen, order note, fulfilment error and the return instructions emailed to the customer. Roughly a thousand strings, where about a hundred were covered before and everything else stayed English however the shop was set up
* Fix: The shipping line on the order screen showed English labels on a translated shop. "Shipping from", "Weight", "Items", "Address" and "Pickup Point" were written back in English over the translated ones, so they stayed English no matter the language
* Fix: The customs bulk edit accepts "nej" in the exclude-from-declaration column. Its error message asked a Swedish shop for yes or no in Swedish, then refused the Swedish word for no
* Fix: Weight limits on a fallback rule are readable in Norwegian and Swedish. The line was assembled from separate English fragments, so it could not be translated at all
* Fix: No more "Undefined array key max_items" on the order editor. An order carrying a manual shipping line - flat rate, free shipping or local pickup - raised a PHP warning while drawing the Holio panel. The panel itself was correct and the button in question was already disabled, so nothing behaved wrongly; the warning was the whole symptom
* Change: Connection diagnostics no longer prints the hostname and IP addresses of checks that passed. A failed check still lists them, since those are the addresses you give your hosting provider to allow through

= 1.1.3 - 2026-08-28 =
* Fix: The pickup point selector stays readable where the checkout gives it a narrow column. Beside an embedded payment iframe the shipping methods can end up in a cell of about 150px, and the block's fixed indent left the dropdown some 80px wide - enough for two letters of the pickup point's name. The indent now gives way when there is no room for it, and is unchanged at every width that could afford it
* Fix: A pickup point the shop already knows about is filled back into the checkout. It was written into the form as the word "Array" instead, so the field stayed empty until JavaScript rebuilt it, and every checkout render raised a PHP notice
* Fix: Choosing a pickup point for one shipping method no longer discards the one chosen for another. Parcel lockers and service points share no location, so a customer who picked in the second method had their first choice replaced - and on returning to it were given whichever point happened to be nearest, without being told

= 1.1.2 - 2026-08-27 =
* Fix: The plugin is called Holio Shipping again on a Norwegian or Swedish shop. Its own name was being translated, which renamed it in the plugins list, the admin menu, the order screen, the product tab and the shipping method itself, while wordpress.org, the changelog and support all still called it Holio Shipping
* Fix: The estimated delivery line follows the language of the shop. Both halves of it were written in Norwegian in the code rather than translated, so a Swedish or an English shop was shown Norwegian. Norwegian shops see exactly what they saw before
* Improvement: Every price on the Subscription tab now says that it excludes VAT, the per-consignment fee included. That fee is the one figure a shop can reconcile against an invoice, and metered prices are billed exclusive of VAT
* Improvement: A parcel locker is treated as one whether its carrier calls it Pakkeboks or Pakkeautomat. PostNord's automats were being given the icon and the address panel of a staffed counter
* Improvement: The Usage Statistics card is hidden on a plan that charges nothing per consignment. Nothing is metered on such a plan, so the card could only ever have reported zero

= 1.1.1 - 2026-08-26 =
* Fix: The free shipping threshold, the cart total visibility rules and the cart conditions on a pricing rule are now read the way your shop shows prices, and coupons are deducted - between them, the same figures WooCommerce's own free shipping method measures. They were compared against the order value net of VAT and before any discount, so a shop showing prices with 25% MVA and a threshold of 1699 was in fact giving free shipping only from 2123.75. Please check your thresholds after updating: the amount you type now means the amount the customer sees
* New: The invoices issued for your subscription are listed on the Subscription tab, each with the period it pays for, its amount, its status and a link to the invoice itself. They are read from Stripe as they stand, so a payment or a refund shows without waiting for anything to catch up
* New: A product can be marked as not being goods in the parcel - gift wrapping, packaging, a handling fee - and is then left out of customs declarations entirely. Such a line began appearing on declarations as soon as a shop set a default commodity code. What was left out is recorded as a note on the order
* Improvement: Usage Statistics follows the Stripe billing period rather than the calendar month, and shows what Stripe has actually accrued. A shop invoiced on the 17th was reading a figure for the 1st to the 31st that never matched its invoice. The next billing date is taken from Stripe as well
* Improvement: Norwegian and Swedish are applied. Both translations were complete but had never been compiled, so every screen stayed in English whatever language the shop was set to
* Improvement: The Holio Shipping block sits at the top of the order sidebar the first time you open an order, instead of below the order notes. Move it elsewhere afterwards and it stays where you put it
* Improvement: HS code and country of origin are marked as required on a product, since a customs declaration cannot be built without them
* Fix: The estimated delivery date and the pickup point opening hours are shown on a block checkout. WooCommerce's Store API drops any rate detail whose name begins with an underscore and both were named that way, so the block checkout never received them however the shipping method was configured
* Fix: The estimated delivery line and the pickup point selector keep lines of their own in checkouts that lay the shipping row out horizontally, where they were squeezed in beside the method name. Their spacing can now be adjusted from a stylesheet

= 1.1.0 - 2026-08-24 =
* New: Weight and dimensions of a shipment can be corrected from the order screen. The button that added parcels is now "Edit Parcels" and the parcel the order arrived with can be edited too, so a figure taken at checkout can be put right before the label is bought. It is available on methods that carry a single parcel as well, where only the correction applies
* Fix: A shipping method excluded for certain products or shipping classes is now hidden only from the parcel that actually carries them. On a multi-warehouse order one excluded article removed the method from every warehouse, including those shipping nothing of the kind
* Fix: A corrected weight is the one quoted and charged. The order screen went on showing the weight from checkout, and the method selector priced against it, so a shipment could be bought at the wrong figure

= 1.0.9 - 2026-08-19 =
* New: A Customs tab holds a default commodity code and country of origin, used for any product that has none of its own. A shop with thousands of products no longer has to edit every one of them before a customs declaration can be built
* New: The same tab can be told to ship without a declaration when the data is still missing, instead of stopping at fulfilment and asking each time. Such shipments are recorded with a note on the order, and the declaration remains a legal requirement on the routes that need one
* New: A product can carry the weight of its own packaging, so a declaration can state a gross weight that includes the box and a net weight that does not. The weight on the Shipping tab is taken as the gross weight and this figure is deducted from it
* New: A product can carry a customs value, used where its order line has no price at all - a free sample, or an item bundled inside another product. A declaration is refused outright when any line is worth nothing, and until now the only answer was to declare a token amount nobody had chosen
* Fix: The declared customs value now includes tax. It was taken net of it whichever way a shop enters its prices, so every declaration understated the goods by the VAT
* Fix: Virtual products are left out of customs declarations. A parcel's declaration was able to list things that are not in the parcel
* Improvement: Plan cards fit as many across the page as there is room for, instead of always two

= 1.0.8 - 2026-08-17 =
* Fix: The pickup point a customer selects is saved the moment they choose it, instead of only when the order is placed. A checkout that completes the order through its own callback - an embedded one such as Svea Checkout with Vipps or card - never reaches that final step, so those orders were created without the pickup point the customer had chosen
* Fix: A chosen pickup point survives leaving the checkout and returning to it. The selection was held only in the open page: classic checkout then showed an empty selector, and block checkout went further and saved the first point in the list - often a parcel locker - in place of the one the customer had chosen
* Fix: The pickup point selector no longer disappears after the delivery address is changed in block checkout. It reappeared only if the customer switched shipping method and back again, while a point they could no longer see had already been saved for the order
* Fix: A pickup point the customer chose is no longer replaced by the first one in the list as the checkout refreshes. Tidying up between refreshes discarded the choice, and the replacement - often a parcel locker rather than the shop the customer picked - was saved as if they had selected it
* Fix: Block checkout no longer builds two pickup point selectors for the same shipping method, where the dropdown on screen could be a different one from the dropdown the order was read from
* Fix: Looking at another shipping method and coming back keeps the pickup point the customer had already chosen, instead of quietly reverting to whichever point is nearest. Where the method they return to genuinely cannot serve that place - a parcel locker product against a chosen shop, or another town - the nearest available point is offered and recorded for the order, so the selector and the order never disagree
* Improvement: Tested with WordPress 7.1

= 1.0.7 - 2026-08-14 =
* New: Picking lists. Each shipment can print a picking list for the warehouse it ships from, listing the articles that warehouse holds, the order number and the consignment number. Available as a printed slip or a PDF, and optionally printed automatically when the consignment is created
* New: "Fulfill with Holio" in the orders list bulk actions, for shipping a batch of orders without opening each one. Orders needing a decision are skipped with the reason given, and a run handles up to 20 orders at a time
* New: A return method can be chosen when fulfilling an order, with estimated costs per method, instead of relying on the automatic choice
* New: Multi-parcel orders split a heavy package into parcels of roughly equal weight, and each parcel keeps its own return QR code
* Improvement: Carrier logos ship with the plugin instead of being loaded from an external service, so no customer data reaches a third party and the admin screens load faster
* Improvement: Shipping rates are no longer served from cache after shipping options, locations or pricing rules change
* Fix: The pickup point chosen at checkout is saved on orders paid through embedded checkouts such as Svea Checkout (Vipps or card). The selection was submitted with the order but discarded, so those orders were fulfilled with no pickup point
* Fix: Choosing a shipping method for one warehouse no longer resets the method already chosen for another. On a multi-warehouse order the first choice fell back to another rate and its pickup point was lost, so the shop was charged for freight the customer had not chosen
* Fix: The plugin no longer changes an order's status back after the shop has set it. Orders that ship by other means are left alone entirely, and an order Holio cannot fulfil automatically now receives a note explaining why instead of being reverted - previously the plugin had to be deactivated to complete such an order
* Fix: Consignments are no longer refused with "Value must be greater than 0" when a customs declaration includes a free line, such as a gift or sample. The line is declared at the product's own price
* Fix: Proceeding without a customs declaration no longer applies to that order permanently - the choice is cleared when the order is reprocessed
* Fix: Order and product screens no longer fail with a fatal error alongside plugins that name shipping packages in their own way
* Fix: The fallback shipping rate is offered only when no other rate is available, instead of appearing next to the shop's own methods
* Fix: Shipping rates reduced to nothing by a free-shipping threshold are shown as free rather than as a zero price
* Fix: The pickup point selector is no longer rendered on the cart page, where it caused JavaScript errors
* Fix: Checkout analytics count one checkout per cart instead of one per session

= 1.0.6 - 2026-07-30 =
* Improvement: "Add Another Parcels" now explains why several parcels are unavailable - whether the carrier allows only one parcel for the chosen method, or the shipping option is configured that way (with a link to the setting)
* Improvement: Parcels that arrived with the order are marked in the parcels dialog, so they are not mistaken for parcels added by hand - a heavy order split into several parcels at checkout shows all of them as such
* Improvement: Saving an order makes fewer requests to the Holio service - the warehouse list is fetched once per request instead of once per shipping item
* Fix: Parcels composed with "Add Another Parcels" are no longer discarded when the order is saved. They are kept until the order's products actually change, and only then rebuilt from the current contents
* Fix: A shipping rate is no longer offered when the carrier priced only part of a multi-parcel shipment. Such a quote covered a single parcel and was a fraction of the real freight cost - the shop would have paid the difference. Applies to checkout, the shipment method selector and the return method selector
* Fix: The estimated cost shown after composing parcels now includes the services selected at checkout, such as the pickup-point service, so it no longer disagrees with the estimate shown elsewhere for the same shipment
* Fix: Changing the shipping method no longer clears the pickup point's customer number, and the "pickup point possible" flag is stored in the same format the rest of the plugin reads - an optional pickup point could become impossible to select after saving
* Fix: Returns for multi-parcel shipments no longer count the duplicate parcels some carriers report, and every return parcel keeps its own QR code instead of losing it
* Fix: The pickup point the customer selected is now shown on the order confirmation and order details pages, for both classic and block checkout. Orders shipped from several warehouses list every pickup point
* Fix: Order screens no longer fail with a fatal error when the plugin is active but no API key has been configured yet

= 1.0.5 - 2026-07-29 =
* Feature: Added Connection Diagnostics to the Setup tab - checks outbound HTTPS access to the Profrakt API and reports blocked hosts, proxies and plugins filtering requests
* Feature: Connection Diagnostics lists every IP address a host resolves to, and blocked hosts are reported with all their addresses plus a note that every one of them must be allowed - hosts behind Cloud Run answer on several addresses, so allowing only one leaves the block in place
* Feature: Subscription handling for the Holio service, with plan details and usage on the new Subscription tab
* Improvement: "Add Another Parcels" in the order screen is now always visible. It used to appear only after using "Edit shipment" once, because the parcel limits were read from saved order data instead of the shipping method configuration. When the method cannot carry several parcels the button is disabled and explains why
* Fix: Shipping rates are no longer hidden when the Holio service cannot be reached - a network timeout is no longer treated as an inactive subscription
* Fix: Checkout no longer fails with a fatal error when the plugin is active but the API key has not been configured yet
* Fix: API key validation now reports the actual connection error for each environment instead of only the last one

= 1.0.4 - 2026-07-16 =
* Improvement: API key validation now reports the real reason when the Profrakt API cannot be reached (connection, SSL, or firewall issues) instead of a generic "Invalid API key" message
* Improvement: Validation errors are logged for easier troubleshooting

= 1.0.3 - 2026-06-24 =
* Fix: Removed subscription-related code for WordPress.org version
* Fix: Removed Holio_Subscription_Repository dependency from admin settings
* Code Quality: Cleaned up unused AJAX handlers
* Compatibility: WordPress.org directory optimized version

= 1.0.2 - 2026-06-22 =
* Security: Enhanced POST data sanitization - added sanitize_textarea_field() before all json_decode() calls
* Security: Implemented recursive array sanitization for nested data structures
* Security: Fixed boolean sanitization with filter_var(FILTER_VALIDATE_BOOLEAN)
* Security: All output properly escaped with absint()/esc_html()
* Feature: Added max rules limit (10 rules per section) to prevent performance issues
* Feature: Frontend validation blocks adding rules beyond limit
* Feature: Dynamic UI shows "(max 10 rules)" in section headers
* Code Quality: All WordPress.org Plugin Check issues resolved (0 errors, 0 warnings)

= 1.0.0 - 2026-06-04 =
* Initial public release
* Multi-carrier shipping integration (Bring, PostNord, HeltHjem, UPS, DHL, Porterbuddy, Instabox)
* Real-time shipping rate calculation from Profrakt API
* Pickup point selection at checkout (Classic and Block checkout)
* Multi-warehouse operations with cart splitting
* Automatic consignment creation
* Label printing (PDF download and direct network printing)
* Return shipment creation with QR codes
* Flexible pricing rules (fixed price, markup, percentage, free shipping threshold)
* Weight, dimension, country, and ZIP code filtering
* WooCommerce Blocks compatible
* REST API support for headless implementations
* Automatic package splitting for heavy orders
* NVIT customs declaration support
* Fallback rules for external order systems
