=== MerQio Connector ===
Contributors: storeboost
Tags: woocommerce, analytics, ai, sync, abandoned-cart
Requires at least: 6.0
Tested up to: 6.7
Requires PHP: 7.4
WC requires at least: 7.0
WC tested up to: 9.4
Stable tag: 1.13.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Connects a WooCommerce store to MerQio AI. A thin connector — all intelligence lives in the MerQio SaaS.

== Description ==

MerQio Connector streams your store's activity to MerQio AI in real time so
you get AI-powered segmentation and recommended actions without any manual export.

It is intentionally *thin*: it stores no business data locally (only its encrypted
connection secret), runs no analysis, and never edits your store. It simply relays
signed signals.

**What it sends (signed with HMAC-SHA256):**

* Products — created / updated / deleted
* Orders — created / status changed / refunded
* Customers — created / updated
* Abandoned carts — detected after 60 minutes of inactivity, plus recovery
* Store name / Site Icon / pages — changed (a signal only; nothing about them is sent)

For products, orders, and customers only the entity id + event type are sent; the
MerQio SaaS then re-fetches the authoritative record from the WooCommerce REST
API (the "webhook-as-signal" pattern). Abandoned carts are the one exception — since
WooCommerce has no cart REST endpoint, the cart contents travel in the event itself.

**Reliability:** failed deliveries are queued locally and retried with capped
exponential backoff via WP-Cron; the SaaS reconciliation job is the final safety net.

== Installation ==

1. Install and activate the plugin (WooCommerce must be active).
2. In WordPress, open **MerQio** in the admin menu and press **Connect Store**.
3. MerQio opens in a new tab. Sign in (or create an account), choose your
   plan, and approve the connection on your own store when WooCommerce asks.
4. Come back to the plugin screen: it shows **Store Connected** by itself.

There are no keys to copy. MerQio sends the plugin its settings directly,
authenticated by the WooCommerce key you approved.

For troubleshooting, add `define( 'SB_CONNECTOR_DEBUG', true );` to wp-config.php
to write a diagnostic log under wp-content/uploads/storeboost-logs/ (it never
contains secrets).

== Security ==

* The webhook secret is stored encrypted (AES-256-CBC, keyed by the site's auth salts),
  and is never shown or typed anywhere.
* Every payload is HMAC-signed; the SaaS rejects unsigned or tampered requests.
* HPOS (High-Performance Order Storage) compatible.
* All admin actions are nonce-protected and require the `manage_woocommerce` capability.

== Changelog ==

= 1.13.1 =
* MerQio now has its own menu in wp-admin, just below WooCommerce and
  Products, with the MQ mark as its icon, instead of sitting inside the
  WooCommerce menu. The page address is unchanged, so links and bookmarks to
  it still work.

= 1.13.0 =
* StoreBoost is now MerQio. The plugin is called MerQio Connector, and the
  screen, the feature tour and every message carry the new name and the new
  MQ mark.
* Nothing to redo: the plugin's folder, its settings and the store's
  connection stay exactly as they were, so a connected store stays connected
  through the update.

= 1.12.3 =
* Fix: after a click, Connect Store and Open MerQio no longer turn square
  with a blue border and dark text (WordPress's own link focus style won over
  the button's). They keep their look; keyboard focus still shows a ring.

= 1.12.2 =
* The feature tour shows more of MerQio, still with example data:
  - Store Assistant: after the chat, its overview counts the conversations,
    messages, add-to-carts, unanswered questions and chat-assisted revenue,
    draws the conversations chart and lists the demand gaps.
  - Customer segments: a customer moves from Active to At risk, AI suggests a
    win-back email, it is approved, and she comes back to Active after ordering
    again. Then a custom segment is built condition by condition while the
    count of matching customers narrows to 214.
  - StoreBrain: a second question, which one-time customers to win back and
    how, answered with what they bought first.
  Each scene keeps the stage's height at every width, pauses, and respects
  "reduce motion".

= 1.12.1 =
* The Store Assistant scene of the feature tour now starts in MerQio's
  Store Assistant settings: a character is picked, then an AI icon, and saved --
  and the storefront assistant then answers wearing that face. Example data, as
  before; it pauses and respects "reduce motion" like every other scene.

= 1.12.0 =
* New: a feature tour beside Connect Store. Nine short animated scenes show what
  MerQio does -- Store Assistant, customer segments, StoreBrain, actions and
  outcomes, cart recovery, email campaigns, email templates, product feeds and
  reports. It is example data for a made-up store: nothing is read from your
  store and nothing is loaded from elsewhere.
* It pauses with its pause button, while the pointer is over it, while it is
  scrolled out of view and while the tab is hidden. With "reduce motion" turned
  on, each scene is shown finished and nothing moves on by itself. The feature
  chips work with the arrow keys.
* Connected stores get an "Open ... in MerQio" link under each scene. It
  opens that page for THIS store, even when you have several stores in
  MerQio (requires the MerQio app release that understands it).
* The screen is now two columns on wide screens and one on narrow ones.

= 1.11.0 =
* New: a single, redesigned screen under WooCommerce > MerQio AI -- "Store
  Not Connected Yet" with a Connect Store button, or "Store Connected" with when
  data was last sent, an Open MerQio button and Disconnect. It turns to
  Connected by itself once you finish connecting in MerQio's tab.
* Removed: the settings tabs (Connection, View Tracking, Recommendations, Store
  Assistant), the form for typing a webhook URL and secret by hand, and the test
  event. Event sending, product-view tracking and the recommendation order are
  always on, and a cart counts as abandoned after 60 minutes. Values saved on the
  old tabs are deleted once on update.
* Changed: Debug mode is no longer a setting. Define `SB_CONNECTOR_DEBUG` as true
  in wp-config.php to turn the diagnostic log on.
* Connect Store also repairs a store MerQio already has -- after the plugin
  was reinstalled, installed after connecting, or disconnected here: MerQio
  sends the plugin its settings again. Update MerQio before this plugin.
* New: removing a store in MerQio (or deleting the MerQio account) now
  disconnects this plugin too, so it stops sending and the storefront assistant
  stops loading. MerQio tells the plugin directly; if your site could not be
  reached at that moment, the plugin disconnects itself on its next delivery.
  The screen then says the store was removed, and Connect Store starts over.
* Changed: Disconnect also stops the storefront assistant and drops deliveries
  still waiting to be retried. Connecting again restores everything.

= 1.10.0 =
* New: publishing, renaming, moving, unpublishing or deleting a page now
  reaches MerQio straight away, so the pages you can choose in MerQio's
  Store Assistant settings are always the ones your shop has. As with the site
  title, the connector only says that something changed -- MerQio reads the
  list of published pages from your site's public address.
* Changed: where the Store Assistant appears -- the pages it stays off, whether
  it shows on phones, and whether it is on -- is now set in MerQio under
  Settings > Store Assistant, not in this plugin. The assistant tab here points
  you there. The choices you had made in this plugin are sent to MerQio
  once, and are obeyed until they arrive, so the assistant does not come back
  on a page you hid. It is still never shown at checkout.
* Update MerQio before this plugin on a site that had hidden pages or turned
  the assistant off: the one-time hand-over is only understood by the current
  MerQio.

= 1.9.0 =
* New: changing your timezone in Settings > General now reaches MerQio
  straight away, so "today" and every daily report follow your store's clock
  from that moment instead of within a day. Both a city timezone and a manual
  UTC offset are watched. As with the site title and icon, the connector only
  says that something changed -- MerQio reads the timezone from your site's
  public address.

= 1.8.0 =
* New: changing your site title or Site Icon now shows in your MerQio
  dashboard straight away, instead of within a day. The connector tells
  MerQio that something changed -- it sends neither the name nor the icon,
  which MerQio reads from your site's public address as before. Saving a
  settings page without changing either sends nothing.

= 1.7.2 =
* Fixed: the Store Assistant now survives speed and caching plugins. Options
  like "delay JavaScript until user interaction" hold every third-party script
  until somebody clicks, which for a chat widget means it is simply never
  there -- with no error, and nothing in your console to explain it. The
  connector now marks its own script as one to leave alone, in the way each of
  the common optimisers expects, and registers itself in their exclusion lists
  where they keep one. It touches none of your other scripts.
* Fixed: two copies of the assistant could appear on pages built by some page
  builders, which run scripts twice.
* The assistant's address is now written in two places on the page, so an
  optimiser that removes one of them no longer leaves an empty corner.
* New: with Debug mode on, the assistant explains in the browser console why it
  did not appear -- switched off, unreachable, or its settings stripped from the
  page. With Debug mode off, which is the default, it stays completely silent.

= 1.7.1 =
* Fixed: the Store Assistant never appeared on the storefront. It was loaded as
  an ES module, and a browser always fetches those under cross-origin rules --
  so every shop was refused the file and reported it only in the developer
  console. It is now a plain script, which needs no such permission. This also
  removes the import-map ordering hazard that made 1.7.0's loading order
  matter: a plain script takes no part in that mechanism, so block cart and
  block checkout cannot be affected by it on any WordPress version.
* Fixed: connecting or reconnecting from the MerQio dashboard now
  configures this plugin as well. Previously only the WooCommerce approval
  screen did, so a store connected any other way stayed unconfigured with no
  way to repair it from either side.
* Fixed: "Manage in MerQio" now opens the deployment your store is actually
  connected to, instead of a fixed address that may not hold your data.
* Fixed: the Store Assistant panel said your plan did not include the assistant
  whenever it had no settings, even when the real reason was that MerQio
  had never sent them. It now tells those two apart.
* Security: the webhook address MerQio sends must be https, except on
  loopback and private networks where a developer needs plain http.

= 1.7.0 =
* New: the Store Assistant appears on your storefront. Shoppers can ask about
  products and add them to the cart from the conversation -- the cart goes
  through WooCommerce's own Store API, so your theme, coupons, taxes and
  shipping behave exactly as they always did.
* The widget is loaded as an ES module through the Script Modules API on
  WordPress 6.5+, so WordPress prints it after its own import map. Without that
  ordering, block cart and block checkout break in Firefox and older Chrome.
* New "Store Assistant" settings tab: whether to show it, whether to show it on
  mobile, and pages to hide it on. It is never shown on checkout. Its name,
  greeting and colour are managed in MerQio so a change reaches shoppers
  immediately rather than waiting for a page cache.
* Orders placed after a conversation carry it, on BOTH the classic and the block
  checkout, so a sale can be traced back to the chat that led to it.

= 1.6.0 =
* New: one-click connect. Approving MerQio through WooCommerce's own
  authorisation screen is now the whole setup. MerQio sends the webhook URL
  and secret straight to this plugin over the authenticated channel the approval
  opened, so neither value is ever displayed, copied or pasted by hand.
* The receiving route lives in the `wc-storeboost/v1` namespace and is
  authenticated by WooCommerce with the merchant's own API key; it requires the
  `manage_woocommerce` capability, the same one needed to approve the connection.
* The settings screen still accepts a webhook URL and secret typed by hand, for
  stores that cannot complete the redirect.

= 1.5.0 =
* Fixed: on stores running WooCommerce Subscriptions, every new subscription was
  being relayed to MerQio as if it were a customer order. A subscription is a
  registered WooCommerce order type, so creating one fires the same hook a real
  order does — and MerQio stored it, giving the store phantom orders with
  statuses like "active" that no order can have.
* The connector now relays only the order types WooCommerce itself relays,
  reading that boundary from WooCommerce rather than keeping its own list. An
  extension that adds a further order type is handled exactly as its author told
  WooCommerce to handle it.
* New: subscriptions are now relayed on their own signal instead of being lost.
  A subscription starting, changing status, or having its next payment
  rescheduled reaches MerQio as it happens — so a failed renewal payment
  shows up when it fails, not whenever something else happened to touch the
  record.
* Works under both WooCommerce order storage modes (legacy and HPOS).
* No effect on any store without WooCommerce Subscriptions.

= 1.4.0 =
* Cross-sells and upsells now appear in the order MerQio ranked them, instead
  of the random order WooCommerce uses by default. With only two cross-sell slots
  on the cart page, a store with five of them was showing any given one about two
  times in five — so the pair the data actually supports was missing from the page
  more often than it was on it.
* Only the ORDER changes. Which products appear, and WooCommerce's own visibility
  and stock rules, are untouched.
* Off-switch on a new Recommendations tab, with the current state shown plainly —
  including "enabled, but the store is not connected", so a ticked box never sits
  beside a storefront that is still randomising.

= 1.2.0 =
* One-click cart restore. A recovery email can now carry a link that rebuilds the
  exact cart the shopper left — the right variants, the right quantities — and
  drops them straight on checkout, instead of returning them to the front page to
  start again.
* The checkout comes back already filled in with whatever they had typed, and if
  the email carried an offer, the coupon is already applied. Nobody is asked to
  copy a code out of an email.
* Both are done through the WooCommerce customer object and cart, which is the
  one place the classic checkout and the block checkout both read from — so it
  works on either without depending on any field id or markup.
* The link is HMAC-signed with the existing webhook secret and expires, so an
  edited or forwarded-months-later URL simply does nothing. The coupon code
  travels inside that signature, so it cannot be swapped for a bigger discount by
  editing the URL.
* Items that sold out or were deleted since the cart was recorded are skipped
  rather than failing the whole restore, and prices are always taken fresh from
  WooCommerce, never from the recorded row.
* Checkout capture now records the full billing address, not just name and phone,
  and no longer stops sending once the email has been seen — previously anything
  typed after the email address was never captured.

= 1.1.1 =
* Carts now carry the shopper's WordPress user id when they were signed in.
  Without it the SaaS could only guess at who a shopper was from whether a
  matching customer record existed — which labelled signed-in staff, and
  registrants who had never ordered, as guests.

= 1.1.0 =
* Cart recovery groundwork. The checkout page now relays the shopper's email as
  soon as it is valid, so a guest who abandons at the shipping step is still
  reachable — previously only logged-in shoppers were.
* Fixed: emptying a cart left it marked abandoned for good. The sweep only
  revisits active carts and recovery only fires at checkout, so nothing ever
  took it back. Emptying now relays `cart.cleared` and drops the local row.
* A recovered cart's local row is now removed once relayed: the cart table is a
  buffer, not an archive.
* Cart contents carry the chosen variation, so a recovery link can rebuild the
  exact variant rather than the parent product.

= 1.0.0 =
* Initial release: signed product/customer/order relay, abandoned-cart tracking,
  WP-Cron retry queue, encrypted credential storage, HPOS compatibility.
