=== Klaviyo Connector for WooCommerce ===
Contributors: catcodestudio
Tags: klaviyo, email marketing, abandoned cart, newsletter, woocommerce
Requires at least: 6.2
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

WooCommerce events, profiles and newsletter consent to Klaviyo: sent from the server in the background, without duplicates, with one API key.

== Description ==

Klaviyo flows (abandoned cart, browse abandonment, thank-you and win-back) are only as good as the events they receive. This plugin sends them from WooCommerce itself, through the official Klaviyo API, in the background — the checkout never waits for Klaviyo.

= Free =

* Connection with one private API key (stored encrypted, never logged). "Check the connection" reads the account and fills in the public key (Site ID); lists load for the dropdowns.
* klaviyo.js on the storefront (Klaviyo sign-up forms and onsite tracking), one small deferred script, nothing in wp-admin. Optional wait for cookie consent: WP Consent API (Complianz, CookieYes, Cookiebot and others), Cookiebot, Complianz, or your own banner calling ccKlaviyo.grantConsent().
* Viewed Product and Recently Viewed Items; Added to Cart from the product page, AJAX buttons and the block cart (Store API) — with the whole cart and a cart restore link.
* Started Checkout as soon as the shopper finished typing a valid e-mail (classic and block checkout; never on each keystroke, so no half-typed profiles) or is logged in. Once per cart and e-mail; a changed cart is a new Started Checkout. CheckoutURL rebuilds the cart — products, variations, quantities, coupons — in any browser and goes to the checkout.
* Placed Order and one Ordered Product per line, from WooCommerce order hooks (not webhooks): once per order, whatever the payment gateway does. You choose which statuses count as placed — custom ones included ("awaiting COD confirmation"). The value is the order total the customer paid, in the order currency; every item carries its price after discounts, with and without tax, the original price, SKU, categories, brand, image and URL; discount codes, shipping, fees, tax, billing and shipping address go with the order.
* Profiles from orders: name, phone in E.164, address, company, language of the order (WPML, Polylang).
* Newsletter checkbox at checkout (classic and block), never ticked in advance, your own text, three positions in the classic checkout, hidden for customers who already subscribed. Only a tick subscribes (Klaviyo Subscribe Profiles, with e-mail marketing consent) to the list you choose; double opt-in follows the list setting in Klaviyo. The answer, the time and the exact wording are kept on the order; an order note tells whether the subscription went through.
* Background queue with retries: Klaviyo's rate limits (429 with Retry-After) pause the queue for exactly as long as Klaviyo asks, network errors and 5xx retry with backoff, refused calls stay visible with Klaviyo's own error text. Every event has a stable unique_id, so a retry or a repeated hook can never duplicate it in Klaviyo.
* Staging protection: the key is tied to the site address; a copy of the database on a staging site sends nothing until you confirm it is the live shop.
* Order box: consent answers and what was sent for this order. API log for 30 days, queue status, "Copy diagnostics".
* HPOS and the classic order storage, classic and block checkout. PHP filters for every event (ccklav_event_properties), order line, profile and catalog item.

= Pro =

* Fulfilled Order (at the status you choose, with tracking numbers from Shipment Tracking plugins), Canceled Order and Refunded Order — every refund, partial ones included, with amount, items and reason. Klaviyo's own metric names and matching ids, so its customer lifetime value counts them.
* Product catalog in Klaviyo (Catalogs API): products as items, variations as variants, with price, stock, images and categories, updated a minute after a product or its stock changes — for product blocks, recommendations and Back in Stock flows.
* Past orders: send the orders of the last 3 to 60 months with their original dates. Klaviyo records them without starting any flow; orders already sent are skipped.
* SMS marketing consent: a separate checkbox, phone converted to international format, its own list.
* Newsletter switch in My Account and at registration — subscribe and unsubscribe in Klaviyo.

Pro can be tried for 7 days for free, no card needed.

= Languages =

English, Ukrainian, Russian.

= Requirements =

* A Klaviyo account and a private API key: Full access, or Custom with Accounts Read, Events Write, Profiles Write, Lists Read and Write, Subscriptions Write (Pro catalog: Catalogs Read and Write).
* WooCommerce 7.9 or newer.

Klaviyo is a trademark of Klaviyo, Inc. This is an independent integration, not affiliated with or endorsed by Klaviyo.

== Installation ==

1. Upload the plugin and activate it.
2. WooCommerce → Klaviyo → Connection: paste the private API key, save, press "Check the connection".
3. Consent: choose the list for the newsletter checkbox.
4. Tracking: check which order statuses count as placed and whether klaviyo.js has to wait for your cookie banner.
5. In Klaviyo, build your flows on the metrics Viewed Product, Added to Cart, Started Checkout and Placed Order.

== Frequently Asked Questions ==

= Can I use it next to Klaviyo's own plugin? =

Not for the same events — both would send Placed Order and the other metrics. Use one of them.

= Is there a Klaviyo test account? =

Klaviyo has no public sandbox. The plugin is built on the official API reference (revision 2026-07-15) and tested against a simulation of it; the log shows every call and Klaviyo's answer.

= Why is Added to Cart missing for some visitors? =

Klaviyo records onsite events only for browsers it knows (a visitor who came from a Klaviyo e-mail, filled in a form, or typed the e-mail at checkout), and only after cookie consent when you ask for it. Started Checkout and Placed Order are sent from the server.

= The subscription is accepted but the profile is not subscribed =

The list uses double opt-in: the customer receives a confirmation e-mail and is subscribed after confirming.

== External services ==

This plugin connects to the Klaviyo API (a.klaviyo.com) with the private API key you enter, and loads klaviyo.js (static.klaviyo.com) on the storefront with your public key when onsite tracking is on. It sends: order events (order number, items with names, SKUs, prices, quantities, categories, images and URLs, totals, discount codes, shipping and payment method, billing and shipping address) and the customer profile (e-mail, name, phone, address, company, language) when an order reaches a placed status; Started Checkout (the cart and the e-mail typed at checkout) when the shopper enters an e-mail at checkout; newsletter subscriptions (e-mail, and with Pro the phone) only when the customer ticks the consent checkbox. klaviyo.js sends Viewed Product and Added to Cart from the visitor's browser and sets Klaviyo's cookie. With Pro it also sends order status events, refunds, product catalog data (names, descriptions, prices, stock, images, categories) and past orders. Klaviyo terms of service: https://www.klaviyo.com/legal/terms-of-service ; Klaviyo privacy policy: https://www.klaviyo.com/legal/privacy-notice

The Pro build also contacts the CatCode licence server (catcode.com.ua) to activate and verify a licence key or to start a trial: it sends the key, the site address and, for a trial, the e-mail you enter. Terms and privacy: https://catcode.com.ua/

== Changelog ==

= 1.0.0 =
* First release: server-side Started Checkout, Placed Order and Ordered Product with deduplication, onsite Viewed Product and Added to Cart, cart restore links, newsletter consent at checkout (classic and block), background queue with rate-limit handling, staging protection. Pro: Fulfilled, Canceled and Refunded Order, catalog sync, past orders, SMS consent, My Account newsletter switch.
