=== ShopSocket ===
Contributors: wpsignal, jaredrethman
Tags: woocommerce, abandoned cart, sales notification, wordsocket, realtime
Requires at least: 6.7
Tested up to: 7.1
Stable tag: 0.8.0
Requires PHP: 8.2
Requires Plugins: wordsocket, woocommerce
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

See your WooCommerce store live: orders as they land, who is shopping, carts and stock. Needs WordSocket and a WPSignal account.

== Description ==

ShopSocket shows your WooCommerce store as it happens. Think Shopify's Live View, for WooCommerce.

https://www.youtube.com/watch?v=BKwID6t_kpQ

**Requires** the [WordSocket](https://wordpress.org/plugins/wordsocket/) plugin and a [WPSignal](https://wpsignal.io/) account. Install WordSocket, click Connect ([video](https://www.youtube.com/watch?v=yS1roK49HEQ)), then install ShopSocket.

**Try it:** [shopsocket.wpsignal.io](https://shopsocket.wpsignal.io/) is a live demo store.

**For you and your team**

* Every order on screen the moment it is placed, with a chime
* Who is shopping right now, the pages that brought each of them to where they are, what is in their carts, and what it is worth, with a guest who has ordered before named as a best guess
* Which carts were left behind
* Which products are in carts right now
* Low-stock and sold-out alerts as they happen
* Full-screen mode for a wall display

**For your shoppers**

* Stock on product pages updates without a reload
* "X shoppers have this in their cart right now" under the price
* "Someone just added this to their cart" notices
* A Live Stock block for any page

Each shopper feature can be switched off site-wide, per category, or per product. All are on by default.

**What it does for your store**

*Never miss an order.* Every new order lands on the ShopSocket board the instant it is placed, with a chime, and its status updates in place as it moves along. Keep the board open on a second screen or a wall display and stop refreshing the Orders page.

*Know who is shopping right now.* How many people are on your store this minute, how many are holding a cart, what is in those carts, and what it is worth. Live means the shopper is on your site at this moment, not a guess from a timestamp.

*See which carts were left behind.* A cart turns abandoned the moment its shopper leaves, with the revenue still in it, so you know what walked away and when.

*Spot what is about to sell.* The products sitting in the carts of shoppers on your site, most held first, with the number of carts holding each, one click from the product's edit screen.

*Catch stock problems as they happen.* Low-stock and out-of-stock alerts reach the board at once, and the product page itself updates: the stock text changes and the add-to-cart button follows, with no reload. A shopper holding a product that sells out hears straight away, and their cart shows WooCommerce's own notice.

*Give undecided shoppers a nudge.* "3 shoppers have this in their cart right now" under the price, kept current as carts change, and a quiet "someone just added this to their cart" notice for shoppers holding the same product.

*Fits your theme.* The storefront features bind to the classic templates and to the Product Price and Product Stock Indicator blocks. The Live Stock block puts availability, units left, and the in-cart count anywhere you like.

**Where to find it**

The board is under WooCommerce > Analytics > Realtime (WooCommerce > ShopSocket when Analytics is switched off). Settings are on the ShopSocket tab of WordSocket's settings page, and each product has its own choices under Product data > ShopSocket.

**Disclaimer**

WPSignal is an independent service, not affiliated with or endorsed by Shopify. Shopify is a trademark of Shopify Inc., named only for comparison.

= Third-Party Service =

ShopSocket uses the **WPSignal service** (api.wpsignal.io), through the WordSocket plugin, to deliver live updates to the browsers on your store. When an order is placed or changes status, stock changes, or a product is added to a cart, WordSocket sends an encrypted event to WPSignal, which relays it to your store's open browsers. Events are not stored.

**What leaves your site, and who can read it.** Every event is encrypted before it leaves WordPress, with a key made from your site's own WordPress salts, which WPSignal never has. WPSignal relays what it cannot open: it never sees an order total, a customer name, a product, or a stock level.

Inside those encrypted events:

* Order events, visible to staff only: the order number, status, total, item count, payment method, and the customer's first name and last initial. No email, address, or line items.
* Stock and cart events, visible on your storefront: product names, links, thumbnails, and counts, plus an anonymous cart id so a shopper's own adds and purchases are never announced back to them.

What WPSignal does see, because it needs it to deliver messages: channel names, how many browsers are connected, and an anonymous id for each shopper's browser and cart. None of it is personal.

**What stays on your site.** ShopSocket keeps no table of its own. While WordSocket's History is on (its Journeys tab), each visit WordSocket keeps carries the cart it was made with: what it held, its value and the order it became, in your own database, for the months set there, linked to the shopper's account when they were logged in. With it off, nothing is kept beyond the WooCommerce session, and the board, the counters and this week's figures have nothing to show. A guest whose browser remembers the email of an earlier checkout offers it to your site once per visit; it is kept for two days only when that email has placed a paid order here, shown to staff flagged as a best guess, never sent to WPSignal, and covered by WordPress's privacy export and erasure by email.

* [Terms of Service](https://wpsignal.io/terms)
* [Privacy Policy](https://wpsignal.io/privacy)

= Source code =

ShopSocket is developed in the open at [github.com/wpsignal/wordsocket-extensions](https://github.com/wpsignal/wordsocket-extensions) under `shopsocket/`.

== Installation ==

1. Install and activate WooCommerce and [WordSocket](https://wordpress.org/plugins/wordsocket/).
2. In WordSocket's settings, click Connect to WPSignal and create an account ([video](https://www.youtube.com/watch?v=yS1roK49HEQ)).
3. Install and activate ShopSocket.
4. Open WooCommerce > Analytics > Realtime.

== Frequently Asked Questions ==

= What do I need? =

WooCommerce, the free [WordSocket](https://wordpress.org/plugins/wordsocket/) plugin (0.30 or later), and a [WPSignal](https://wpsignal.io/) account (the free plan is enough to start).

= Does it cost anything? =

ShopSocket and WordSocket are free. WPSignal has a free plan; paid plans for busier stores are at [wpsignal.io/pricing](https://wpsignal.io/pricing/).

= Is there a demo? =

Yes: [shopsocket.wpsignal.io](https://shopsocket.wpsignal.io/). Open a product in two browsers and add it to the cart in one. The demo shows the storefront; the board is in wp-admin.

= Does it work with block themes? =

Yes. For full control, add the Live Stock block to the Single Product template or any page.

= Does it work on a local site over plain HTTP? =

Yes.

= Does it support High-Performance Order Storage? =

Yes.

= Can I turn parts of it off? =

Yes. Site-wide switches and category exclusions are on the ShopSocket tab of WordSocket's settings page (WordSocket 0.29 or later). Each product has its own Default, On, or Off choice under Product data > ShopSocket.

Developers: `shopsocket_storefront`, `shopsocket_in_carts_enabled`, `shopsocket_activity_enabled`, `shopsocket_activity_throttle`, and `shopsocket_publish_stock` filters.

= What does cart history keep? =

Nothing of its own: carts ride on WordSocket's journeys. Switch on History on WordSocket's Journeys tab and every visit is kept there with the cart it was made with (its products, value, when the shopper left and the order it became) for the months you set. The board then lists recently abandoned carts and this week's figures, the counters count the carts, and WordPress's privacy tools export and erase it all with the journeys.

= Can it nudge a shopper? =

With WordSocket 0.31 or later, yes, through moments you set up on WordSocket's Moments tab: when the cart holds something and the shopper is on the cart page, show a prompt; when they hide the tab, remind them on return; and alert your team on the Realtime board. Nothing fires until you switch a moment on, and every prompt can be dismissed.

To offer a coupon, create it in WooCommerce with the limits you want (an expiry, a usage limit, one per customer), put its code in a synced pattern, and show that pattern with a moment. The Moments tab then tells you how many orders followed. The code is as public as one on a banner, so let the coupon's own limits do the guarding.

= Who can see the board? =

Anyone who can manage WooCommerce.

== Screenshots ==

1. The Realtime board under Analytics, before the first shopper arrives.
2. The board with a busy store: users online, live and abandoned carts with their revenue, the products in live carts, and orders as they are placed.
3. A product page: live stock, how many shoppers hold the product right now, and a toast when someone else adds it.
4. The cart at the moment a held product sells out elsewhere: WooCommerce's own notice appears without a reload, with ShopSocket's alert beside it.
5. The Live Stock block on an ordinary page: availability, units left, and the in-cart count, all live.

== Changelog ==

= 0.8.0 =
* New: the board's Right now card draws where each shopper came from: their route through your pages this visit, ending where they are now, with a hidden tab's route dotted and the page they are on pulsing.
* A shopper with several tabs open is one row, every tab's page listed and a hidden tab's in a dashed border, and one shopper on the diagram with a route per tab, lit together when hovered.
* The board's Right now figures are two cards: Shoppers on the site, with a bar showing how many are looking or on a hidden tab and what their carts are worth, and the top pages and top products in carts this minute.
* The shoppers table and the routes diagram on the board are two tabs: Shoppers and Journeys.
* New: the board's Abandoned carts card keeps everything about a cart left behind in one place: how many were left and not ordered since and what they are worth, where shoppers leave from, the carts left with the order when one followed, and the products left most often. The figure is shown for the last 24 hours, 48 hours and 7 days side by side, and choosing one sets the time frame for the rest: the carts still left, the carts an order recovered, the products left most often and the pages shoppers most often left from, each under a line saying what it lists. A guest there is named the way the shoppers table does: by the email their browser remembers, once it matches a paid order.
* Each low or out of stock product is a notice of its own on the board, and every notice can be dismissed.
* A new order is an alert at the top of the board too, and the alerts minimize to a count beside the Live badge.
* The board's sound switch is a speaker icon that shows at a glance whether a new order chimes.
* Live orders lists the orders placed in the last 24 hours, so the board stays on what is happening now.
* New for developers: `wp shopsocket journeys seed` fills a test site with made-up shopper journeys and carts, and `wp wordsocket journeys unseed` removes them.
* New: a guest whose browser remembers the email of a past checkout is named on the board as a best guess, with the billing name and how many paid orders that email has placed here, once the email matches; the guess is kept for two days and WordPress's privacy tools export and erase it by email.
* A shopper moving between pages no longer costs the server a request: the storefront remembers their cart for the visit and asks again only when it changed.
* New: with WordSocket 0.31, the Moments tab knows the shop. Conditions on the cart (items, count, total, a product, a category, whether the product on the page is in it) and the WooCommerce pages, and one action: alert your team on the Realtime board
* New: one moment ships switched off, listed on WordSocket's Moments tab: a shopper who hides the tab with a cart sees the tab title flash and, on return, a banner naming what is waiting
* New: with history on, the journeys record which moments fired, and the Moments tab can replay a moment over them before you switch it on; a moment that fires right after a shopper's first add to cart is recorded too
* Nothing changes on WordSocket 0.30: the rules pieces load only when the engine is there
* Faster pages on WordSocket 0.31: the shopper's cart state comes back in the visit report WordSocket already sends, so a page load makes one request instead of two; the cart-id route still serves cart changes and reconnects. A visitor without a cart makes none at all, since there is nothing to record for them yet.
* New: on WordSocket 0.31, the Moments tab shows what each moment has done over your stored journeys, orders included, beside the builder.
* New: the journeys of logged-in shoppers are linked to their account, so the Abandoned carts card and a staff alert name the customer with a link to their profile; WordPress's privacy tools export and erase those journeys with the carts. The `shopsocket_cart_left` hook tells other plugins when a cart is first left behind, with its items and its customer, so your email plugin can send the reminder.
* Carts are WordSocket's journeys now: switch on History on its Journeys tab and every visit is kept there with the cart it was made with, so that tab's visuals show orders a day, carts left behind a day and where carted shoppers leave from, and the board's leak sentence links straight into them. ShopSocket keeps no table of its own any more: the cart tables, the days setting and its own privacy exporter are gone (the carts go out and away with WordSocket's journeys), the "in carts" counter counts the carts History keeps and so needs it on, and the shopper's cart reaches their journey through WordSocket's own visit report, one request a page.
* New: the board opens with the last 24 hours when history is on, each figure against its average day over the last seven and drawn day by day: sales, carts left behind and what they hold, orders recovered after a moment fired and checkout conversion.
* With history on, an order is credited to the moments that fired for that cart in the past week, even when the shopper came back later in a new visit, and each firing records how far into its page it happened, whether the shopper came back to the tab, dismissed the prompt or clicked something inside it.
* WordSocket's Journeys tab warns when your site has no persistent object cache, since with history on every page a shopper with a cart opens writes to the database; Redis or Memcached is recommended on a busy store.
* New: the Realtime board lists every shopper on the site with the page they are on, what their cart holds and whether their tab is hidden; a logged-in shopper is named with a link to their profile. A search shows as "Search", never what was searched for.

= 0.7.0 =
* New: cart history. Switch it on under ShopSocket settings to keep each cart's products, value, when the shopper left and whether it became an order, for the days you choose, and shoppers' page journeys for the months you choose. Off by default; off keeps exactly what earlier versions kept
* New: the board lists recently abandoned carts, and says how many shoppers and carts are "away" (every tab hidden) rather than gone
* New: a WooCommerce privacy exporter and eraser for the history, and the tables are removed on uninstall
* Changed: cart rows live in tables of their own instead of a transient, so two shoppers adding at the same moment no longer overwrite each other
* Requires WordSocket 0.30, whose visitor tracking carries the journeys (0.31 since ShopSocket 0.8, which keeps them)

= 0.6.0 =
* New: the board's Storefront Customers and Open Tabs figures say how many of them are your own staff
* Changed: the settings switches are labelled by what they show, the category exclusion is "Except in these categories", and its picker lists every category when clicked
* Changed: the settings tab confirms a save with a toast at the bottom of the screen, and now needs WordSocket 0.29

= 0.5.1 =
* Fixed: an order placed while the board's own connection was down did not appear until the page was reloaded. The board now catches up on missed orders and status changes when it reconnects, when you return to its tab, and on its regular refresh

= 0.5.0 =
* New: a ShopSocket tab on WordSocket's settings page (WordSocket 0.28 or later) with site-wide switches for the in-cart count and the added-to-cart notification, each with its own list of product categories to exclude
* New: a per-product choice for each feature under Product data > ShopSocket: Default, On, or Off. On and Off win over the site setting and the categories
* New: the in-cart count speaks to a shopper who holds the product: "You have this in your cart right now", "You and 1 other shopper have this in your carts right now". The `woo.cart.removed` event now carries the remover's anonymous cart id
* Changed: switching the toasts off no longer stops the cart-added event, which the in-cart count needs; the event now carries an `activity` flag and the storefront shows no toast when it is false. A product with both features off publishes nothing

= 0.4.0 =
* "Basket" is now "cart" everywhere: on the board, in this readme, and in the code. Breaking if you listen to the relay directly: the `woo.baskets` event is now `woo.carts`, `GET /shopsocket/v1/basket-id` is now `/cart-id`, and the `shopsocket_baskets` transients are now `shopsocket_carts`
* Fixed: the storefront stylesheet was left out of the release package, so the in-cart counter's dot and update flash never showed on installed sites
* Storefront scripts are versioned by their contents, so an update reaches browsers that cached the previous build
* The board holds a lower Open Tabs figure for a few seconds before showing it, so a shopper moving between pages no longer reads as a tab closing and reopening

= 0.3.2 =
* Fixed: the extension registered its name and description before WordPress loads translations, which logged a notice with debugging enabled

= 0.3.1 =
* Fixed: a shopper who buys the last unit is no longer told it has sold out (stock events now carry the buyer's anonymous cart id)
* Fixed: the board's logo no longer flashes at full screen width before its styles load
* The readme spells out what leaves your site and what the relay can read

= 0.3.0 =
* The plugin is listed under WordSocket on the Plugins screen, where WordSocket 0.24 and later keep the family together

= 0.2.1 =
* Requires WordSocket 0.23: the visitor id and channel check now come from WordSocket
* Fixed: the Live Stock block's in-cart count was missing on load on pages other than the product's own
* Works on plain HTTP sites


= 0.2.0 =
* First public release
* The Realtime board under WooCommerce Analytics: users online, live and abandoned carts from relay presence, products in live carts with units, and live orders that update in place
* Live stock on product pages, the shop, and the cart: availability text, add-to-cart buttons, quantity limits, and "N shoppers have this in their cart"
* Sell-out notices: a shopper holding a product that sells out hears at once, and the cart shows WooCommerce's own notice without a reload
* "Someone just added this to their cart" toasts, shown only for products the shopper also holds
* The Live Stock block for the Single Product template or any page
* A card on WordSocket's Extensions tab

== Upgrade Notice ==

= 0.8.0 =
Needs WordSocket 0.31. ShopSocket's cart tables are dropped on update: carts now live on WordSocket's journeys, so switch on History on WordSocket's Journeys tab to keep carts, see the board's figures and count carts on product pages.

= 0.7.0 =
Needs WordSocket 0.31. Cart history is off by default; switch it on under the ShopSocket tab when you want carts kept, and WordSocket's History on its Journeys tab for the journeys.

= 0.6.0 =
The ShopSocket settings tab now needs WordSocket 0.29; the board and storefront are unaffected.

= 0.5.1 =
The board catches up on orders placed while its connection was down.

= 0.5.0 =
Adds the storefront settings. Update WordSocket to 0.28 first to see the new ShopSocket tab.

= 0.4.0 =
Breaking for direct relay listeners: `woo.baskets` is now `woo.carts` and `basket-id` is now `cart-id`. Everything else is a fix.

= 0.3.2 =
Fixes a premature translation notice logged with debugging enabled.

= 0.3.1 =
Fixes a sold-out notice shown to the shopper who bought the last unit.

= 0.3.0 =
The plugin is listed under WordSocket on the Plugins screen, with WordSocket 0.24 and later.

= 0.2.1 =
Requires WordSocket 0.23: the visitor id and channel check now come from WordSocket

= 0.2.0 =
First public release.
