Changelog

Everything we changed, in public.

Straight from the readme that ships with the plugin, so this page cannot drift from what you actually installed. Every entry below went out to every site running Milo.

Current version
1.8.36
Last released
2026-10-05 3:46pm
Releases
21
Changes shipped
113

1.8.36

5 changes

  • Fixed

    in standalone mode, a subscription with a free trial was recorded as active. The checkout wrote “active” over the trial status Stripe sent in the same second, and the trial’s zero invoice did the same.

  • Fixed

    in standalone mode, newer Stripe API versions were not read: periods now come from the subscription items and invoices from their new subscription details when the old fields are missing.

  • Fixed

    in standalone mode, plan prices in currencies without decimals, such as JPY or KRW, were divided by 100 on screen and multiplied by 100 when saved from the plan form.

  • Fixed

    in standalone mode, a customer who subscribed again had the download drip start over. Files now unlock from their first subscription.

  • Fixed

    the “Open customer portal” button on a standalone subscription opened the administrator’s portal instead of the subscriber’s.

1.8.35

7 changes

  • Fixed

    the Apple Pay, Google Pay and WooPay buttons WooPayments or the Stripe plugin draw on product pages and at checkout were offered on subscriptions, where their gateway is refused without Any Gateway. The wallet sheet opened and the order then failed. They are now hidden on subscription products and carts unless Any Gateway is active.

  • Fixed

    a subscription could be paid with a method that can never be charged again, such as Afterpay, Affirm or Alipay through the Stripe plugin. The sign-up went through and the first renewal had nothing to charge. Those methods are now hidden from subscription carts, unless the store invoices every renewal.

  • Fixed

    an import from WooCommerce Subscriptions could hang forever on hosts that do not run background tasks, common on staging sites, and trying again answered “A migration is already in progress”. The Import screen and the setup wizard now run the import themselves when it stops moving, and starting again picks up the run in progress.

  • Fixed

    after importing from WooCommerce Subscriptions, the dashboard and Analytics counted each subscription twice, the original and Milo’s copy, doubling active subscriptions and recurring revenue. They now count the subscriptions Milo manages, like the Subscriptions list. Analytics also read renewal revenue as zero on stores that keep orders as posts.

  • Fixed

    variable subscription products skipped WooCommerce’s price filters, so multi-currency plugins could not convert their price and the tax suffix was missing.

  • Fixed

    links in notes imported from WooCommerce Subscriptions led nowhere, because their ampersands stayed encoded.

  • Added

    card update links. With the new setting on, the payment update email carries a personal link that opens the card form of that one subscription without signing in. It expires after three days, stops working once the card is updated or the billing email changes, and can be created or revoked from the subscription screen. Available for Milo Payments gateways from Milo Payments 1.0.21.

1.8.34

6 changes

  • Fixed

    a store coming from WooCommerce Subscriptions could hit a fatal error on My Account or when an email went out, because a customised WooCommerce Subscriptions template with the same file name kept loading. Milo now reads theme overrides from yourtheme/milosubscriptions/, ignores those leftovers and names them in an admin notice.

  • Fixed

    renewals through a gateway that keeps the recurring agreement on its own side, such as Worldline Online Checkout, now call the gateway’s renewal handler instead of going straight to an invoice. A gateway that stores cards but charges nothing without WooCommerce Subscriptions, such as the official PayPal plugin, is now invoiced with an explanation instead of leaving the renewal pending in silence.

  • Added

    a Charge now action on the subscription screen, which charges the next renewal to the saved payment method through the same path as a scheduled renewal. “Create renewal order” is renamed “Create unpaid renewal order”, no longer creates a second unpaid order for the same cycle, and marking a renewal order paid by hand now says no payment was taken.

  • Fixed

    the related orders list on a subscription showed every total in the store currency, whatever currency the order was paid in.

  • Fixed

    a subscription order left unpaid for a day is now cancelled, and its pending subscription with it. WooCommerce only cancels unpaid orders when stock management is on, so on a digital store they piled up forever, one per bot attempt.

  • Fixed

    cancelling a subscription that was never paid no longer emails the shop and the customer about a cancellation.

1.8.33

10 changes

  • Fixed

    the standalone reconciler no longer cancels subscriptions that belong to another Stripe account, or to the other mode of the same account.

  • Fixed

    a plan’s cached Stripe Product and Price are only reused on the account and mode that created them, so a test price can no longer bill in live.

  • Fixed

    a standalone customer with two checkout tabs open could pay for two subscriptions. A customer now has one open checkout at a time, and a paid session is never replaced.

  • Fixed

    a standalone subscriber could buy a second subscription that replaced the first while Stripe kept billing both. A second purchase is now refused.

  • Fixed

    two stores sharing a Stripe account could create or cancel each other’s subscriptions. Events now name their store, and a store only applies its own.

  • Fixed

    a paid standalone invoice recorded the period that had just ended instead of the one it paid for, so a renewed subscriber looked expired.

  • Fixed

    on a store that never ran WooCommerce, administrators could not see archived plans or use the standalone subscription endpoints.

  • Fixed

    a standalone sign-up fee was sent to Stripe with an empty currency when the currency setting had never been filled in.

  • Fixed

    moving a subscription’s next payment date to today or earlier now runs the renewal on the next queue pass instead of leaving the old job on the original date.

  • Security

    the licence update check for add-ons sent the licence key in the URL, where servers log it. It now travels in the request body.

1.8.32

5 changes

  • Added

    a returning subscriber who checks out signed out, with an email that already has an account, is no longer refused with “please log in”. Subscription carts force registration, so their first purchase created an account they were never told about, with a password they never set. Milo now emails them a one-time sign-in link and says so at the checkout; the link brings them back, signed in, with their cart. On by default, can be switched off under Checkout & Payments.

  • Fixed

    “View version details” on a Milo add-on update could open on “Plugin not found” again, with no way to read the release notes, whenever an older copy of the licence client elsewhere on the site loaded before the fixed one. The core now loads the client itself, ahead of every add-on, and answers the details request for any Milo plugin nothing else answered for.

  • Fixed

    wp milo subscription renew reported success on staging sites where the renewal guard had blocked it, and on subscriptions the renewal path had skipped. It now refuses on staging, saying why, and warns when a run created no order and moved nothing.

  • Fixed

    on a site without WooCommerce, the notice now says the store is running in standalone mode, that plans take the place of products, links to Plans, and offers to record the choice, instead of pointing at a wizard. The wizard itself no longer offers WooCommerce mode when WooCommerce is not active.

  • Added

    a Downloads block, the twin of the [milo_subscriptions_downloads] shortcode. Four of the five standalone shortcodes had a block in the Milo category; this was the one missing, with nothing saying why.

1.8.31

9 changes

  • Fixed

    cancelling a subscription twice (double-click, refresh or prefetch of the My Account link) no longer turns a pending cancellation into an immediate one that revokes prepaid access.

  • Fixed

    running alongside WooCommerce Subscriptions doubled the subscription count. Both plugins use the same product type, so an order placed through WooCommerce Subscriptions was indistinguishable from one of ours, and each of them produced a second subscription here the first time it changed status. Milo now asks WooCommerce Subscriptions whether an order is already its own, and leaves it alone if so. Reported by a merchant evaluating the two side by side.

  • Fixed

    renewal orders were created in the store’s currency instead of the subscription’s. On a multi-currency store, a CAD subscription produced a renewal order denominated in USD: the right amount in the wrong currency, which changes what the customer is charged.

  • Fixed

    manually setting a renewal order back to a paid status moved the subscription’s next payment date each time, with no charge behind it. One status change on a weekly subscription was enough to lose five days of billing. A renewal order now advances the schedule once, the first time it is paid.

  • Fixed

    the schedule advanced from the moment a renewal payment completed rather than from the date it was due, so every cycle inherited the last one’s lateness and the billing day slowly walked. A renewal that ran six hours late used to push the next one six hours later, permanently. Reported by a merchant.

  • Fixed

    every amount and date in the admin now follows the site’s language instead of the browser’s. On a French store opened from an English browser, prices read “€9.00” rather than “9,00 €”, and dates came out in English. Sixteen places were affected.

  • Fixed

    billing periods and subscription statuses were shown as stored, in English, inside otherwise translated screens: “19,00 € / month”, and status badges reading “trialing” or “Pending-Cancel”.

  • Fixed

    258 strings were missing from the French translation, which had fallen behind the code: the admin screens, the settings and their help text, and every lifecycle email, its name, subject and default body.

  • Fixed

    one French string was present but empty, which rendered as nothing rather than falling back to English.

1.8.30

9 changes

  • Fixed

    Health Check no longer touches subscriptions that belong to another plugin. After an import, the WooCommerce Subscriptions originals are still there, and the scan flagged every one of them as missing a next payment date. Fixing one wrote a Milo renewal date onto a record Milo does not manage, and the subscription then appeared to vanish, because it had never been in the Subscriptions list to begin with. Reported by a merchant.

  • Fixed

    the subscription details screen shows the tax included in the recurring total. The renewal order beside it itemised the same money, so a total silently included something it did not name. Reported by a merchant.

  • Fixed

    Health Check and Import are refused in Standalone mode instead of reporting a clean bill of health for subscriptions they never read. Standalone subscriptions live in their own table, which the scan does not look at, so an empty result meant “not checked”, not “nothing wrong”.

  • Fixed

    a checkout that offers no way to pay now says why, to store managers only. When a cart holds a subscription and no Milo Payments gateway is enabled, every other gateway is removed and the payment section is left empty with no explanation. A merchant read that as their card gateway failing to load.

  • Fixed

    a product created from Milo stayed a plain product instead of becoming a subscription. The type was set after the product had been saved, so WooCommerce went on serving the type it had cached during that save; the product only sold once, at the price shown, and never renewed. The same applies to products converted by the importers. Reported by a merchant.

  • Fixed

    the Short description field said its text appears at checkout. It appears on the product page.

  • Fixed

    subscription amounts are shown in the currency of the subscription rather than the store’s. On a multi-currency store every screen but Products labelled a CAD subscription as USD, which is worse than showing no symbol at all. Reported by a merchant running Currency per Product.

  • Fixed

    the import preview in the setup wizard printed a euro sign whatever currency the store used.

  • Fixed

    notes imported from WooCommerce Subscriptions showed their HTML in the activity log instead of their text. Links in them are now readable and clickable.

1.8.29

13 changes

  • Fixed

    a subscription created by hand from the admin priced its line the same wrong way on a tax-inclusive store, so its renewals were taxed twice too.

  • Fixed

    on a store that enters prices inclusive of tax and has “update prices on renewal” switched on, renewals were still taxed twice, and each one wrote the taxed figure back onto the subscription. 1.8.28 fixed this where subscriptions are created; this fixes the other path, where renewals re-price from the product. A subscription already inflated this way repairs itself at its next renewal.

  • Fixed

    the setup wizard could not create a first plan in Standalone mode. It asked WooCommerce to create a product, which does not exist on a standalone store, so the step answered “No route was found” and offered no way past it once the form was filled in. Reported in a public review.

  • Fixed

    an optional wizard step can always be skipped, even after a failed attempt. Filling the form used to replace the skip button with the one that had just failed.

  • Changed

    plans can be created before Stripe is connected. Building a catalogue needs no payment account; only selling does. The screen now says which of the two is missing, since an account that is linked but not yet cleared by Stripe to take charges was reported as no account at all.

  • Fixed

    the WooCommerce email settings no longer show a red failure on a store without WooCommerce. They now explain that they need it, which is what the server was saying all along.

  • Fixed

    a Standalone setup no longer asks for WooCommerce-only routes it cannot reach, which left 404s in the browser console throughout a first run.

  • Fixed

    the Plans screen carried twice the page padding of every other screen, because it added its own on top of the one the admin shell already applies.

  • Changed

    every screen now says the same thing the same way when there is nothing to show, and says which kind of nothing it is. A clean Health Check scan reads as good news rather than “No results”; an empty subscriptions list distinguishes a store with no subscriptions from a filter that matched none, and offers to clear the filters; the Products and Health Check screens share that wording and shape. A store that has never scanned is invited to run one.

  • Fixed

    the admin header no longer runs its title under the action buttons on a narrow window. The buttons move to their own row instead, and the title stays whole.

  • Fixed

    the Products screen sat further from its header than every other screen, for the same reason the Plans screen did: it added its own page padding on top of the one the admin shell already applies.

  • Fixed

    the plan editor stretched to the full width of the screen, because it declared no size and fell back to the fill default. Its fields now sit in a readable column.

  • Fixed

    the setup wizard called things by their name in Standalone mode. It offered to create a “product” with a “product name”, pointed at the Products screen, and finished by sending you to the WooCommerce product editor, none of which exists on a standalone store.

1.8.28

4 changes

  • Fixed

    creating subscriptions no longer commits a database transaction opened by someone else. The plugin opened its own, which MySQL treats as committing the current one, so a store importing orders inside a transaction lost the ability to roll it back.

  • Fixed

    on a store that enters prices inclusive of tax, renewals were charged the tax a second time. A 25,00 subscription renewed at 30,75 with VAT at 23%. New subscriptions now record the same net amount and tax as the order that created them; subscriptions created before this update keep the amount they were saved with.

  • Fixed

    a variable subscription now answers to is_type( 'variable' ) as well as to its own type, so themes and plugins that gate their work on that check treat it as the variable product it is. Attribute swatches, for one, left the variation dropdown untouched on subscription products.

  • Fixed

    changing plan left the customer with two subscriptions. The switch order was treated as an ordinary purchase before the switch was applied, so alongside the subscription that moved to the new plan a second one was created and renewed on its own date.

1.8.27

2 changes

  • Fixed

    a customer could put a spreadsheet formula in their own billing details and have it sit unescaped in an exported CSV, ready to run when the merchant opened the file. Reported by Hikmet Kovsarov.

  • Fixed

    on stores running WooPayments, subscription products lost their type when saved in WooCommerce, could not be added to the cart, and their admin screens redirected away. WooPayments disables subscriptions it did not create; Milo now takes itself back out of its reach.

1.8.26

3 changes

  • Added

    add-ons can now adjust the cart’s recurring total, so a discount that repeats is shown as what will actually renew.

  • Fixed

    on a store using WooPayments with its built-in subscriptions switched on, Milo paused itself and reported that WooCommerce Subscriptions was active, a plugin those merchants do not have. The notice now names WooPayments and explains how to hand subscriptions over to Milo.

  • Fixed

    asking whether something is a subscription product could take a page down when a theme had left a string where the product should be; it now simply answers no.

1.8.25

1 change

  • Fixed

    on a site without WooCommerce, the settings and dashboard screens answered “No route was found matching the URL”, which left onboarding stuck and standalone mode impossible to switch on.

1.8.24

3 changes

  • Added

    two new add-ons, WPForms and Contact Form 7, turn any form into a subscription sign-up ($29/year each, in the bundle).

  • Added

    the Add-ons marketplace gains a live search, category chips, an Active filter, New badges, and a reassurance strip; forty-six cards is past the point where scanning beats typing.

  • Added

    the Import page and setup wizard now surface the WP-CLI migration commands, the faster route for large stores.

1.8.23

4 changes

  • Fixed

    two links in this readme pointed at pages that no longer exist (the add-ons bundle and Any Gateway).

  • Fixed

    the dashboard’s “This week” chart drew a decorative shape; it now draws the store’s real per-day sign-ups.

  • Fixed

    a product on sale showed its price in the Products list as a run-on sentence; it now shows the struck-through original beside the sale price.

  • Changed

    updated links to documentation and support pages.

1.8.22

2 changes

  • Fixed

    Virtual and Downloadable are no longer offered on a variable subscription’s parent, where a tick was dropped on save. They belong to each variation.

  • Fixed

    a lifetime plan no longer honours a free trial, which credited its full price at checkout with nothing ever scheduled to collect it; a lifetime price now also names its sign-up fee.

1.8.21

1 change

  • Changed

    the opt-in usage report now includes which payment gateways a store has connected, alongside the ones already billing subscriptions. Gateway slugs only, as before: no account identifiers, no keys, nothing about individual customers.

1.8.20

6 changes

  • Fixed

    paying the renewal order of an expired subscription flipped it back to active with its end date in the past and nothing scheduled to bill, because two handlers decided what a paid renewal was worth and the one without a rule always won. The considered rule now stands alone: a payment recovers on-hold, cancelled and pending-cancel subscriptions, expired stays expired, and the merchant filter that narrows the list finally takes effect.

  • Added

    the pay page now states what paying a renewal order will do before taking the money. A cancelled or on-hold subscription’s invoice says it will reactivate and names the next renewal date; a fixed-length subscription near its end says it will not be billed again; an expired subscription’s invoice is refused with the reason and a link to subscribe again, since that payment would buy nothing.

  • Fixed

    a customer who fixed their payment method after a renewal failed kept being declined. The renewal order carries a copy of the payment details taken when it was created, and every later attempt charged that copy, so the subscription showed a good card while each retry used the one that had already failed. With the retry add-on’s default schedule that is up to sixteen days of declines and dunning emails ending in a cancellation, for someone who did exactly what they were asked. A renewal order is now brought up to date with the subscription’s current payment method before each attempt, and the gateway it is addressed to follows the subscription too.

  • Added

    a subscription now records what became of its emails, in its own notes: the ones handed to the mail server, and the ones the mail server refused. Answering “did this customer get told?” no longer needs a third-party email logger, and an email refused by the mail server is named as the site-wide problem it is rather than looking like a subscription fault. Admin copies are left out of the successful ones, so the record stays readable.

  • Fixed

    a subscription with no customer email address dropped every one of its emails in silence. Nothing was recorded on the subscription or anywhere else, while WooCommerce’s own order emails kept arriving because those are addressed from the order rather than the subscription, so there was no way to tell an email that was never attempted from one that was attempted and lost in delivery. The subscription now says so in its notes, naming the email and how to fix it.

  • Fixed

    on a site detected as staging, subscription emails were held back silently. WooCommerce > Settings > Emails kept showing every one of them as enabled, because the block is applied on top of those settings rather than through them, and the staging notice listed renewal payments and scheduled events but never mentioned emails. A store whose payments were working read that notice as irrelevant and had nowhere left to look. The email settings screen now says so, next to the toggles it contradicts, and the notice names emails among what staging holds back.

1.8.19

9 changes

  • Fixed

    the Subscriptions list showed the gateway name for a subscription that had no payment details stored, so one that could not renew read exactly like one that could. The Payment column now marks a subscription set to renew automatically with nothing on file, using the same rule the Health Check uses so the two screens cannot disagree.

  • Added

    import subscriptions from Easy Digital Downloads Recurring Payments. Statuses, billing periods (including EDD’s quarterly and semi-yearly), trials, sign-up fees, fixed-length plans and downloadable files are carried over, each download becomes a draft subscription product, and variable price tiers get one product each because the tiers can bill on different schedules and because EDD gates files per tier. Imported subscriptions arrive on manual renewal, so each renewal is invoiced until the customer re-authorizes payment: EDD keeps the payment agreement in its own gateway profile, which Milo cannot charge. They are added to the re-authorization audience so that request can be sent in bulk.

  • Fixed

    importing from Easy Digital Downloads with the plugin deactivated attached every subscription to nobody. Customer records were read through EDD’s API, which does not exist once EDD is switched off, so a whole store arrived as guest subscriptions with no accounts, silently, and only visible when subscribers could not find their subscription in My Account. Customers are now read from EDD’s table like everything else the import reads.

  • Fixed

    an Easy Digital Downloads subscription whose date columns held MySQL’s zero date was imported with a next payment date in the year -1, which made it permanently overdue and invoiced the customer the moment the store migrated. Those columns are declared NOT NULL with no default, so rows written without a value carry a zero date rather than nothing at all.

  • Fixed

    the import preview counted the subscriptions it had sampled rather than all of them, so a store with more subscriptions than the sample limit was shown the size of the sample as its total.

  • Fixed

    a subscription bought without a WordPress account never had its download access changed. Cancelling one left the customer able to keep downloading its files indefinitely, and reactivating one never gave the access back. Access now follows the subscription’s status whether or not there is an account behind it.

  • Fixed

    the Health Check reported every subscription renewing through Milo Payments as set to renew automatically with nothing on file to charge. Its lists of what counts as a stored payment method knew the third-party gateways but not Milo Payments’ own, so the plugin’s main payment path was flagged as broken while it renewed perfectly well. Stripe, Mollie, Square and PayPal details saved by Milo Payments now count, and a half-stored method (a card with no customer) is still flagged, because that one genuinely cannot be charged.

  • Fixed

    a subscription whose end date had passed was invoiced again instead of expiring. The expiry event is only ever scheduled for a future date, so a subscription imported with a term already behind it had no expiry scheduled at all, while an overdue payment did get a catch-up renewal: a fixed-length plan whose term ended months ago billed the customer for a cycle they never bought.

  • Fixed

    a subscription could not serve the files it holds. WooCommerce only allows a download when the order behind it is completed or processing, and a subscription is neither, so a file attached to the subscription itself was refused with “Invalid order”. An active subscription now permits its own downloads; nothing else is widened, and the drip schedule still applies.

1.8.18

3 changes

  • Fixed

    a subscription could inherit a saved card without the customer account it was saved against, which cannot be charged off-session. The renewal tried anyway, so the customer got a declined-payment email for a card that was never chargeable and the merchant saw a payment problem. Payment details now travel complete or not at all, and a renewal will not attempt a charge against details it can already tell are incomplete: it sends an invoice and says why on the subscription.

  • Added

    milo_subscriptions_gateway_meta_dependencies and milo_subscriptions_incomplete_gateway_meta filters, so a gateway can declare which of its keys belong together and answer for itself whether stored details are usable.

  • Added

    Health Check now flags a subscription that is set to renew automatically with nothing stored to charge. Such a subscription passed every existing check, so the first visible sign was a renewal that never happened. Free plans, manual-renewal subscriptions and lifetime plans are deliberately left alone, and the fix offered is the re-authorization email.

1.8.17

3 changes

  • Fixed

    a subscription was listed under its billing address rather than the customer account that owns it. On an order paid through a finance address, the admin showed “Accounts Payable / [email protected]” for a subscription that actually belongs to the customer’s account, which is what decides who sees it in My Account. Guest checkouts still show the billing name, and the invoice details remain on the subscription.

  • Fixed

    paying a renewal order after the subscription had been cancelled took the money and left it cancelled. The retries give up and cancel, the customer pays the link still sitting in a dunning email, and Milo recorded the payment and scheduled the next cycle while access stayed revoked. Paying an outstanding renewal now reactivates the subscription, and a cancelled or expired subscription can be reactivated from the admin instead of only over WP-CLI. Reported from production, where it cost a subscriber twelve days of access.

  • Added

    milo_subscriptions_valid_status_transitions filter, so a store can forbid a status change it does not want or allow one this plugin does not.

1.8.16

8 changes

  • Added

    a variation of a variable subscription can now have its own billing period, interval, expiry, sign-up fee and free trial, so one product can offer a monthly option beside a yearly one. Leave a field empty and it keeps using the parent’s value.

  • Fixed

    a variation ignored the parent’s “Expire after” setting and never expired. Every other setting inherited correctly; this one read 0, which does not mean “unset” but “never expires”.

  • Fixed

    a variable subscription whose variations bill on different schedules advertised a price nobody could buy. The range took the cheapest variation’s period and applied it to the whole range, so $9 monthly beside $90 yearly read as “$9 – $90 / month”. Schedules are now listed separately.

  • Fixed

    choosing a variation showed a bare price with no billing period beside it.

  • Fixed

    switching to a variation that uses the parent’s schedule left the subscription on its old billing period. A customer moving from a yearly option to a monthly one stayed billed yearly.

  • Fixed

    switching did not move the expiry date onto the new plan, so an upgrade kept the old plan’s end date and a downgrade left access nobody was charging for.

  • Fixed

    migrating from WP Swings or YITH dropped a variation’s expiry, sign-up fee or free trial when the variation kept its parent’s billing interval. The affected variations arrived inheriting the parent instead.

  • Fixed

    the product editor stored whatever billing period it was sent. The fields are dropdowns so this was …

Want it before everyone else?

Every release goes out on WordPress.org first. Updates arrive in your plugins screen like any other, with no licence key for the free core.