Integration Health card
At the top of Stores › Configuration › Conviro › AI Chat. One row per part of the integration, each Pass, Warning or Action required with the sentence that fixes it, then one verdict. Nothing is shown as healthy without a measurement. Plan §13, §23. Code: AiChat/Block/Adminhtml/IntegrationHealth.php, AiChat/Service/Health/{HealthCheck,HealthFacts,ConviroStatus}.php. Every message quoted below is from HealthCheck.php (2026-09-24; the Store-wide bearer tokens row 2026-09-26).
Verdict
- Integration ready — no row needs action (with "— N warnings" if any row warns).
- Action required: <row> — <first sentence> (+N more) — the first row that needs action.
- Disconnected from Conviro on <date> UTC — nothing is sent and Conviro no longer reads this store — after a Disconnect (a Warning, not a failure).
Where the facts come from
Magento-side facts (queue, cron, settings, the integration's ACL) are read on every page load. Conviro's view comes from one call to GET /api/magento/tenant-info (3 s connect / 4 s total), cached 60 seconds per API URL and key; the card says how old it is. Save Config drops that cache; Test connection bypasses it. When Conviro cannot be asked, rows that depend on it say so ("as of the last Save Config") and show a Warning, not a Pass.
Rows
Every row that is not a Pass links here ("What this means and how to fix it"), to <Documentation URL>/integration-health#row-<row> — the base is Documentation URL (conviro_aichat/general/docs_url, default https://repo.conviro.io/docs/magento2, where Conviro serves these pages).
Connection
| State | Meaning | Fix |
|---|---|---|
| Pass | "Connected to Conviro workspace "…" (answered in N ms, checked …)". | — |
| Action | Not connected: no API key saved. | Setup wizard › Connect to Conviro (or paste a key and Save Config). |
| Warning | Disconnected on … (and whether Conviro confirmed, is still being told by cron, or could not be told). | Setup wizard › Reconnect. If Conviro could not be told, also disconnect in the Conviro dashboard. |
| Warning | Not checked yet. | Test connection. |
| Action | The API key belongs to another workspace than the one this store was connected to. | Save Config (connects to the key's workspace) or paste the other workspace's key. |
| Warning | Connected, but the module is disabled (Enable = No): no widget, no events. | General Settings › Enable = Yes, Save Config. |
| Action | Magento cannot reach Conviro (no HTTP answer). | Allow outbound connections to api.conviro.io:443, then Test connection. |
| Action | "Conviro's network protection blocked this server — contact Conviro support" (1.4.1): the answer was a challenge / block page of the network protection in front of the Conviro API (cf-mitigated: challenge, or an HTML "Just a moment…" page), not the API. | Contact Conviro support with this server's public IP address; nothing to change in Magento (Troubleshooting). |
| Action | HTTP 401 / 403 that is not an answer of the Conviro API (no JSON body; 1.4.1): a proxy or firewall on this side, or Conviro's network protection. | Check outbound proxies / firewalls; otherwise contact Conviro support. |
| Action | HTTP 401 from the Conviro API: key wrong, revoked or expired. | Paste an active key, Save Config. |
| Action | HTTP 403 from the Conviro API: key lacks kb:write (or magento:module). | Use Connect to Conviro in the setup wizard, or create a key with kb:write and Save Config. |
| Warning | HTTP 429 or 5xx — temporary; queued events are kept and retried. | Test connection again in a few minutes. |
| Action | Any other answer. | Test connection; if it persists, download diagnostics for Conviro support. |
Authentication
| State | Meaning | Fix |
|---|---|---|
| Pass | Magento OAuth 1.0a: every Conviro request is signed; the granted permissions; when Conviro last verified. | — |
| Warning | Same, but Conviro could not be asked now. | Test connection once Conviro is reachable. |
| Warning | Legacy bearer token: Magento rejected the OAuth signature. | A proxy / CDN terminates HTTPS: make it pass the header in web/secure/offloader_header (default X-Forwarded-Proto: https), then Save Config. |
| Warning | Legacy bearer token, other reason. | Save Config to switch to OAuth 1.0a. |
| Action | Waiting for the connection (no key). | Connect first. |
| Action | The "Conviro AI Chat" integration does not exist / is inactive. | Save Config. |
| Action | The integration is missing N permission(s). | Save Config (grants them again). |
| Action | Conviro has this store as disconnected (since …). | Setup wizard › Reconnect, or Save Config. |
| Action | Conviro holds no Magento credentials for this store yet. | Save Config. |
| Action | Conviro's last call to this store failed: … | Fix the cause shown, Save Config. |
| Action | Not registered with Conviro yet. | Save Config. |
Webhooks
| State | Meaning | Fix |
|---|---|---|
| Pass | Signing secret set; when Conviro last accepted a signed event and when the last signed webhook from Conviro was verified. Adds a note when Conviro still accepts unsigned legacy requests (Require Signed Webhooks = No). | Consider Require Signed Webhooks = Yes. |
| Action | No signing secret yet: events cannot be signed and Conviro's webhooks are refused. | Save Config (Conviro issues the secret). |
| Warning | N webhooks to /conviro/webhook/receive were rejected in the last 24 h after the last verified one. | Save Config to re-sync the secret. Rejections that continue are requests not sent by Conviro. |
| Warning | Secret set but no signed event exchanged yet. | Send test event. |
Catalog sync
| State | Meaning | Fix |
|---|---|---|
| Pass | How many products Conviro knows, last product update delivered, last full re-sync. | — |
| Warning | Sync Products to KB is off. | Switch it on, Save Config, Re-sync catalog. |
| Action | The last catalog re-sync failed: … | Fix the cause, Re-sync catalog. |
| Action | The re-sync has not moved for over 15 minutes: cron is not running it. | bin/magento cron:install; it resumes where it stopped. |
| Warning | Re-sync in progress (progress text). | Nothing. |
| Action | Conviro has no products from this store yet. | Re-sync catalog. |
| Warning | No products at Conviro yet, but N events are waiting. | Wait for delivery (see Cron / queue). |
| Warning | Not verified with Conviro. | Re-sync catalog once, then Test connection. |
Orders / events
| State | Meaning | Fix |
|---|---|---|
| Pass | Last event delivered (and how long after it happened), last order event, what Conviro last received and how many today. | — |
| Action | The event queue table is missing. | bin/magento setup:upgrade. |
| Action | N events held: Conviro refused the store's credentials (401/403). | Check the API key, Save Config — held events are re-queued automatically. |
| Action | N events failed permanently (last error …). | Fix the cause, Retry failed (or Repair failed items). |
| Warning | N events being retried (7 attempts over about 10 h 43 min — the text is built from the retry schedule, RetryPolicy::describe()). | Test connection to see why. |
| Warning | Send Order Events is off (chat order lookups still work). | Switch it on, Save Config. |
| Warning | No event delivered yet. | Send test event. |
Cron / queue
| State | Meaning | Fix |
|---|---|---|
| Pass | Delivery job ran … (last success …); connection maintenance ran …; N events waiting. | — |
| Action | Cron has never run the Conviro delivery job. | bin/magento cron:install; check crontab -l. |
| Action | Cron runs, but not the Conviro jobs. | bin/magento cache:flush so cron picks them up. |
| Action | The last delivery run failed (with the error's class and message, e-mail addresses masked). | See var/log/cron.log and var/log/exception.log. |
| Action | Cron has stopped (delivery job last ran more than 10 minutes ago). | Check the crontab and that cron:run completes. |
| Warning | The last run was missed. | Check that cron runs every minute. |
| Warning | N events waiting, the oldest queued more than 15 minutes ago (with the reason, e.g. Conviro's network protection). | Delivery is behind: Test connection, check each cron run finishes. |
Since 1.4.1 the two jobs that run every minute — conviro_deliver_events (the outbox worker) and conviro_connection_maintenance (OAuth migration, disconnect retry, the health report to Conviro) — record their own last run, last success and last failure (Magento's flag table, rows conviro_cron_<job>); Details shows them as Delivery heartbeat and Maintenance heartbeat. The row judges from these, and uses cron_schedule only until the first heartbeat exists — Magento deletes successful cron_schedule rows after an hour, so "when did it last succeed" was not answerable from it.
A store with nothing to send is never flagged: the heartbeat runs every minute whether or not there are events, and "events waiting" counts only events that exist. Both problems — cron silent for 10 minutes, or an event waiting for 15 minutes while cron runs — are also shown as an admin system message on every admin page of a connected store (1.4.1), and the store reports them to the Conviro dashboard (Delivery health on the Magento store card) every 15 minutes; a report that stops arriving is shown there as "no report since …".
Extension version
| State | Meaning | Fix |
|---|---|---|
| Pass | Installed version is the latest. | — |
| Warning | Update recommended. | Run the shown command from the Magento root. |
| Action | SECURITY UPDATE REQUIRED: the installed version is below Conviro's security minimum. | Run the shown command. |
| Warning | Latest version could not be checked. | Test connection. |
The command shown is built by the module from the published version number (since 1.4.0 — any command text Conviro's answer carries is ignored, and a version that is not a plain 1.2.3 / 1.2.3-rc1 is neither shown nor compared). Since 1.4.1 it is built for this store — its Magento mode and the locales a static deploy must build (active store views, active admin users, en_US) — for example, production mode, a tr_TR store: bin/magento maintenance:enable && composer require 'conviro/module-aichat:^<version>' && bin/magento setup:upgrade && bin/magento setup:di:compile && bin/magento setup:static-content:deploy -f en_US tr_TR && bin/magento cache:flush && bin/magento maintenance:disable (composer update conviro/module-aichat in place of the composer require when no valid version is known; developer mode: composer, setup:upgrade, cache:flush). The row says which mode it was built for. Run it as the owner of the Magento files, never as root. Each step, and the release-directory method: Installation › Upgrading. The latest-version answer is cached 12 hours (15 minutes after a failed check).
Environment
Pass: Magento version (and deploy mode), PHP, Conviro API latency, HTTPS storefront. Action when any of: Magento older than 2.4.4; PHP older than 7.4; the default store view's base URL is not https ("order and customer data would travel unencrypted"); the API URL is not https; no outbound connection to Conviro.
Cart & payment events (shown only when relevant)
Warning when Abandoned Cart Recovery or Payment Failure Assistance is on (at any scope) but not confirmed — cart.updated / checkout.started / payment.failed are not sent (with "held since the upgrade to 1.4, <date>" when the upgrade held it). Fix: open the admin message's link (Confirm cart and payment data sharing — confirms only, starts no sync), or set Confirm cart / payment data sharing = Yes and Save Config; or switch the toggle off.
Since 1.4.1 the same sentence is also an admin system message (severity major, on every admin page of a connected store) with a link to the confirmation page, until the feature is confirmed or switched off — a merchant who upgraded from the command line sees it without opening this card.
Storefront widget (shown only when relevant)
Since 1.4.1 the card looks at the theme of every active store view — and its parent themes, in Magento's fallback order — for Conviro overrides: Conviro_AiChat/templates/widget.phtml, lead-form.phtml, Conviro_AiChat/web/js/widget-loader.js, any Conviro_AiChat/layout/**, and any theme layout file that names the conviro.aichat.widget block or a Conviro_AiChat:: template (removing or re-adding the widget). The file scan is cached for an hour (cache:flush clears it).
| State | Meaning | Fix |
|---|---|---|
| Action | The override bypasses the module's loader: its own inline cw('init' snippet (the 1.3.x way), a CSP nonce in cacheable HTML, no module configuration block, no module loader, or a loader file of its own. The 1.4 fixes — no shopper data in cached pages, no nonce frozen into cached HTML — and every later loader change do not reach the store. | Remove the theme's Conviro_AiChat overrides (Details lists the files). Load the Chat Widget and Lead Form Placement (Widget Settings) now do what such overrides were for. Deploy static content, flush the caches, click Check storefront. |
| Warning | The override still renders the module's configuration and loader. It works, but template changes in module updates will not reach the store. | Remove it if it only defers the widget or hides the lead form. |
| Action / Warning | The last Check storefront found a problem (below). | Fix it, click Check storefront again. |
Check storefront (button on the card) makes one read-only GET of the default store view's home page — the public URL, as a visitor gets it, from Magento's full-page cache or Varnish if they answer — and of the widget loader file that page references. It checks: exactly one widget configuration block, carrying this store's widget key (otherwise the page is cached from before a change); exactly one module loader script, and that the file served is this release's loader (otherwise static content was not redeployed after the upgrade); nothing else starting the widget (an inline cw('init' or a direct widget.iife.js tag, e.g. a theme override or a pasted snippet — two widgets); at most one lead-form script. Nothing is sent to Conviro. If the server cannot reach its own public URL (some firewalls), the check says so.
Skipped events (shown only when relevant)
Warning when an observer skipped an event in the last 24 hours because preparing or queuing it failed (1.4.1). Every Conviro observer wraps its whole body: the order, checkout, cart or save it runs in always continues — a Conviro problem never becomes a checkout or payment error — and Conviro misses that one event. The row says how many, the last observer, exception class and time; the details are in var/log/system.log ("[Conviro] … event skipped", no personal data). Counted per hour in the flag table (conviro_observer_failures) and reported to the Conviro dashboard.
Store-wide bearer tokens (shown only when relevant)
Warning when Magento's own Allow OAuth Access Tokens to be used as standalone Bearer tokens (Stores › Configuration › Services › OAuth › Consumer Settings, oauth/consumer/enable_integration_as_bearer) is Yes while Conviro signs with OAuth 1.0a (Conviro's answer; the last Save Config when Conviro cannot be asked). 1.3.x switched it on for the whole store on every Save Config; 1.4.0 never changes it by itself, because another integration of yours may send its access token as a bare bearer token. While it is on, anyone who obtains the access token of any integration on the store can call the REST API with it, without an OAuth signature. Conviro does not need it.
Fix: the row's Turn off store-wide bearer tokens button (needs Conviro_AiChat::setup; asks for confirmation first; a POST with the admin form key) sets it to No at the default scope, the only scope Magento reads — or set it yourself on the page above. Check first that no other integration of yours authenticates with a bearer token; if one stops working, switch it back on there. The button changes nothing while Conviro still uses the legacy bearer connection (the Authentication row says so), and says so when a value in app/etc/env.php or config.php overrides the database. Not shown on the legacy bearer connection or without an API key.
Customer Experience & Identity (1.5.0, unreleased)
1.5.0 (unreleased), read 2026-09-27 on feat/magento-1.5.0-p34-module (Block/Adminhtml/Setup/IdentityCard.php, Service/Identity/IdentityCardView.php; not merged yet). What the feature does: Signed customer identity and My orders.
On this card — below the sync jobs, one line: Customer identity: off., Customer identity: on. or Customer identity: needs attention (…) with a link to the card and — Phase 5, branch feat/magento-1.5.0-p5-module — a link Why doesn't it work? (30-second runbook) that opens the runbook at this store's first failing gate. The reasons it can name: not connected, key not registered, Conviro backend without identity, key refused, key registration failed, PHP sodium missing, key rotation due, order listing permission missing. It reads only this store's facts (no call to Conviro).
The card is on Stores › Settings › Conviro Setup and at the top of Stores › Configuration › Conviro › AI Chat › Signed Customer Identity (beta). It renders even when Conviro cannot be reached; it never shows a secret, a customer or an order.
| Section | Shows | Source |
|---|---|---|
| First blocker (Phase 5) | the first line under the title: the first failing gate of the runbook's ordered list — connection, this store's switch, key, announcement, Conviro's switch, integration at Conviro, store view mapping, clock, then (while My orders is on) the My orders switch, OAuth, order permission, Conviro's My orders switch — with the fix and a runbook link; Nothing blocks… when all pass | this store at once; both sides once Conviro answered (Conviro's own firstBlocker, when its backend sends one, counts too) |
| Connection | Connected: Conviro signs its calls with Magento OAuth 1.0a / Degraded / Disconnected | the Integration Health facts above |
| Signed identity | the key state (below), the key id (public), when it was registered or replaced, Rotate identity key and — Phase 5 — Reset identity (the emergency rotation, after a confirmation; runbook) (both with Conviro_AiChat::setup), the key age and the rotation advice | this store |
| Permissions | only when there is something to fix: Order listing permission missing | this store (the integration's grant) |
| Features | Signed customer identity, Personalized greeting (display only), My orders, Order tracking (part of My orders), Guest verification, Return assistance (= Order-action assistance) — each off on every website or on for … | this store's switches |
| Store views | each store view, its website, signed identity and My orders on / off, and which orders a verified shopper sees there | this store |
| At Conviro | loaded after the page (admin AJAX, 3 s, cached a minute): whether Conviro switched the feature on for your workspace, whether it received the store's announcement, whether it holds this store's key (and whether it is the same key), the last successful verification and the last 24 hours (succeeded / failed, with the most frequent failure reason explained), My orders at Conviro, the server clock against Conviro's, and Conviro's store-view mapping next to this store's | GET /api/magento/identity-status; Phase 5: the clock also from the Date header of the module's other Conviro calls (clock) |
| Diagnostics | Test identity bridge for a chosen store view, with its step list | below |
Key state (the Signed identity line)
| State | Meaning | Fix |
|---|---|---|
| Off | Signed identity is off on every website. | Switch it on per website (how). |
| On, but no key is registered with Conviro yet | The switch is on; the key was not registered yet. | Save Config or Reconnect. |
| On. This store's public key is registered with Conviro | Good. | — |
| The Conviro backend does not support it yet | The key registration route answered 404: an older Conviro backend. Everything else works as before. | Wait for Conviro; nothing to change in Magento. |
| Conviro refused this store's key | The reason is shown (e.g. store URL in another workspace, store disconnected, a key of another installation). | Troubleshooting. |
| The key could not be registered | Network or server error; retried on the next save or Reconnect. | Save Config later; check the Connection row. |
| The PHP sodium extension is not loaded | This store cannot sign. | Install / enable ext-sodium for the PHP that runs Magento. |
Key age: "Key age: N days (since …)". From 180 days the card warns Keys older than 180 days should be rotated (policy set 2026-09-28); a key created before the module recorded its age shows unknown.
Order listing permission missing
Turkish admin: Sipariş listeleme izni eksik. Show verified shoppers their own orders is on, but the Conviro AI Chat integration does not hold the read permission A verified shopper's own orders (read) (Conviro_AiChat::api_customer_orders), so Conviro cannot list a signed-in shopper's orders — the shopper sees "Order details aren't available in the chat for this store" and the account-page link.
Fix: Repair access on the card (needs Conviro_AiChat::setup; an admin without it is told who can). It registers the store with Conviro again, which grants exactly the permissions the switches call for, then reads the grant back; if the permission is still missing it says so — then check the Conviro AI Chat integration under System › Extensions › Integrations and run bin/magento setup:upgrade if the Conviro_AiChat::api_customer_orders resource is unknown (it comes with 1.5.0). The same warning appears in the Conviro dashboard (Order listing permission missing in Magento), also when Magento refused one of Conviro's order reads with "not authorized".
When the integration cannot be read at all the card says Order listing permission: could not be read (reload; see the Authentication row).
Test identity bridge
Signs a synthetic assertion with this store's real key — audience conviro-widget-identity-test, subject synthetic-test, no customer, no binding row — and asks Conviro to verify it without creating anything (Conviro refuses such a token anywhere else, and a real assertion here). Needs Conviro_AiChat::config; Conviro allows 10 tests an hour per store. Steps:
| Step | Fails when | Fix |
|---|---|---|
| Store view found in this Magento | the chosen store view is gone | choose another |
| Signed customer identity is on for this store view's website | switched off there | switch it on for that website |
| This store signed a synthetic test assertion with its identity key | no usable key | switch it on and Save Config |
| Conviro answered | timeout, no connection, server error, API key refused, rate limit, the network protection in front of Conviro answered, an older backend | see the Connection row; try later |
| Conviro knows this store's key · The signature verifies · The issuer is this installation | a key Conviro does not hold, or another installation's | Save Config (registers again), or Rotate identity key |
| The test audience is accepted | — (Conviro-side check) | — |
| The store view is mapped at Conviro | the store view is not in Conviro's store mapping | select it in the setup wizard (step 4) and save |
| The server clock is in step with Conviro's | more than 30 s apart — every real assertion is then refused | synchronise the clock (NTP: timedatectl set-ntp true, chrony or ntpd) |
| Signed customer identity is switched on at Conviro | the platform flag is off | ask Conviro |
| The integration is active at Conviro | disconnected / inactive | Reconnect |
| My orders is open | My orders is off here or at Conviro | switch it on, or ask Conviro |
| Dry run: nothing was created at Conviro | Conviro reported that the test created something — it must never do that | tell Conviro support |
A green test proves the store's key, the mapping, the clock and Conviro's switches — not a real shopper's browser (the same-origin bootstrap). For that, sign in as a test customer and open the chat.
Sync jobs panel
Below the rows: each job type with its progress, counts, times, last error and stall / pause notes, and the buttons Re-sync inventory, Re-sync recent orders, Import customers (only if chosen), Repair failed items (Data sync).
Actions
| Button | Does |
|---|---|
| Setup wizard | Opens Stores › Settings › Conviro Setup (needs Conviro_AiChat::setup). |
| Test connection | Runs every check now, re-reads the latest version, and reports each row as an admin message. |
| Send test event | Queues and delivers a signed test.ping through the real path. |
| Retry failed | Re-queues dead and blocked events. |
| Re-sync catalog | Starts the catalog job (a second click while it runs does nothing). |
| Download diagnostics | Diagnostics bundle. |
| Turn off store-wide bearer tokens | Only in the Store-wide bearer tokens row: sets oauth/consumer/enable_integration_as_bearer to No after a confirmation (needs Conviro_AiChat::setup). |
Measured: admin-health.sh 32/32 on the local stack (3bb49b22); 42/42 with the Store-wide bearer tokens row and its button (2.4.7-p4 dev stack, 2026-09-26); page timings in Performance.