=== ReplyPlex ===
Contributors: replyplex
Tags: support, helpdesk, edd, woocommerce, fluentcart
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Show a customer's orders and licenses inside ReplyPlex, and move an existing helpdesk's ticket history across when you switch.

== Description ==

This plugin connects your WordPress site to [ReplyPlex](https://replyplex.com) for commerce
context, helpdesk migration, and an optional customer portal.

= Commerce context =

Support agents answering "where is my licence?" or "was I charged twice?" normally have two
tabs open: the helpdesk and the store. This plugin closes the second one.

It adds a small, authenticated REST endpoint to your site. When an agent opens a ticket in
ReplyPlex, ReplyPlex calls that endpoint with the customer's email address and shows what
comes back — orders, subscriptions and licenses — beside the conversation.

It auto-detects and supports:

* **Easy Digital Downloads** — purchases, licenses (EDD Software Licensing) and subscriptions (EDD Recurring)
* **WooCommerce** — orders, and subscriptions via WooCommerce Subscriptions
* **FluentCart** — orders, and licenses via FluentCart Pro

The commerce endpoint answers requests authenticated with your API key and reads your
store live each time. It does not run a background sync.

= Customer portal (requires ReplyPlex portal activation) =

The Portal tab is off by default. When your ReplyPlex workspace has an active portal,
approve this site's exact HTTPS origin and WordPress connection there, then copy its
portal URL and IDs into Settings → ReplyPlex → Portal. Add the ReplyPlex portal or ticket
form block, or use [replyplex_portal] or [replyplex_ticket_form].

Enabling this feature embeds the configured ReplyPlex portal. For a signed-in visitor,
the plugin sends that visitor's WordPress user ID, email address, site URL and a short-lived
signed proof from your server to the configured portal to request sign-in. The API key
stays on your server. Customers verify their email once before linking their WordPress
account; later visits sign in automatically while that link remains valid. Guests use an
email code. Revoked site trust or changed identity credentials require fresh verification.

Only enable a portal you trust. Disable the feature here to remove its embeds; remove
site trust in ReplyPlex as well to revoke existing portal sessions.

ReplyPlex admins can separately select this store for the optional product/licence
selector on new tickets. The server looks up the customer's verified email and returns
only product names and order/licence references from WooCommerce, EDD or FluentCart.
Licence keys, payment details, activation sites and store-admin links are not included.
Customers can still submit a ticket if a store is unavailable or a product is missing.

= Moving your ticket history =

If you already run a helpdesk on this site and are moving to ReplyPlex, the plugin can hand
over its history — tickets, replies, internal notes, customers, agents, tags, custom fields
and attachments, keeping the original dates and authors. Losing years of past tickets is the
usual reason teams put off switching, so it does not have to happen.

Currently supported: **Fluent Support**.

This half is **off until you switch it on**, and deliberately hard to leave on by accident:

* The export endpoints are not registered at all unless a supported helpdesk is detected.
* You open the window yourself, from Settings → ReplyPlex.
* It uses a **separate key** from the commerce API key above, so the key your store is
  connected with cannot read your ticket archive.
* The window **closes itself after 30 days**, and destroys its key when it does.

Export is read-only. Nothing on your site is changed, moved or deleted, and your existing
helpdesk keeps running throughout — you can import first and switch over afterwards.

= You need a ReplyPlex account =

This plugin is one half of a pair and does nothing on its own — it is the store-side
connector for [ReplyPlex](https://replyplex.com), a hosted customer-support platform. Without
a ReplyPlex workspace to call it, the endpoint simply sits there.

== External services ==

This plugin does not send data to any external service. It is the receiving end: the
ReplyPlex application connects **to your site**, and only with the API key you generate.

What that means in practice:

* **Who can call it:** anyone holding the API key from Settings → ReplyPlex. In normal use
  that is your ReplyPlex workspace, because that is where you pasted it.
* **What it returns:** for the email address in the request — the customer's recent orders,
  licenses and subscriptions from the carts listed above, plus their WordPress display name.
  It returns nothing at all for an address with no purchases.
* **When:** only on request. There is no schedule, no background job and no outbound call.
* **How to stop it:** revoke the key on the settings page. The endpoint immediately refuses
  every request. Deleting the plugin removes the key entirely.

ReplyPlex's own handling of the data it fetches is covered by its
[terms of service](https://replyplex.com/terms) and
[privacy policy](https://replyplex.com/privacy).

== Installation ==

1. Install and activate the plugin.
2. Go to **Settings → ReplyPlex** and generate an API key.
3. In ReplyPlex, open **Manage → Integrations**, add a connection, and paste the Site URL and
   API key.

The settings page lists which of your carts were detected, so you can confirm the right one
was found before connecting.

To move an existing helpdesk's history across, the same settings page has a **Migrate history
to ReplyPlex** section — it appears only if a supported helpdesk is found. Open the export
window there, paste the migration key into ReplyPlex, and close the window when the import
finishes.

== Frequently Asked Questions ==

= Does this send my customer data to ReplyPlex? =

Not on its own — it never initiates a connection. It answers when ReplyPlex asks, one
customer at a time, and only for a request carrying your API key. Nothing is copied or
mirrored: every answer is read live from your store.

= What happens if I revoke or regenerate the key? =

The old key stops working instantly. Regenerating also invalidates the old one, so paste the
new value into ReplyPlex or the sidebar will show a connection error.

= Do I need EDD, WooCommerce or FluentCart? =

Yes — one of them at least, otherwise there is nothing to report. The settings page tells you
which were detected. If none are, the plugin stays quiet rather than erroring.

= Will this slow down my store? =

No. Nothing runs on page loads, on cron, or for your visitors. The endpoint does work only
while answering a request, and the queries are deliberately lean: rows are capped, customers
are resolved by indexed lookup first, and per-order line items are not fetched.

= Does it work on multisite? =

Yes. Each site in the network has its own key and its own connection.

= Where is the data actually shown? =

In the ReplyPlex conversation sidebar, next to the ticket the agent is reading.

= Does the history export change my existing helpdesk? =

No. It only reads. Your helpdesk keeps running exactly as before, during the export and
after it — nothing is edited, moved, marked or deleted. If you decide not to switch, there is
nothing to undo beyond closing the window.

= What if I forget to close the export window? =

It closes on its own after 30 days and deletes its key at the same time. You can close it
earlier from the settings page, and re-opening later always mints a fresh key rather than
reviving the old one.

= Can the commerce API key read my tickets? =

No. History export uses its own key, and neither key works on the other's endpoints. That is
the point of separating them: the commerce key is long-lived and held by ReplyPlex, while the
migration key exists only for the length of one migration.

== Privacy ==

The plugin stores its own settings in your site's options table and nothing else: the API
key, plus — only while an export window is open — a migration key and its expiry time. It
creates no tables, writes no logs, sets no cookies and does not profile anyone. Uninstalling
deletes all of them, on every site of a multisite network.

== Security ==

* Every endpoint requires `Authorization: Bearer <key>`, verified in constant time.
* Keys are generated with WordPress's own CSPRNG and can be regenerated or revoked at any
  moment from the settings page.
* Commerce and history export use **separate keys**, and neither is accepted on the other's
  endpoints.
* The history-export endpoints are registered only when a supported helpdesk is detected,
  refuse every request while the window is closed or expired, and are read-only.
* Attachment downloads are confined to your uploads directory, so a malformed file path in
  the helpdesk's own records cannot be used to read anything else.
* Only URLs on `http`/`https` are ever included in a response, so a link recorded by a cart
  plugin cannot carry an unexpected scheme through to the agent's browser.

== REST API (replyplex/v1) ==

Commerce, authenticated with the API key:

* `GET /wp-json/replyplex/v1/ping` — verify the connection; reports detected carts and helpdesks.
* `GET /wp-json/replyplex/v1/customer?email=<email>` — normalized commerce context.

History export, authenticated with the migration key and only while the window is open:

* `GET /wp-json/replyplex/v1/migration/meta` — what is here to migrate, and how much of it.
* `GET /wp-json/replyplex/v1/migration/export?entity=<entity>&after_id=<id>` — one page of records.
* `GET /wp-json/replyplex/v1/migration/attachment/<id>` — one attachment's contents.

== Changelog ==

= 1.0.0 =
* First public release: EDD, WooCommerce and FluentCart commerce context for ReplyPlex, served over an API-key-authenticated REST endpoint.
* Optional customer portal and ticket-form blocks/shortcodes, with mailbox-verified WordPress sign-in.
* Separate authenticated product/licence references for the customer portal's optional ticket selector.
* The commerce card carries a link to the customer's profile in the store's own admin, and each EDD licence carries its pre-filled renewal checkout link (EDD).
* A ReplyPlex agent with permission can deactivate a single site from an EDD licence without leaving the ticket. The endpoint exists only when EDD Software Licensing can do it, is idempotent, and every use is recorded as a note on the ReplyPlex conversation.
* Move an existing helpdesk's history to ReplyPlex — tickets, replies, notes, customers, agents, tags, custom fields and attachments, with their original dates and authors. Supports Fluent Support. Read-only, off by default, uses its own key, and closes itself after 30 days.
* Upgrading from a hand-installed build: your API key still works and no reconnection is needed. This release adds multisite-aware cleanup on uninstall, a fully translatable admin screen, and restricts emitted links to http/https.

== Upgrade Notice ==

= 1.0.0 =
First public release, including optional customer portal embedding and product references. Existing connections keep their keys. Portal activation and store selection are configured separately in ReplyPlex.
