{"id":371064,"date":"2026-09-26T09:36:17","date_gmt":"2026-09-26T09:36:17","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/trackdolphin-server-side-tracking-for-woocommerce\/"},"modified":"2026-09-26T09:36:04","modified_gmt":"2026-09-26T09:36:04","slug":"trackdolphin","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/trackdolphin\/","author":23568646,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.7.5","stable_tag":"0.7.5","tested":"7.1.2","requires":"6.0","requires_php":"8.0","requires_plugins":null,"header_name":"Trackdolphin \u2013 Server-Side Tracking for WooCommerce","header_author":"Trackdolphin","header_description":"Server-side tracking for WooCommerce. Sends shop events and paid orders to your Trackdolphin project, first-party and consent-aware.","assets_banners_color":"0e2328","last_updated":"2026-09-26 09:36:04","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/trackdolphin.com\/downloads","header_author_uri":"https:\/\/trackdolphin.com","rating":0,"author_block_rating":0,"active_installs":0,"downloads":37,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.7.5":{"tag":"0.7.5","author":"trackdolphinhq","date":"2026-09-26 09:36:04","revision":3714045}},"upgrade_notice":{"0.7.5":"<p>A &quot;no&quot; to a single service in the Trackdolphin banner (for example Google Ads while Meta is allowed) now reaches the purchase, so that service no longer receives the order. No configuration needed. If you use a page cache, clear it after updating.<\/p>","0.7.4":"<p>Advertising click identifiers are sent only with marketing consent, and a withdrawal deletes the identifier cookies the plugin set.<\/p>","0.7.3":"<p>Adds consent-aware LinkedIn click ID capture for server-side conversions.<\/p>","0.7.2":"<p>The consent banner script now ships inside the plugin instead of being fetched from Trackdolphin. Clear your page caches after updating so cached pages load the local script.<\/p>","0.7.1":"<p>The setup notice can be dismissed. No action needed after the update.<\/p>","0.7.0":"<p>New: three tracking modes for the time before a visitor has decided, set per country in the Trackdolphin dashboard, and a consent mode default announced in the page head. No action needed after the update.<\/p>","0.6.0":"<p>Options, hooks and the REST namespace move from <code>td_<\/code> to <code>trackdolphin_<\/code>; the migration runs automatically on first load. The custom update channel is gone: updates come from WordPress.org from now on.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3714045,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3714045,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3714045,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3714045,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3714045,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.7.5"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3714045,"resolution":"1","location":"assets","locale":"","width":1280,"height":800},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3714045,"resolution":"2","location":"assets","locale":"","width":1280,"height":800},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3714045,"resolution":"3","location":"assets","locale":"","width":1280,"height":1120},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3714045,"resolution":"4","location":"assets","locale":"","width":1280,"height":800}},"screenshots":{"1":"Settings page with the activation code field and the status line (link state, last confirmed connection, consent management finding).","2":"Trackdolphin dashboard: linking the plugin with a one-time activation code and checking a test purchase across the connected platforms.","3":"Designing the consent banner in the dashboard: brand, layout, purposes, services and texts with a live preview.","4":"Trackdolphin consent banner served first-party from the shop."}},"plugin_section":[],"plugin_tags":[232,20011,986,219244,550],"plugin_category":[36],"plugin_contributors":[282786],"plugin_business_model":[],"class_list":["post-371064","plugin","type-plugin","status-publish","hentry","plugin_tags-analytics","plugin_tags-consent","plugin_tags-conversion-tracking","plugin_tags-server-side-tracking","plugin_tags-tracking","plugin_category-analytics","plugin_contributors-trackdolphinhq","plugin_committers-trackdolphinhq"],"banners":{"banner":"https:\/\/ps.w.org\/trackdolphin\/assets\/banner-772x250.png?rev=3714045","banner_2x":"https:\/\/ps.w.org\/trackdolphin\/assets\/banner-1544x500.png?rev=3714045","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/trackdolphin\/assets\/icon.svg?rev=3714045","icon":"https:\/\/ps.w.org\/trackdolphin\/assets\/icon.svg?rev=3714045","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/trackdolphin\/assets\/screenshot-1.png?rev=3714045","caption":"Settings page with the activation code field and the status line (link state, last confirmed connection, consent management finding)."},{"src":"https:\/\/ps.w.org\/trackdolphin\/assets\/screenshot-2.png?rev=3714045","caption":"Trackdolphin dashboard: linking the plugin with a one-time activation code and checking a test purchase across the connected platforms."},{"src":"https:\/\/ps.w.org\/trackdolphin\/assets\/screenshot-3.png?rev=3714045","caption":"Designing the consent banner in the dashboard: brand, layout, purposes, services and texts with a live preview."},{"src":"https:\/\/ps.w.org\/trackdolphin\/assets\/screenshot-4.png?rev=3714045","caption":"Trackdolphin consent banner served first-party from the shop."}],"raw_content":"<!--section=description-->\n<p>Trackdolphin reports what happens in your WooCommerce shop to the advertising and analytics platforms you use (Google Ads, Meta, GA4 and others) from the server, not from the browser. Ad blockers, Safari's tracking prevention and abandoned redirects no longer swallow your conversions, and eligible purchases are reported with the value WooCommerce actually invoiced.<\/p>\n\n<p>This plugin is an interface to the Trackdolphin service (serviceware). All functionality included in the plugin is available without restrictions: there is no license key, trial period or locked feature. It requires a Trackdolphin account (<a href=\"https:\/\/trackdolphin.com\/en#preise\">service pricing<\/a>). The activation code only links your shop to its project in the dashboard; without that link, no data leaves your shop.<\/p>\n\n<p><strong>What the plugin does<\/strong><\/p>\n\n<ul>\n<li>Reports paid orders (and refunds) from the server, with hashed match signals (e-mail, phone, name, address) in the format Google Ads and Meta expect. Value and line items come from the WooCommerce order, not from a data layer.<\/li>\n<li>Adds a small first-party script to the storefront that records page views, product views, add-to-cart, checkout start and payment info. The script talks to your own shop (<code>\/wp-json\/trackdolphin\/v1\/collect<\/code>); the shop relays the event to Trackdolphin. If the shop REST route is unavailable, browser events can fall back to your project collector directly.<\/li>\n<li>Reads the visitor's consent decision from the WP Consent API, Google Consent Mode, Cookiebot, Usercentrics, IAB TCF and Trackdolphin's own banner. Only an explicit analytics or marketing grant unlocks event delivery; identifiers and cookies additionally require their respective consent. A page-level default never grants permission.<\/li>\n<li>Delivers purchases in the background through the WooCommerce Action Scheduler, signed with an installation key, with retries for up to seven days. The thank-you page never waits for Trackdolphin.<\/li>\n<li>Optionally serves the Trackdolphin consent banner you design in the dashboard, using the readable GPL-licensed JavaScript bundled in the plugin.<\/li>\n<li>Shows a status line in WordPress: link state, last confirmed connection, consent management detected, purchases the server declined, and pending delivery jobs.<\/li>\n<\/ul>\n\n<h3>External services<\/h3>\n\n<p>This plugin is an interface to Trackdolphin, a server-side tracking service operated by Trackdolphin (Germany). The service processes events, stores consent records and forwards conversions to your connected advertising and analytics platforms. Using it requires a Trackdolphin account; you create the account and a project at <a href=\"https:\/\/app.trackdolphin.com\">app.trackdolphin.com<\/a> and link the shop with a one-time activation code from the dashboard. The code carries the collector address, the project id and a one-time secret for signed communication; it does not unlock plugin features.<\/p>\n\n<p><strong>Until you paste that activation code, the plugin contacts no external server at all.<\/strong> No script is added to your pages, no cookie is set, no request leaves your shop \u2014 not on install, not on activation, not on a page view. Every connection described below starts only after you have linked the shop yourself.<\/p>\n\n<p>The plugin communicates with your project collector and links to the dashboard. The consent banner JavaScript is bundled locally in <code>assets\/td-consent.js<\/code> under GPL-2.0-or-later; no executable banner code is downloaded from Trackdolphin.<\/p>\n\n<p><strong>1. The Trackdolphin collector of your project \u2014 <code>https:\/\/&lt;project&gt;.trdph.com<\/code><\/strong><\/p>\n\n<p>The plugin locally blocks browser events, paid orders and refunds until the visitor has explicitly granted analytics or marketing consent. It also blocks fully denied decisions. This applies even when the service returns \"collect\" (sammeln) or \"always\" (immer); the settings page explains the override. Queued purchases without an eligible checkout snapshot are discarded without transmission.<\/p>\n\n<p>The exact address is contained in the activation code you paste. Your shop sends the following to it; browser events can also be sent directly by the visitor's browser when the shop REST route is unavailable:<\/p>\n\n<ul>\n<li><em>Browser events<\/em>, relayed only after the local consent check while a visitor is browsing (page view, product view, add to cart, checkout start, payment info): event type, page URL (query parameters and referrer only with marketing consent), currency, product ids, names, prices and quantities, the visitor's consent state, a first-party visitor id and session id (only with consent), click ids from Google and Meta (only with consent), and the visitor's IP address and user agent, so that the advertising platforms can attribute the event to the visitor instead of to your server.<\/li>\n<li><em>Paid orders and refunds<\/em>, in the background only with an eligible consent snapshot recorded on the order: order id, value, tax, shipping, currency, coupon, payment method, line items, the buyer's country, SHA-256 hashes of the buyer's e-mail, phone, first and last name, city, state and postcode, a pseudonymous customer id, the identifiers captured at checkout, the buyer's IP address and user agent, WooCommerce order attribution (UTM values, entry page) and the consent snapshot recorded at checkout.<\/li>\n<li><em>Banner configuration<\/em>, fetched as JSON when a linked shop page needs it and cached for five minutes per visitor country: project id and, only after visitor consent and when locally available, the visitor's country. The JavaScript that displays the banner is included in the plugin.<\/li>\n<li><em>Consent decisions<\/em> made in the Trackdolphin banner, if you use it: the decision itself, language, page and visitor id (the collector stores only a hash of that id).<\/li>\n<li><em>A status report<\/em>, once a day and on every click on \"Verbindung pr\u00fcfen\" (check connection): plugin, PHP, WordPress and WooCommerce versions, whether HPOS is enabled, which consent management tool was detected, and the delivery counters, so that the dashboard can show the state of the installation. This report contains no visitor data.<\/li>\n<li><em>A revocation<\/em>, once, when you uninstall the plugin: the installation key is invalidated.<\/li>\n<\/ul>\n\n<p>Trackdolphin additionally applies the per-country project rule before forwarding events to an advertising platform. That rule cannot relax the plugin\u2019s local consent check. Configuration requests and installation status reports use the shop server connection and do not forward visitor IP addresses or user agents; consent records are sent only after a banner decision.<\/p>\n\n<p><strong>2. <code>https:\/\/app.trackdolphin.com<\/code> \u2014 the dashboard<\/strong><\/p>\n\n<p>Linked from the plugin's settings page for you to click. The plugin itself sends nothing there.<\/p>\n\n<p>By linking your shop you agree to the Trackdolphin terms of service and acknowledge its privacy policy. Data sent to Trackdolphin is processed on your behalf under the data processing agreement.<\/p>\n\n<ul>\n<li>Terms of service: <a href=\"https:\/\/trackdolphin.com\/en\/docs\/agb\">https:\/\/trackdolphin.com\/en\/docs\/agb<\/a><\/li>\n<li>Privacy policy: <a href=\"https:\/\/trackdolphin.com\/en\/docs\/datenschutzerklaerung\">https:\/\/trackdolphin.com\/en\/docs\/datenschutzerklaerung<\/a><\/li>\n<li>Data processing agreement: <a href=\"https:\/\/trackdolphin.com\/en\/docs\/avv\">https:\/\/trackdolphin.com\/en\/docs\/avv<\/a><\/li>\n<li>Documentation: <a href=\"https:\/\/trackdolphin.com\/en\/docs\">https:\/\/trackdolphin.com\/en\/docs<\/a><\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Install and activate the plugin. WooCommerce 8.0 or newer must be active.<\/li>\n<li>The integration requires a Trackdolphin account (<a href=\"https:\/\/trackdolphin.com\/en#preise\">service pricing<\/a>). Create an account and a project at app.trackdolphin.com. Under Setup you find the code for linking the shop.<\/li>\n<li>In WordPress open Trackdolphin (top-level menu entry, also under Settings), paste the activation code and click \"Verkn\u00fcpfen\". The code carries the collector address, the project id and a one-time secret; it is valid for 24 hours and can be redeemed once.<\/li>\n<li>Click \"Verbindung pr\u00fcfen\" (check connection). The status line then reads \"Verkn\u00fcpfung: hergestellt\".<\/li>\n<li>Make sure WP-Cron runs (or a system cron calls <code>wp-cron.php<\/code> every few minutes): purchases are delivered by the WooCommerce Action Scheduler in the background.<\/li>\n<\/ol>\n\n<p>Updating from 0.5.0 or earlier: the plugin renames its options, transients, hooks and REST namespace from <code>td_<\/code> to <code>trackdolphin_<\/code> on first load. Credentials, settings and counters are carried over automatically; delivery jobs that were already scheduled are still processed; the old REST route <code>td\/v1<\/code> keeps answering for cached pages.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20the%20plugin%20respect%20visitor%20consent%3F\"><h3>Does the plugin respect visitor consent?<\/h3><\/dt>\n<dd><p>Yes. Browser events and server-side orders require an explicit analytics or marketing grant before leaving the shop, including the visitor\u2019s IP address and user agent. No event is sent before a decision or after full rejection, regardless of the service mode. The script reads the WP Consent API (opt-in), Google Consent Mode, Cookiebot, Usercentrics, IAB TCF 2 and Trackdolphin's banner. Defaults never count as decisions. Purchases use the consent snapshot saved at checkout; missing or ineligible snapshots are not transmitted. The same local check applies to queued purchases after an update. Marketing identifiers require marketing consent.<\/p>\n\n<p>After updating, purge any external full-page\/CDN cache so visitors receive the new script. The plugin invalidates supported WordPress page caches once; cached HTML outside WordPress must be purged by the site operator.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20hpos%20%28high-performance%20order%20storage%29%3F\"><h3>Does it work with HPOS (High-Performance Order Storage)?<\/h3><\/dt>\n<dd><p>Yes. The plugin declares compatibility with <code>custom_order_tables<\/code> and only reads and writes order data through the <code>WC_Order<\/code> object.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20the%20block%20checkout%3F\"><h3>Does it work with the block checkout?<\/h3><\/dt>\n<dd><p>Yes. Consent and identifiers are captured through <code>woocommerce_store_api_checkout_update_order_meta<\/code> for the block checkout and through <code>woocommerce_checkout_create_order<\/code> for the classic checkout. The plugin declares compatibility with <code>cart_checkout_blocks<\/code>.<\/p><\/dd>\n<dt id=\"what%20happens%20without%20a%20trackdolphin%20account%3F\"><h3>What happens without a Trackdolphin account?<\/h3><\/dt>\n<dd><p>Nothing. Until the shop is linked with an activation code, no script is added to your pages, no cookie is set and no data is sent anywhere. Paid orders that arrive while the plugin is unlinked are counted in the status line (\"Nicht gemeldete K\u00e4ufe\") so you can see what was missed.<\/p><\/dd>\n<dt id=\"which%20cookies%20does%20the%20plugin%20set%3F\"><h3>Which cookies does the plugin set?<\/h3><\/dt>\n<dd><p>_td_vid (first-party visitor id, 365 days, only with marketing consent) and <code>_td_consent<\/code> (the consent decision the script saw, 180 days, only after a decision). Click ids (<code>gclid<\/code>, <code>gbraid<\/code>, <code>wbraid<\/code>, <code>_fbc<\/code>) are stored as cookies only with marketing consent. LinkedIn's click ID (<code>li_fat_id<\/code>) is stored in <code>_td_li_fat_id<\/code> for 30 days, also only with marketing consent.<\/p><\/dd>\n<dt id=\"where%20is%20the%20data%20stored%3F\"><h3>Where is the data stored?<\/h3><\/dt>\n<dd><p>Trackdolphin stores the events of your project on its own infrastructure. Nothing about the visitor is stored in the WooCommerce database except the consent snapshot and identifiers on the order (<code>_td_*<\/code> order meta) and a small encrypted delivery queue in the options table while a purchase is waiting to be sent.<\/p>\n\n<p>Purchases, cancellations and refunds are always delivered to the project the shop is currently linked to, also after the project or collector address has changed. For orders anonymized by WooCommerce's privacy tools, pending and later events are still sent, but without personal data (no identifiers, hashes, address, IP address or user agent; only amount, currency, items and the country code).<\/p><\/dd>\n<dt id=\"what%20is%20deleted%20when%20i%20uninstall%20the%20plugin%3F\"><h3>What is deleted when I uninstall the plugin?<\/h3><\/dt>\n<dd><p>Uninstalling revokes the installation key at Trackdolphin, removes the credentials, settings, counters and the delivery queue. Orders keep their <code>_td_*<\/code> meta so that a later reinstall does not report the same purchase twice.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.7.5 (2026-09-26)<\/h4>\n\n<ul>\n<li>Links to trackdolphin.com now carry the language prefix (<code>\/en\/docs\/\u2026<\/code>); the old addresses keep working as permanent redirects.<\/li>\n<li>Purchases, cancellations, refunds and queued deliveries are sent to the currently linked project, also after a project or collector address change.<\/li>\n<li>Orders anonymized by WooCommerce's privacy tools: pending and later events are still sent, without personal data.<\/li>\n<li>The delivery queue marks an event as delivered only after the collector confirms it.<\/li>\n<li>Per-service consent: with service switches in the Trackdolphin banner, a \"no\" to a single service (e.g. Google Ads while Meta is allowed) now reaches the consent record, the browser events and the purchase. The consent relay also keeps <code>origin: migrated<\/code> and <code>source: placeholder<\/code>; invalid entries in the service map are dropped one by one instead of rejecting the record. A retry carries a service the visitor has meanwhile switched off. <code>_td_consent<\/code> stays purpose-based; the purchase reads only the denials from the banner cookie. No new cookie; nothing leaves the shop before the visitor decides.<\/li>\n<li>Consent banner runtime rebuilt from the current banner package. With service switches, a \"no\" to Google Ads or Google Analytics now also sets the matching Google Consent Mode signals to <code>denied<\/code>, even when another service of the same purpose is allowed; the dataLayer event <code>td_consent_update<\/code> carries the service map as <code>td_services<\/code>; if the cookie gets too large, the denials are kept and only the \"yes\" entries are dropped. Embeds marked with <code>data-td-cm-src<\/code> stay unloaded behind a placeholder until the visitor loads them. The runtime still makes no network request of its own; nothing leaves the shop before the visitor decides.<\/li>\n<\/ul>\n\n<h4>0.7.4<\/h4>\n\n<ul>\n<li>Block browser events and queued orders locally until explicit visitor consent, regardless of service mode; show the override in settings.<\/li>\n<li>Validate and sanitize browser payloads before forwarding, preserving consent, identifiers and commerce values.<\/li>\n<li>Defer cron scheduling and migrations until init to prevent early translation notices.<\/li>\n<li>Gate advertising identifiers on marketing consent and remove plugin cookies on withdrawal.<\/li>\n<\/ul>\n\n<h4>0.7.3<\/h4>\n\n<ul>\n<li>Added: captures LinkedIn's click ID (li_fat_id) with marketing consent and passes it to the server-side conversion.<\/li>\n<li>Fixed: pages cached before 0.7.2 keep loading the consent banner via a redirect from the old script address to the bundled file.<\/li>\n<li>Security: invalid consent requests no longer use up the shop's consent limit; limits apply per visitor plus a shop-wide cap.<\/li>\n<\/ul>\n\n<h4>0.7.2 (2026-09-19)<\/h4>\n\n<ul>\n<li>Changed: the readable, unminified consent banner runtime is bundled in the plugin under GPL-2.0-or-later and loaded locally with the plugin version. Removed the remote runtime download, its cache and the <code>\/consent.js<\/code> REST route. Clear page caches after updating so cached pages load the local script.<\/li>\n<li>Fixed: unlinked or disabled shops emit no consent scripts and make no banner requests.<\/li>\n<li>Security: consent relaying has a separate limit of 60 requests per shop per minute, a 64 KiB body limit and strict validation of the decision, four boolean purposes and metadata. Public consent and collect routes document why anonymous access is needed and how it is protected.<\/li>\n<li>Security: reject unexpected input types in forms, activation codes, request bodies, server values and identifier parameters; validate identifier cookies.<\/li>\n<li>Clarified: Trackdolphin is serviceware. The linking code is not a license key; the plugin contains no trials, paid feature locks or quotas.<\/li>\n<\/ul>\n\n<h4>0.7.1 (2026-09-17)<\/h4>\n\n<ul>\n<li>Changed: the admin notice asking for the link code can now be dismissed, and the choice is remembered. A real error (failed connection test, damaged code) still shows and is never hidden behind the dismissal.<\/li>\n<li>Changed: plugin tags no longer name third-party brands.<\/li>\n<\/ul>\n\n<h4>0.7.0 (2026-09-11)<\/h4>\n\n<ul>\n<li>Added: three tracking modes (after consent, collect, always). The mode says what happens BEFORE the visitor has decided: \"after consent\" stays silent (no event, no cookie, no reading); \"collect\" sends everything that is known without touching the device (page including its parameters, referrer, products, value) and leaves the device alone, so there is no visitor id and no session; \"always\" measures right away with identifiers and a cookie. Which mode applies is decided in the Trackdolphin dashboard, per country; the collector tells the plugin. A decision by the visitor always wins over the mode.<\/li>\n<li>Added: the consent mode default is now announced in the head of every page, before the shop's own Google tag: all four signals denied with wait_for_update, or granted in \"always\" mode. Without an announcement a Google tag behaves as if consented and sets cookies; in the EEA Google reads missing signals as no consent and does not use the data at all. Switchable, and off by default when another consent tool is detected, because two contradicting defaults are worse than none.<\/li>\n<li>Changed: the settings page now has a section \"Trackingverhalten und Zustimmungssignal (Profi-Einstellungen)\" with one sentence per mode and a link into the dashboard. The old, technical note about the visitor cookie is gone (Christopher Motz, 11.9.: \"too technical and it makes no sense, because we want to leave the choice to the user\"). The country list stays in the dashboard on purpose: maintained twice it would contradict itself.<\/li>\n<\/ul>\n\n<h4>0.6.1 (2026-09-11)<\/h4>\n\n<ul>\n<li>Added: a red admin notice on every admin page as soon as the collector declines events for lack of consent and no consent tool hands over a decision. It offers both ways out: \"set up consent banner\" (opens the Trackdolphin dashboard for this project) and \"change tracking settings\" (the plugin settings), plus the note that switching to \"always collect\" runs counter to local regulations in Europe. Dismissible per state; a changed state shows it again. Without declined events the previous, quieter warning stays.<\/li>\n<li>Added: consent tools are now detected without the plugin list as well, through constants, classes, functions and options. A tool no longer goes unnoticed just because its folder was renamed, it runs as a must-use plugin, or it is not distributed through the WordPress directory at all. Every marker is backed by the tool's source or its vendor documentation; where no evidence was found, nothing is claimed.<\/li>\n<li>Added: three more plugin folders recognised: gdpr-cookie-consent (WebToffee, NOT the same product as CookieYes although both set the same cookies), uk-cookie-consent (Termly) and cookie-notice (hu-manity.co).<\/li>\n<li>Added: the finding now distinguishes three cases: none found, found but it hands us nothing, and found and reporting. The wording follows them: a merchant who HAS a consent tool is no longer told he has none, but is told which tool it is and how to wire it up. The self-report to the dashboard carries the case as consent_status.<\/li>\n<\/ul>\n\n<h4>0.6.0 (2026-09-11)<\/h4>\n\n<ul>\n<li>Fixed: after a click on \"accept all\" the page view of the CURRENT page is now sent again. The WP Consent API reports every category on its own and synchronously (<code>wp_set_consent()<\/code> fires <code>wp_listen_for_consent_change<\/code> per call), so the first event still said \"marketing denied\" and the catch-up was rejected by the collector with 403 <code>consent_required<\/code>. The script now reads the consent state once, after all categories have been set.<\/li>\n<li>Changed: everything the plugin stores or registers in WordPress now carries the prefix <code>trackdolphin_<\/code> instead of <code>td_<\/code>: options, transients, the delivery hook (<code>trackdolphin_deliver_event<\/code>), the daily heartbeat, admin actions, nonces, the settings group and the REST namespace (<code>trackdolphin\/v1<\/code>). A one-time migration copies existing options and transients to the new names and removes the old ones; delivery jobs scheduled under the old hook are still processed; the old REST namespace <code>td\/v1<\/code> stays registered as an alias for pages served from a cache. Cookies (<code>_td_vid<\/code>, <code>_td_consent<\/code>), order meta (<code>_td_*<\/code>) and signature headers (<code>X-Td-*<\/code>) are unchanged: they are the contract with the collector, not WordPress namespace. Constants <code>TRACKDOLPHIN_VERSION<\/code> and <code>TRACKDOLPHIN_PATH<\/code> replace <code>TD_VERSION<\/code> and <code>TD_PATH<\/code> (kept as aliases).<\/li>\n<li>Removed: the update channel introduced in 0.4.1 (<code>Trackdolphin_Updates<\/code>, <code>pre_set_site_transient_update_plugins<\/code>). Plugins in the WordPress.org directory receive their updates from the directory; a custom updater is not permitted there.<\/li>\n<li>Changed: licensed under the GPLv2 or later.<\/li>\n<li>Changed: the relay rate limit uses a transient instead of direct database writes; the inline configuration and script tags are printed through <code>wp_print_inline_script_tag()<\/code> and <code>wp_print_script_tag()<\/code>; every file guards against direct access; inputs are unslashed and sanitized; <code>parse_url()<\/code> replaced by <code>wp_parse_url()<\/code>; no <code>error_log()<\/code> in production code (the reason now lands in the status line). Plugin Check reports no errors and no warnings for the shipped files.<\/li>\n<li>Changed: outdated admin texts that still mentioned the \"personal plugin package\" now point to the activation code.<\/li>\n<\/ul>\n\n<h4>0.5.0 (2026-09-11)<\/h4>\n\n<ul>\n<li>Changed: the personal plugin package is gone. The plugin is the same ZIP for everyone; linking happens with a single activation code from the dashboard (Setup), pasted under WordPress \u2192 Trackdolphin. The code carries collector address, project id, installation id and the one-time secret; it is valid 24 hours and redeemable once. Existing linked shops keep working.<\/li>\n<li>Changed: the consent banner runtime is no longer shipped inside the plugin. The shop serves it from its own route (<code>\/wp-json\/trackdolphin\/v1\/consent.js<\/code>, fetched from the Trackdolphin service and cached for an hour), so the browser still sees only the shop domain and a new banner release needs no plugin update.<\/li>\n<li>Added: Trackdolphin Consent, the project's own cookie banner. Once a version is published in the dashboard, the plugin fetches it from the collector (cached five minutes) and writes it as an inline configuration into the page head: first-party, no third-party request before the decision.<\/li>\n<li>Added: the banner's decisions reach everything that reads consent; every decision is relayed as a consent record to the collector through the shop.<\/li>\n<\/ul>\n\n<h4>0.4.2 (2026-09-11)<\/h4>\n\n<ul>\n<li>Added: when the collector declines browser events for lack of consent (<code>403 consent_required<\/code>), the status line says so, with the last time it happened and what helps.<\/li>\n<li>Fixed: timestamps in the status line are shown in the shop's timezone instead of raw UTC.<\/li>\n<\/ul>\n\n<h4>0.4.1 (2026-09-11)<\/h4>\n\n<ul>\n<li>Added: the buyer's identifiers are captured at checkout and travel with the purchase: visitor id, <code>gclid<\/code>\/<code>gbraid<\/code>\/<code>wbraid<\/code> (also from Google's <code>_gcl_aw<\/code> cookie), <code>_fbc<\/code>\/<code>_fbp<\/code>, GA client id; fallback is the entry URL of WooCommerce's order attribution.<\/li>\n<li>Added: compatibility declared for HPOS (<code>custom_order_tables<\/code>) and the block checkout (<code>cart_checkout_blocks<\/code>).<\/li>\n<li>Added: the plugin reports its version, PHP\/WP\/WC versions, HPOS state, consent finding and delivery counters to the collector with every connection check, on activation and once a day.<\/li>\n<li>Added: status line warns when five or more delivery jobs are waiting, with the WP-Cron hint.<\/li>\n<li>Fixed: the server-side visitor cookie decision now reads the full consent snapshot, not only the WP Consent API.<\/li>\n<\/ul>\n\n<h4>0.4.0 (2026-09-11)<\/h4>\n\n<ul>\n<li>Changed: the plugin no longer decides about consent; the server does. Every paid order is sent with the consent snapshot and its origin (<code>source: cmp<\/code> or <code>source: default<\/code>); the collector answers 202 or 403 <code>consent_required<\/code>.<\/li>\n<li>Added: <code>country_code<\/code> in the purchase payload so the server can apply the per-country rule.<\/li>\n<li>Added: a 403 <code>consent_required<\/code> from the server is counted once per order, shown in the status line and never retried.<\/li>\n<li>Fixed: orders without a consent snapshot (admin, import, subscription renewals) are sent with <code>source: default<\/code>.<\/li>\n<li>Fixed: the snippet ignored the WP Consent API unless the banner set <code>window.wp_consent_type<\/code>; it now also reads <code>window.wp_fallback_consent_type<\/code>.<\/li>\n<li>Added: the snippet writes the banner decision it sees to the first-party cookie <code>_td_consent<\/code>; the server-side snapshot reads it as a second source.<\/li>\n<li>Changed: without a decision the snippet sends an anonymous page view and lets the server decide.<\/li>\n<li>Fixed: browser events relayed through the first-party proxy lost the visitor's IP and user agent; the relay is now signed with the installation credentials.<\/li>\n<\/ul>\n\n<h4>0.3.3 (2026-09-10)<\/h4>\n\n<ul>\n<li>Fixed: a Consent Mode <code>default<\/code> was treated like an <code>update<\/code>. A preset never unlocks events or cookies, only a decision does.<\/li>\n<li>Every browser event and the purchase snapshot now carry <code>consent.source<\/code> and <code>consent.cmp<\/code>.<\/li>\n<li>WP Consent API: the visitor has decided only once the API has written its cookie.<\/li>\n<\/ul>\n\n<h4>0.3.2 (2026-09-10)<\/h4>\n\n<ul>\n<li>Consent management detection and WP Consent API check on the settings page, with a dismissable admin notice when a banner is not bridged to the API.<\/li>\n<li>Fixed: the server-side consent snapshot queried a filter that does not exist; every purchase was recorded as \"no consent\" even with a correctly bridged banner.<\/li>\n<li>Removed the \"visitor cookie only after consent\" settings row and the \"delete settings on uninstall\" checkbox; uninstall always removes the settings, orders are never touched.<\/li>\n<\/ul>\n\n<h4>0.3.1 (2026-09-09)<\/h4>\n\n<ul>\n<li>Activation errors show their cause; activation redirect and top-level admin menu.<\/li>\n<\/ul>","raw_excerpt":"Server-side tracking for WooCommerce: sends shop events and paid orders to your Trackdolphin project, first-party and consent-aware.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/371064","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=371064"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/trackdolphinhq"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=371064"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=371064"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=371064"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=371064"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=371064"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=371064"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}