Skip to content

Changelog

What changed in each release of Review Requests, in terms of what it means for you rather than which files moved.

1.7.1 — 3 October 2026

Corrections only. No setting was added, nothing in the database changed, and the API answers exactly what it did. Coming from 1.1.0? Read 1.7.0 as well: everything in it comes with this one.

Status off now means nothing is sent, from every door. Until now only the hourly schedule and the command line's pass respected it, so Run a pass now, Start an initial collection and the command line's backfill still emailed the customers of a store you had switched off, or that an update had switched off for you. All of them now hold. The Before anything is sent checklist gains a first line for it, so it is nine lines now: a store that is switched off says so there, instead of going red on the schedule and blaming a crontab that is fine. Every update still switches the module off; switch Status on and save.

A second store follows the default store until you configure it. A store whose settings tab you never saved used to run on the shipped defaults, with no status chosen, so it quietly asked nobody. It now runs on the default store's settings, the way OpenCart itself reads a store's settings, and its tab shows them. Saving its tab gives it answers of its own, which it keeps from then on. Status is still per store and still comes back off after an update, so a store following the default one sends nothing until you switch it on. See limits.

Names with an ampersand read as typed. A product called Salt & Pepper arrived as Salt & Pepper in the request email, on the review page and on the Requests tab, and so could the store's name, and a shopper's own text when the form was shown again. Wording you write on the settings screen no longer gains another & each time you save it, and switching language on the wording panel no longer drops you on the login page.

Writing a review through the link.

  • No duplicate review when something after the save fails. If the review was written and a later step failed, such as OpenCart's own new-review alert email, the shopper used to see an empty form and could submit it again. The review now counts as written. If the save itself fails, the form comes back with what they typed and a message asking them to try again.
  • A link past its expiry no longer takes a review from a page that was opened before it expired. Opening such a link already refused.

On the admin screens.

  • Acknowledge and Resend on the Requests tab bring you back to the same page, store and filters rather than the first page of the default store.
  • Customers > Personal Data and Remove everything held about a person now say so when the erasure gets no answer, from a timeout or an expired login, instead of leaving the button greyed out with nothing to say whether it ran.

The API refuses an API user whose key was emptied by hand. OpenCart's own form will not save an empty key, but a row edited directly in the database let a caller in with no key at all. It no longer does.

On updating. Nothing to do beyond switching Status back on, as after every update. A second store whose tab you never saved starts following the default store's settings, as described above.

1.7.0 — 30 September 2026

Coming from 1.1.0? That is the version the marketplace offered until this one, so this release also brings you everything from 1.2.0 to 1.6.0 below. Two of those matter most: on OpenCart 4.1.0.4, 1.1.0 never sends a request at all, because that release's own scheduler is broken, and 1.4.0 is the version that stopped needing it; and 1.6.0 can pay Loyalty points for an approved review.

Leave products out of requests. Two new lists under When a customer is asked on the Settings tab, Never ask about these products and Never ask about these categories, for what nobody reviews: gift cards, samples, services. A category takes its subcategories with it.

  • Checked when a request or reminder is sent, so they apply to orders already waiting. An order with nothing else on it is not asked at all.
  • The product is still recorded on the request, marked as left out of requests on the Requests tab, on the review page and through the API.
  • Nothing already reviewed changes, and neither the badge nor Loyalty points are affected.

See leave products out of requests.

Sending hours. Send from (hour) and Send until (hour), under How much is sent, keep requests, reminders and an initial collection's emails to the hours you choose. 22 to 6 wraps past midnight. Outside the hours, passes still run and find orders; what waited goes out once the hours open. The hours are in your installation's one timezone. See set sending hours.

Reply to a review. OpenCart's own review form on Catalog → Reviews has a Reply box under the review's text, on any review, and the reply prints under that review on the product page, headed Response from the store: a tenth wording field, Reply heading, rewords it per language. Nobody is emailed when you reply, and turning the badge off does not hide replies. A theme that does not print the review's text the way core does gets no reply on the page; the checklist says so. See reply to a review.

Fixed: a review written through a request link now earns Loyalty points. Until now only a review typed into the product page's own form by a logged-in customer earned them, because a review collected through a request link is stored against no customer. It now earns for the customer account that placed the order. A guest order still earns nothing.

On updating. Every new setting starts at what the extension did before it existed: nothing left out and every hour open, so your store behaves exactly as it did until you change something. Replies are kept in a table of this extension's own, which, like all of them, is never dropped, so an update keeps them, and so does uninstalling: they print again if you install again.

1.6.0 — 26 September 2026

A review can now earn its author Loyalty points. Set Points for an approved review on the settings tab, and a customer whose review you approve on Catalog > Reviews is paid that many points through the Loyalty extension, straight onto their Reward Points balance.

  • Paid when you approve a review, never when it is submitted, so a spam review you never approve earns nothing.
  • Paid once per review. Approving it again, or saving it again after an edit, pays nothing more.
  • Off until you set it. The setting starts at 0, including on upgrade.
  • Loyalty is not required. Without it installed the setting does nothing, and approving a review works exactly as it did before. If Loyalty refuses or fails, the review is still approved and the reason goes to this extension's log.

See settings.

1.5.0 — 21 September 2026

The settings screen now says what two OpenCart releases have taken away. Neither is ours to repair and neither is claimed any more:

  • 4.0.2.3: OpenCart's own review form loads a file that release does not have, so no review can be submitted at all. Everything here still works: the requests send, the link opens, the badge is still right about the reviews you already have. What does not work is the one thing the email asks a customer to do, which is why the screen says so and why you may want to pause the requests while you are on it. See limits.
  • 4.1.0.1: OpenCart's guest checkout answers a PHP warning ahead of its reply, so a guest never places the order a request would follow. See limits.

4.0.2.2 is now a tested release. The list runs 4.0.2.0 through 4.1.0.4 with those two gaps.

1.4.0 — 21 September 2026

  • Review Requests now runs on OpenCart 4.1.0.4, the hourly pass included. That release broke OpenCart's own scheduler: every scheduled task on the store stops inside OpenCart before an extension is reached, ours and everybody else's. That is why it was not a version to install on. It is now, because Review Requests no longer needs that scheduler: one line in your server's own crontab, php extension/review_requests/review_requests.php cron, runs the hourly pass exactly as the store's cron would. Same discovery, same emails, same Recent passes rows, same log lines. See running the hourly pass yourself.
  • On such a store Review Requests says so on its own screen, names your exact release and what it has stopped, and gives you the command. It also stops telling you that no pass has ever run for this store: on that release the answer is not one you could act on, and the notice above says what is really wrong.
  • Troubleshooting has a section for a request that never sent, because a schedule that cannot run and a request skipped on purpose look identical from the storefront and are answered in different places.
  • The same command is the answer on any store whose host does not call cron.php, or where you would rather run one scheduler than two.
  • Nothing about your requests, your suppression list or your settings changes on upgrade, and no setting moved.

1.3.0 — 21 September 2026

  • Review Requests now publishes what it holds about a person, column by column, with what removes each one: every column of its six tables, on what this holds about a person. The ask table is the one to read: three of its twenty-five columns are the customer's and are emptied on your retention window, and the other twenty-two are the store's own record that one order was asked once, which is kept for ever on purpose.
  • Customers > Personal Data answers what Review Requests holds about one person and erases them from the same screen, alongside every other extension on the store that answers the same question. Erasing does exactly what retention would have done later: the address, the link and any delivery error are emptied and the request is marked purged. Nothing is deleted, because a deleted request is a verified-purchase badge that stops rendering on your storefront.
  • Remove everything held about a person, linked from the settings screen, is new: the same act over everybody at once, without uninstalling. Every badge keeps rendering and no order can be asked twice afterwards.
  • The opt-out list is kept by both, and the page says so rather than leaving you to find out. Emptying it is the one act that would let your store write again to people who asked it to stop.
  • Nothing about your data changes on upgrade, and no setting moved.

1.2.0 — 10 September 2026

Reading your requests out through the API is much faster on a busy store, and updating puts the index there. Both API collections (the requests themselves and the sending passes) are read a page at a time in a fixed order, and until now nothing in the database was arranged to serve that order, so each page was a read of the whole table. On a store with 200,000 rows that was 71.8 milliseconds a page; it is now 0.16, and walking the lot end to end went from about four and a half minutes to under a second. You do not have to do anything: updating adds the index to the tables you already have. Nothing about what the API returns changed, so an integration built against 1.1.0 keeps working untouched.

One bug fix a multilingual store could not see, and a wording section that refuses nothing.

A request email could be written in the wrong customer's language. If your store runs more than one language, a sending pass that mailed several customers in a row could hand one of them the sentences meant for the customer before them, where the second customer's language was one Review Requests ships no translation of. Nothing failed and nothing was logged; the email simply read in somebody else's language. Fixed, on both the email and the page its link opens. A store running one language was never affected.

The wording section now shows what ships instead of pre-filling it. The review disclosure line and the badge label used to arrive in the box as real text, which meant opening another language and pressing Save wrote our English into that language as your wording, permanently, with nothing on screen to say so. They are now shown in grey behind an empty box, the way the other fields already were, and clearing any box puts our wording back rather than leaving the sentence out. So there is no longer a field this screen can refuse to save: the disclosure line is still never blank, and the fallback to our wording, not a red message, is what keeps it so. Where an earlier version had frozen our English into one of your languages, this release takes it back out and leaves anything you typed alone.

A ninth field. The introduction above the review forms, on the page the email's link opens, is now yours to write, alongside the eight that already were.

Which language your customer's email is written in is now recorded as a language code rather than as OpenCart's internal id for it. A language you delete and re-add takes a new id, and the old one can be handed to a different language, so a record kept for months could come to name the wrong one. The API gains an opencart_language_code field beside the existing opencart_language_id, which is unchanged and still there.

Beside all of that, Review Requests now works out which of the languages it ships your store should be served rather than assuming your language code is spelled the way our directories are. It still ships English and only English, so that question has one answer today. See Limits and guarantees for what a shopper reads in which language and why.

1.1.0 — 8 September 2026

Nothing you can see in the storefront or in the admin changed. The request email, the reminder, the landing page, the unsubscribe link, the verified-purchase badge, the Requests tab and the suppression list all behave exactly as they did in 1.0.0. This release adds one thing beside them and changes nothing that was already there.

Review Requests now answers a JSON API, for a system that keeps your own records (a reporting tool, a BI stack, whatever holds the numbers you report on) rather than for a browser. Two things it can read:

  • ask: one order asked for a review, with a line per product on it and the OpenCart review id each one collected, so which of our reviews came from a real purchase is one call. One at a time, or the whole set walked page by page, narrowed by state, by store, by order, by when it was discovered or by when it last changed.
  • run: one pass of the sending machinery: what it found, what it sent, what it skipped and how it ended, so a monitoring system can tell a store whose cron has stopped from one with nothing to send.

It is off until you switch it on, and while it is off every route answers as though the extension had no API at all. The switch is in a new API section at the bottom of the Settings tab, beside the base address, the versions being answered, a link to System → Users → API and a warning if there is no credential that could call it yet. It is one switch for the whole installation rather than one per store, so on any store but the default that section shows the state and the way to the control.

That switch is deliberately independent of the extension's own status. You can switch Review Requests off, so no requests go out, and the API keeps answering. What happened to the requests you already made is your own record, and a storefront switch should not hide it from the system that holds your data.

Four things to know before you hand the address to anybody:

  • The API only ever reads. Nothing can send a request, write a review, unsubscribe anybody or add an address to the suppression list through it. A resend and an acknowledgement are judgements about one customer and stay on your own screen, where the record of who made them is kept. Writing a review through an API is words in somebody's mouth under a badge that claims a real person wrote them, and no release will add it.
  • The suppression list is not readable through it. It is the audience, and the credential below cannot be narrowed to one extension.
  • The credential is OpenCart's own API user, and it is not scoped to this extension. One is enough to read every extension's API on the store and core's own order API besides, across every storefront in the installation. Restrict it by IP address under System → Users → API, and treat it the way you would treat an admin login.
  • One thing an incremental sync cannot see. You can ask for every request changed since a moment, and every change this extension makes moves that stamp, including erasing somebody, which here empties the row and keeps it rather than deleting it. What does not move it is OpenCart approving a review: that happens in core's own Catalog → Reviews screen and touches nothing this extension owns, so a request can go from Waiting to be checked to On the site without an incremental read noticing. Re-read the waiting ones, which is a short list, or walk the whole collection periodically.

The API's own page is the API, and it is generated from what the extension actually answers rather than written beside it.

Everything each version promises stays answerable for at least twenty-four months after a replacement ships. See the API promise.

1.0.0 — 30 August 2026

The first public release. There is no previous version, so nothing below is a change. This entry is the baseline every later one is measured against.

What ships: one email per order, sent once the order reaches the status you chose and the delay you set has gone by, listing every product on it still worth reviewing; one optional reminder after it, never a second, and any review landing for that order cancels it. The link opens a page with a card per product (no account, no password, no captcha), so a guest order is asked like any other, and each card submits on its own. What comes back is written through OpenCart's own review model, so it moderates and reports like a review typed on the product page, and nothing is approved on your behalf. Approved reviews carry a Verified purchase badge and a disclosure line, spliced into the review list your theme already renders and both yours to reword per language.

Around that: a suppression list anybody can put themselves on from the footer of any request email, behind a confirmation button rather than a link that acts on being opened; a sending rate you set per rolling 24 hours, with a cooldown that leaves one address alone between requests, so how often your crontab fires does not change the volume; an initial collection that shows you the arithmetic, and how many days it will take, before it touches your back catalogue; a checklist at the top of the Settings tab that names the screen fixing each line it fails; and the Requests tab, one row per order in one of nine states, with Needs a look counting the rows pointing at something that has changed since. Every setting is per store, and every link, logo and thumbnail in an email is absolute against the address of the store the order was placed on.

What it does not do is the shorter list, and the one to read first. There is no review gating in any form, and there will not be one.

It runs on OpenCart 4.0.2.0 and 4.1.0.3, the two releases a full install-to-uninstall pass has actually been run against. It does not refuse to install anywhere: it enforces no version floor of its own, so a store outside that pair is untested rather than blocked. On 4.1.0.4 in particular it installs and works, but drive it from the command line: that release cannot run any scheduled task at all, for any extension on the store. See requirements and install.

The sweep has two ways to wake, and only two: OpenCart's own scheduled task, and the command-line entry point. Neither can be reached over the web, deliberately: what a stranger would otherwise be pressing is a button that sends email to your customers, and a sent ask is never asked again.

What an update keeps

Nothing you have collected is lost. The requests, the collected reviews and the join that badges them, the suppression list and the reading mark all stay. No table is dropped, at an update or ever. So an update does not re-ask anybody and does not start over from your back catalogue.

Your settings come back, with the exceptions below. An update is an uninstall and then an install, and OpenCart deletes an extension's settings at the uninstall step. Review Requests keeps its own copy of them and puts them back afterwards. Each store keeps its own, apart from module_review_requests_api_enabled and module_review_requests_diary_verbose_until, which Review Requests reads once for the whole installation.

These are asked for again rather than put back:

  • module_review_requests_status — Whether the module is on is OpenCart's to set, and an extension putting it back for itself is an extension deciding it should be switched on. Switch it back on after an update with the Status switch on this extension's own settings screen, which Extensions > Modules opens with its Edit button: the module list itself has no switch.
  • module_review_requests_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.

A setting a release adds does not change what your store does. Its default is what Review Requests 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.