php4u / module-watchtower-m2-connector

php4u/module-watchtower-m2-connector

Watchtower monitoring connector - observes store data locally and reports coarse anomaly statuses to the Watchtower platform. See LICENSE.

magento2-module Compatibility: 2.4.8-2.4.9 Code Quality: Fail Tests: N/A Security: Pass BUSL-1.1

Watchtower Connector for Magento 2

Your checkout broke at 2am. Nobody noticed until a customer emailed at 9.

Uptime monitors do not catch this. The site was up the whole time. It was
returning 200s, serving pages, and quietly failing to take money.

Watchtower Connector watches the things that actually mean your shop is
working: orders completing, carts being created, customers signing in, your ERP
sync still running, cron still ticking, queues still draining. When one of them
stops behaving the way it normally does, you hear about it.

The platform side lives at watchtower-commerce.com.
The documentation covers creating a
project, connecting a store, and what each signal means.

Your numbers never leave your store

This matters enough to be the second thing on the page.

Everything is worked out inside your Magento install. The baseline, the
thresholds, the comparison, the decision that something looks wrong: all of it
runs locally, on your own server.

What gets sent is a word. NORMAL, or SEVERE_DROP, or INSUFFICIENT_DATA,
per signal, per store view. Never an order count, a revenue figure, a customer
name, a product, an email address, or an error message. The build fails if
anything beyond the documented fields reaches the payload, or if the API key
ever turns up in a request body. Those tests live in the source repository, so
you can read them rather than take our word for it.

So you can run this on a store whose numbers you would not share with anyone,
and the answer to "what does Watchtower know about my business" stays "whether
each signal looked normal this hour".

What it watches

Nine signals. Some compare against your own history, some against fixed
thresholds, some are a straight pass or fail.

Against your own baseline. These learn what a normal Tuesday at 3pm looks
like for your shop specifically, then tell you when this Tuesday at 3pm is not
that. A store doing 40 orders a day and a store doing 40,000 each get judged
against themselves.

Signal Catches
checkout Orders stopped completing
basket_quote Nobody is filling carts any more
customer_account Sign-ins and registrations fell off a cliff

Against fixed thresholds. No warm-up period. These work on your first day
and on a store of any size, because "half of checkout attempts are failing" is
bad regardless of what normal looks like for you.

Signal Catches
checkout_failure A payment method, a shipping rate call, or a tax service breaking order placement
admin_auth_failure A burst of failed admin sign-ins

Pass or fail. Infrastructure that either works or does not.

Signal Catches
cron_health Magento's scheduler stopped. Nothing else in Magento works properly when this happens, and stores run for days without noticing
integration_health Your ERP, PIM, marketplace or feed sync stopped running
indexer_health An indexer stuck invalid, or a materialized-view backlog nothing is draining
queue_health Queued work piling up with no consumer attached to it

cron_health, admin_auth_failure, indexer_health and queue_health cover
the whole installation. The rest are reported per store view, so a problem on
your German storefront does not get averaged away by a healthy UK one.

How fast you hear about it

Signals are evaluated once an hour, on the last complete hour, and a change is
only reported once it has held for two consecutive evaluations. In practice
that means about one to two hours from a problem starting to an alert
arriving.

That two-evaluation wait is deliberate. Monitoring you learn to ignore is worse
than none, and a single odd hour is usually just a quiet hour.

Integrations, without the guesswork

integration_health is the one signal you choose the contents of, and it tries
hard not to make that your problem.

The connector reads the scheduled jobs your store actually runs and groups them
under the extension that installed them, so you tick Mailchimp rather than
hunting for ebizmarts_ecommerce among sixty-odd job codes. Pick as many as
you like.

There is no interval to enter. The connector measures how often each job really
runs on your server and judges it against that. A nightly sync gets judged as a
nightly sync. A job that runs every five minutes gets five minutes. Get that
number wrong by hand and you either miss real outages or cry wolf every night,
which is why the connector works it out instead of asking you.

Integrations that run no cron at all, like an ERP pushing into Magento over the
API, can send a watchtower_integration_health event from your own code and
appear in the same list.

Requirements

  • Magento 2.4.7, 2.4.8 or 2.4.9 (Open Source or Adobe Commerce on-prem)
  • PHP 8.3, 8.4 or 8.5

Magento's own cron must be running. If it is not, this module cannot do
anything, and cron_health is the signal that would have told you.

Exact Composer constraints
php                                      ~8.3.0||~8.4.0||~8.5.0
magento/framework                        103.0.*
magento/framework-amqp                   100.4.*
magento/framework-bulk                   101.0.*
magento/framework-message-queue          100.4.*
magento/module-asynchronous-operations   100.4.*
magento/module-backend                   102.0.*
magento/module-config                    101.2.*
magento/module-cron                      100.4.*
magento/module-store                     101.1.*

composer.json is authoritative; this list is generated from it.

Install

composer require php4u/module-watchtower-m2-connector
bin/magento module:enable Watchtower_Connector
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush

Then go to Stores > Configuration > Watchtower > Connection and fill in two
fields:

Field What to put in it
Watchtower Base URL Already filled in with the live platform. Only change it for a self-hosted deployment.
Install API Key The key from your Watchtower project. Stored encrypted.
Enabled Turns the whole module on and off without losing your settings.

Click Test Connection to check the key before waiting for the next cron
run. No project yet? Create one and get a key.
Already have one? Find or rotate your key.

Some signals report immediately. checkout and basket_quote seed their
baseline from your existing order and cart history at install time, so they
usually have something useful to say within a day rather than after weeks of
watching. customer_account cannot be seeded this way (there is no historical
log to seed sign-ins and registrations from), so it always starts cold and
needs several weeks of live activity to establish its own baseline, the same
as a brand new store would for any signal.

Running it

For devops

Cron. One job, watchtower_report, is polled every five minutes and does
real work roughly once an hour. It tracks elapsed time since its last real run
rather than watching for a particular minute, so it self-corrects if your host
runs cron:run irregularly, and installs naturally spread themselves across
the hour instead of all reporting at once. watchtower_sync,
watchtower_rollup_prune and watchtower_event_counter_prune run daily.
None of it needs configuring.

The module can only run as often as bin/magento cron:run is invoked. Magento
recommends every minute; every five minutes is the practical floor here.

Storefront cost. Nothing runs in a shopper's request. Observation is cheap
and writes to the module's own tables; all evaluation and network traffic
happens in cron.

When the platform is unreachable. Reports are buffered locally and
backfilled on reconnect, with exponential backoff between attempts. An outage
at our end produces a delayed catch-up, not a hole in your history.

Diagnostics over SSH, without needing admin access:

bin/magento watchtower:status

Connection state, buffer backlog, per-signal status and sequence numbers, and
the most recent submission outcomes including anything the platform rejected
and why. The admin Diagnostics page shows the same thing.

Command What it does
watchtower:ping Check connectivity and key validity
watchtower:status Full local diagnostics
watchtower:sync Push this install's store views now
watchtower:report Evaluate and submit now
watchtower:coverage Report and seed local baseline history
watchtower:event-counter-prune Prune every raw event counter table past retention now
watchtower:rollup-prune Roll up and prune aged counters now

All of these run on a schedule already. The commands exist for setup checks and
troubleshooting.

For developers

Detection lives in Model/, one directory per signal, each with its own
evaluator. The wire contract, including payload shape, evaluation cadence,
debounce rules and the privacy boundary, is specified on the platform side
rather than invented here.

Each signal versions its own ruleset_version independently, and reports it on
every submission, so the platform always knows which logic produced a given
status:

Signal Constant
cron_health Model/CronHealth/Evaluator::RULESET_VERSION
checkout, basket_quote, customer_account Model/RateSignal/DispersionEvaluator::RULESET_VERSION
checkout_failure Model/CheckoutFailure/Evaluator::RULESET_VERSION
admin_auth_failure Model/AdminAuthFailure/Evaluator::RULESET_VERSION
integration_health Model/IntegrationHealth/WatchedSetEvaluator::RULESET_VERSION
indexer_health Model/IndexerHealth/Evaluator::RULESET_VERSION
queue_health Model/QueueHealth/Evaluator::RULESET_VERSION

There is deliberately no single module-wide version pinned to the spec. Changing
how one signal computes its baseline says nothing about the others, and one
number would hide that.

Tests. The unit suite lives in Test/Unit in the source repository and
runs on all three supported versions, against the PHPUnit each one ships:
9.6 on 2.4.7, 10.5 on 2.4.8, 12.5 on 2.4.9.

It is export-ignored, so a Composer install gives you the module without the
tests. Clone the repository if you want to run or read them.

Emitting a custom integration signal from your own module:

$this->eventManager->dispatch('watchtower_integration_health', [
    'integration' => 'acme_erp',   // appears in the admin once we have seen it
    'status'      => 'ok',          // or 'failed'
    'store_id'    => $storeId,      // optional, defaults to current store
]);

Send it once and the label becomes selectable under Watchtower >
Integrations
. The connector measures how often it arrives and alerts when it
stops. You cannot type a label in by hand, deliberately: a typo would sit there
looking healthy forever while the integration behind it was dead.

License

Business Source License 1.1 (BUSL-1.1).

Read it, audit it, run it in production to monitor your own stores. You cannot
use it to build a competing commercial monitoring service. On 2029-08-14 it
converts to MIT. The LICENSE file governs.

Changelog

All notable changes to this module are documented here. Versioning follows
Semantic Versioning, tracked via git tags on this
repository (composer.json deliberately carries no hardcoded version
field — Composer's VCS-repository support resolves it from the tag).

[1.30.1] - 2026-09-02

Packaging fix only, no code change. The distributed package now excludes
docs/, README.md, CHANGELOG.md, phpcs.xml, phpstan.neon, and
bin/, none of which Magento reads at runtime, alongside Test/ which
was already excluded. docs/ in particular named a real merchant's
store in an internal design record.

[1.30.0] - 2026-09-02

The Watchtower > Diagnostics page now reads as merchant-facing status,
not internal wire state. A store view still building its baseline shows a
calm "Warming up" note instead of the same red "Needs attention" banner a
real anomaly gets, status and reason values are plain English ("Warming up",
"Routine check-in") instead of raw values like INSUFFICIENT_DATA, and the
internal Sequence Number column is gone.

[1.29.0] - 2026-09-01

Stops integration_health reporting a healthy status for a store whose
watched set is empty. When the set is emptied the signal kept heartbeating its
last confirmed verdict, so a store that lost its selection reported NORMAL
every hour while nothing was being watched at all; it now reports
INSUFFICIENT_DATA, which keeps the platform's staleness sweep quiet without
claiming health.

If Watchtower > Integrations shows nothing selected, re-select the
integrations you want watched: an install that upgraded from 1.24.x or earlier
straight to 1.27.0 or later skipped the migration that carried the old
per-store-view sources over.

[1.28.0] - 2026-08-28

Reworks the Watchtower > Integrations page after reviewing it on a store
with fourteen integrations rather than one. Integrations now lead with a
distinct name, so three Amasty extensions no longer all read "Amasty"; the
per-integration job list is an inline link instead of a heading repeated down
the page; every integration shows how often it was measured running, not only
the awkward ones; and there is a filter box plus a line naming anything you
watch that is currently failing.

Also stops offering cron jobs that have no class behind them. A crontab.xml
config_path naming a different job code than its own job name makes Magento
mint a schedule with nothing to execute, which can only ever look broken. On
one store that was catalog_product_alert, erroring every time it fired.

Upgrade: run bin/magento setup:upgrade and bin/magento setup:di:compile.
No configuration changes, and anything you already watch stays watched.

[1.27.0] - 2026-08-27

Internal cleanup with no change to what the connector monitors or reports:
removes the per-store-view integration_health source model that the
Integrations page replaced in 1.25.0, along with its database table.

Upgrade: run bin/magento setup:upgrade. It drops
watchtower_integration_health_config, which is no longer read.

[1.26.0] - 2026-08-27

Adds a Custom integrations section to Watchtower > Integrations, for
integrations that never run as a scheduled job, such as an ERP that pushes into
your store over the API. Your own code sends a watchtower_integration_health
event and the label appears there to be ticked. You can only select events we
have actually received, never type a name in, since a name with a typo would
look healthy forever while the integration behind it was dead.
bin/magento watchtower:status now names a failing custom integration too.

[1.25.0] - 2026-08-27

Replaces how integration_health is set up. You now tick the integrations you
want watched under Watchtower > Integrations, discovered for you and named
by the extension that ships them, as many as you like per install rather than
one per store view. There is no longer an interval to enter: the connector
measures how often each job really runs and judges it against that, which fixes
a healthy nightly sync being reported as down for 23 hours a day.

Upgrade: run bin/magento setup:upgrade. It adds two tables and moves your
existing cron-job and convention-event sources across automatically. Only
sources configured as a queue consumer cannot be moved; those are written to
the log instead. Convention events keep working once migrated, but cannot yet
be added from the new page.

[1.24.1] - 2026-08-25

Corrects the queue_health line in bin/magento watchtower:status, which
described every queue holding a message as "undrained". On the MySQL queue
backend a busy store nearly always has work pending, which is healthy until it
stays put, so the line now reads "work waiting in" and leaves the verdict to
the signal status itself.

[1.24.0] - 2026-08-25

Adds the queue_health signal, reporting whether Magento's message-queue
consumers are working through the jobs queued for them. Stock updates, bulk
imports, product URL rebuilds and admin config saves all wait in these queues,
and when nothing drains them that work piles up while cron itself still looks
healthy. Queue depth alone is never the test: a store part-way through a bulk
import legitimately holds a deep queue and is fine, so the signal reports on
work left waiting with nothing processing it. Both queue backends are
supported, resolved per consumer, so a store mixing RabbitMQ and the MySQL
backend is read correctly. Running your consumers outside Magento's cron is a
supported setup and is not treated as a fault. bin/magento watchtower:status
names the affected queue locally; only the categorical status is transmitted.
Requires platform connector metrics spec 2.12 or later.

[1.23.0] - 2026-08-25

Adds the indexer_health signal, reporting whether your indexers are current
and the materialized-view backlog is draining. It catches the case where
everything else looks fine while the storefront serves stale prices and
out-of-date category pages because a reindex never finished. Reports on how
long the condition has lasted, not on the bare status, so an indexer briefly
invalid after an import does not alert. Requires platform connector metrics
spec 2.10 or later.

[1.22.0] - 2026-08-24

Raises the minimum store volume at which the rate-based signals (cart
activity, checkout, and customer accounts) will report a drop. Below roughly
20 orders a day these signals now report "Warming up" rather than a drop,
because at that volume an ordinary quiet overnight stretch is statistically
indistinguishable from a real stop, and the underlying detection method is
only validated from about 20 to 30 orders a day upward.

This removes a class of false "severe drop" alert that low-traffic stores
could get overnight. It was confirmed in production: a quiet night on a
genuinely low-volume store paged as a severe drop in cart activity while
checkout and every other signal stayed normal. Higher-volume stores are
unaffected.

The failure signals (checkout failures, admin sign-in failures) and cron
health need no baseline and keep working at any volume, so a low-traffic
store is still protected against a genuinely broken checkout or a stopped
cron.

No schema change. Nothing to do beyond updating the module.

[1.21.1] - 2026-08-23

Fixes the two install-scoped signals, admin_auth_failure and cron_health,
reporting a brief "Warming up" status in their first hour on a fresh install.
Both read a fixed threshold or the scheduler's own record, so they have a
trustworthy reading from the very first evaluation and never need to warm up.
A healthy first hour now reports normal straight away instead. A problem
present from the first hour still takes two consecutive evaluations to
confirm before it alerts, exactly as before.

[1.21.0] - 2026-08-23

Adds admin_auth_failure, a new signal counting failed Magento admin
sign-ins per hour, install-wide. A burst of these usually means someone is
guessing passwords rather than an administrator mistyping one. Like
cron_health it is install-scoped, and it never transmits or stores the
attempted username or the exception, only a count.

checkout_failure now tightens its thresholds toward each store's own
demonstrated normal once the store has enough history, so a clean store
catches a degradation the conservative default would sleep through. This
never delays first-hour detection: with no history the fixed defaults
apply unchanged.

Also consolidates the two-evaluation debounce every signal shares into one
class, replacing three near-identical copies. No behavioural change.

Run setup:upgrade, it adds one table for the new signal's counter.

[1.20.0] - 2026-08-23

Adds checkout_failure, a new signal reporting the share of order
placement attempts that failed. Magento's tables only record orders that
succeeded, so a placement that throws leaves nothing to count and is
invisible to every other signal until the drop in order volume becomes
statistically obvious. This one needs no baseline and reaches a verdict in
its first hour, including on low-volume stores where the drop-based
detection cannot say anything at all.

customer_account now actually reports the login and logout counts it has
been collecting all along; they were being written and pruned but never
read, so the category was silently reporting registrations only. As a
consequence it is no longer seeded at install: two of its three
sub-counters have no history to read, and seeding only the third would
leave every live hour compared against a baseline missing its largest
term. That category now warms up over its first baseline window instead,
and says so in diagnostics. checkout and basket_quote still seed
immediately.

Requires the Watchtower platform to be running metrics spec 2.7 or
later.
An older platform rejects the whole submission, not just the new
report, so upgrade the platform side first. Run setup:upgrade, it widens
one column.

[1.19.0] - 2026-08-23

The integration health source picker now lists every cron job the store
declares, grouped by cron group, rather than only the jobs currently sitting
in cron_schedule. That table is a work queue, not a catalogue, so most
declared jobs were invisible for most of the day.

Also fixes three cases where integration_health reported a status its
configured source never justified: changing the monitored source carried the
previous source's evidence and status forward, a newly configured
long-cadence job reported DOWN before it had a chance to run, and a
monitored job's success could be missed entirely when its cron_schedule
row was pruned between hourly cycles. Run setup:upgrade, it adds three
columns.

[1.18.1] - 2026-08-22

Fixes every outbound API call 401ing with "Missing API key" on Magento
2.4.7 and older: Magento's own Curl adapter silently dropped the
Authorization header on those versions. The client now uses Laminas's
own Curl adapter instead, which has always formatted headers correctly.

[1.18.0] - 2026-08-22

The connector now reports its own version on every metrics submission
(roughly hourly), not just the once-daily sync. The platform's admin
previously showed a connector version up to a day stale after a mid-day
upgrade.

[1.17.0] - 2026-08-22

The admin diagnostics page and watchtower:status now show per-signal
local baseline seed coverage (e.g. "cart history seeded: 26 days" or
"cart history unavailable (quote lifetime is 7 days); warming up") --
the answer to "why is this still warming up?", previously only visible
in a log line or a manual watchtower:coverage run. Adds a
watchtower_seed_coverage table, written by both watchtower:coverage
and the automatic first-evaluation seed; run setup:upgrade.

[1.16.0] - 2026-08-22

The admin diagnostics page and watchtower:status now show which named
checks (dispersion, seasonal, trend) actually drove a rate-based signal's
last classification, for a status transition produced by the ensemble
combiner. Adds an ensemble_driving_checks column to
watchtower_dispersion_state; run setup:upgrade.

[1.15.0] - 2026-08-22

The admin diagnostics page and watchtower:status now show the reason
(heartbeat or transition) behind every signal's last reported status, not
just the status itself. Adds a last_reported_reason column to all three
signal state tables (watchtower_health_state, watchtower_dispersion_state,
watchtower_integration_health_state); run setup:upgrade.

[1.14.0] - 2026-08-22

The admin diagnostics page and watchtower:status now show a store's
estimated detection latency for a full outage on any signal currently in
Low-Volume Signal Mode, so a low-volume merchant sees an honest confidence
number instead of a silent status toggle.

[1.13.0] - 2026-08-22

Low-Volume Signal Mode now reports INSUFFICIENT_DATA instead of a
percentile-based verdict when a signal's estimated daily volume is below 5
orders/day, the floor the spec's own simulation actually validated. A
near-dormant store view with only a handful of historical events could
otherwise report SEVERE_DROP off a gap distribution too thin to mean
anything, the moment its already-typical silence passed the small sample's
own maximum. ruleset_version bumps to 1.4.0.

[1.12.0] - 2026-08-22

Seeds a store view's historical baseline automatically the first time it's
evaluated, instead of only via the manual watchtower:coverage command --
an install that never had it run by hand previously cold-started on
whatever the live cycle collected from scratch, risking a false anomaly
off a few hours of noise instead of a real baseline.

[1.11.0] - 2026-08-22

Fixes a false "back to normal" email on a brand-new install or store view:
CronHealth, IntegrationHealth, and RateSignal\DispersionEvaluator now
report NORMAL confirmed straight out of the INSUFFICIENT_DATA seed as a
heartbeat instead of a transition, since nothing was ever actually down.

[1.10.1] - 2026-08-21

Condenses this changelog's entries. No functional change.

[1.10.0] - 2026-08-21

Prunes watchtower_event_counter and watchtower_event_drop_counter,
which previously grew unbounded (90-day retention, new
watchtower:event-counter-prune command). Also moves all
watchtower_* cron jobs into their own dedicated cron group, isolated
from Magento's shared default group.

[1.9.0] - 2026-08-21

Adds a Configuration link under the Watchtower admin menu, and the
FR27 admin notice for available connector updates. Also fixes invalid
db_schema.xml comments (apostrophes/backslashes) that broke
setup:upgrade.

[1.8.1] - 2026-08-21

Fixes invalid XML in etc/crontab.xml (a stray -- inside a comment)
shipped in v1.7.0/v1.8.0.

[1.8.0] - 2026-08-21

Fixes the reported connector version showing a leading "v", which also
threw off the platform's version comparison.

[1.7.0] - 2026-08-21

Replaces ReportJob's wall-clock jitter with an elapsed-time guard.
Fixes installs whose host cron ran less often than every 5 minutes
silently never reporting.

[1.6.0] - 2026-08-21

Fixes on-enable sync silently no-op'ing when Base URL, API Key, and
Enabled were all saved together on first setup.

[1.5.0] - 2026-08-21

Surfaces ignored local/dev-domain syncs to the merchant via an admin
notice instead of only logging them. Also warns on the config screen
if the current store's own URL looks local.

[1.4.1] - 2026-08-19

Renames the Composer package to php4u/module-watchtower-m2-connector
— the previous name broke Magento's own unit test suite discovery.

[1.4.0] - 2026-08-19

Renames the Composer package to php4u/watchtower-m2-module-connector
(naming preference).

[1.3.0] - 2026-08-19

Renames the Composer package to php4u/module-connector — the
watchtower vendor namespace was already taken on Packagist.

[1.2.0] - 2026-08-16

Adds a minimum/latest version check against the platform. Installs
below the minimum self-disable sync and reporting (buffering
continues) until upgraded; below latest is advisory only. Replaces the
old GitHub-polling update check — run bin/magento setup:upgrade
after updating, it drops two now-unused columns.

[1.1.0] - 2026-08-16

Syncs now report this install's Magento version/edition and the
connector's own version. The platform echoes back EOL and
update-availability status in response.

[1.0.1] - 2026-08-15

Added a copyright/license header to every source file. No behavioral
change.

[1.0.0] - 2026-08-15

Initial release.

Versions
Version Stability QA Status Compatibility Released
v1.30.1 stable Fail Magento 2.4.8-2.4.9 Details 2026-09-02 20:20:44
v1.30.0 stable Not tested Not yet tested Details 2026-09-02 19:34:16
v1.29.0 stable Not tested Not yet tested Details 2026-09-01 11:15:13
v1.28.0 stable Not tested Not yet tested Details 2026-08-28 09:52:06
v1.27.0 stable Not tested Not yet tested Details 2026-08-27 22:08:54
v1.26.0 stable Not tested Not yet tested Details 2026-08-27 20:53:50
v1.25.0 stable Not tested Not yet tested Details 2026-08-27 20:37:15
v1.24.1 stable Not tested Not yet tested Details 2026-08-25 18:48:35
v1.24.0 stable Not tested Not yet tested Details 2026-08-25 18:40:06
v1.23.0 stable Not tested Not yet tested Details 2026-08-25 13:06:59
v1.22.0 stable Not tested Not yet tested Details 2026-08-24 09:32:27
v1.21.1 stable Not tested Not yet tested Details 2026-08-23 19:33:16
v1.21.0 stable Not tested Not yet tested Details 2026-08-23 18:04:10
v1.20.0 stable Not tested Not yet tested Details 2026-08-23 14:23:16
v1.19.0 stable Not tested Not yet tested Details 2026-08-23 11:40:59
v1.18.1 stable Not tested Not yet tested Details 2026-08-22 19:44:59
v1.18.0 stable Not tested Not yet tested Details 2026-08-22 18:47:40
v1.17.0 stable Not tested Not yet tested Details 2026-08-22 15:10:28
v1.16.0 stable Not tested Not yet tested Details 2026-08-22 14:51:56
v1.15.0 stable Not tested Not yet tested Details 2026-08-22 14:41:18
v1.14.0 stable Not tested Not yet tested Details 2026-08-22 14:14:44
v1.13.0 stable Not tested Not yet tested Details 2026-08-22 13:52:40
v1.12.0 stable Not tested Not yet tested Details 2026-08-22 09:17:48
v1.11.0 stable Not tested Not yet tested Details 2026-08-22 08:56:39
v1.10.1 stable Not tested Not yet tested Details 2026-08-21 19:26:30
v1.10.0 stable Not tested Not yet tested Details 2026-08-21 19:13:39
v1.9.0 stable Not tested Not yet tested Details 2026-08-21 16:14:53
v1.8.1 stable Not tested Not yet tested Details 2026-08-21 15:46:46
v1.8.0 stable Not tested Not yet tested Details 2026-08-21 15:41:22
v1.7.0 stable Not tested Not yet tested Details 2026-08-21 15:33:38
v1.6.0 stable Not tested Not yet tested Details 2026-08-21 14:24:19
v1.5.0 stable Not tested Not yet tested Details 2026-08-21 12:03:05
v1.4.1 stable Not tested Not yet tested Details 2026-08-19 18:04:28
v1.4.0 stable Not tested Not yet tested Details 2026-08-19 17:52:00
v1.3.0 stable Not tested Not yet tested Details 2026-08-19 17:43:11
v1.2.0 stable Not tested Not yet tested Details 2026-08-16 19:29:24
v1.1.0 stable Not tested Not yet tested Details 2026-08-16 18:37:01
v1.0.1 stable Not tested Not yet tested Details 2026-08-15 20:12:36
v1.0.0 stable Not tested Not yet tested Details 2026-08-15 18:55:04

Requires 10

Package Constraint
magento/framework 103.0.*
magento/framework-amqp 100.4.*
magento/framework-bulk 101.0.*
magento/framework-message-queue 100.4.*
magento/module-asynchronous-operations 100.4.*
magento/module-backend 102.0.*
magento/module-config 101.2.*
magento/module-cron 100.4.*
magento/module-store 101.1.*
php ~8.3.0||~8.4.0||~8.5.0

Compatibility

Each Magento release line is installed on its supported PHP versions, then the module is built (DI compilation + static-content deploy) and its unit and integration suites are run. The matrix shows the lines and PHP versions the module is confirmed to install and run on. Code-quality results further down (phpstan, phpcs, …) are reported separately and never affect compatibility.

Compatibility matrix (Magento × PHP)
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 not tested Pass
2.4.8 Pass Pass
2.4.9 Pass Pass

Code Quality

Advisory checks against the module's source. Static analysis runs once across the whole module; PHPStan re-runs per Magento + PHP version because resolvable symbols differ between releases. These NEVER affect the Compatibility badge. A phpcs finding can't make a module incompatible.

Static analysis

Coding standards (phpcs), mess detection (phpmd), copy-pasted code (cpd), PHP cross-version compatibility, composer.json validity. Each runs once for the whole module.

Static analysis results
Tool Status Findings Summary
PHPCS Pass 0
PHPMD Warning 22 22 rule violations (UnusedPrivateField:20, ExcessiveClassLength:2)
Cpd Warning 18 18 duplicated chunks spanning 352 total lines (min-lines=5, min-tokens=70)
Composer validate Pass 0

PHPStan

Type-checks the module's PHP against a real Magento install at the configured gate level. Re-runs per Magento and PHP version because resolvable symbols differ between releases.

PHPStan results by Magento and PHP version
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 N/A 30
2.4.8 30 30
2.4.9 30 30

Tests

Unit and integration suites, run for each applicable Magento and PHP version. A test failure speaks to the module's behaviour, not its compatibility with a Magento line, so it is reported here separately and never reddens the compatibility matrix.

Unit tests

Unit tests results by Magento and PHP version
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 N/A N/A
2.4.8 N/A N/A
2.4.9 N/A N/A

Integration tests

Integration tests results by Magento and PHP version
Magento PHP 8.2 PHP 8.3 PHP 8.4 PHP 8.5
2.4.7 N/A N/A
2.4.8 N/A N/A
2.4.9 N/A N/A

Security

Security checks run directly against the module: an audit of its declared dependencies for known vulnerabilities (composer audit) and a scan of its source for malware and web-shell signatures. Each runs once. A malware detection fails the version outright.

Security results
Tool Status Findings Summary
Composer audit Pass 0
Malware scan Pass 0
License
BUSL-1.1
Make it pay

Turn an existing module into recurring revenue.

If you already maintain a Magento 2 module on GitHub or GitLab, listing it on Packagento takes about five minutes. We mirror your tags, handle distribution signing, and route paid licenses through Stripe Connect, so you can keep shipping the way you already do.