=== affilinode ===
Contributors: affilinode
Tags: affiliate, affiliate links, price comparison, product box, comparison table
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 0.72.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Product boxes, price comparisons, comparison tables and buttons with live data from the affilinode API (Amazon, Awin and more).

== Description ==

affilinode keeps the products in your affiliate posts up to date: prices, availability, offers from several shops, specifications and successor models come from the affilinode service and are rendered by this plugin as product boxes, lists, comparison tables and buttons.

**You need an affilinode account** (with a 14-day free trial) for live data – see [affilinode.com](https://affilinode.com/). Without an account you can try everything in **demo mode** with bundled sample products; demo mode does not contact any server.

= Features =

* Product boxes in several layouts (box, card, horizontal, compact) with the best offer, more offers, delivery times and highlights
* Template editor: your own boxes, cards and list entries in HTML with placeholders such as {{title}} and {{{button}}} – affiliate links, tracking and disclosures stay correct automatically
* Lists, best-of lists, grids, rows and accessible carousels
* Price comparison across shops (Amazon, Awin advertisers, your own WooCommerce shop and more)
* Comparison tables with the best value per row, spare parts and accessories, replacement and successor products
* Alternatives (cheaper, better equipped, successor), "best in category" podiums, "at a glance" key values, "A vs B" comparisons, price-performance chart, running costs from the EU energy label
* Test rating box with your own score, criteria, pros and cons
* Product search with live results and filters, product advisor (buying guide quiz) and a compatibility check ("Does it fit my …?") for your visitors
* Buttons, deals lists, a deals RSS feed, vouchers and ad banners of your affiliate programs (where the partner programmes allow it, see below)
* Price history and price alerts by e-mail, back-in-stock notifications (never for Amazon)
* Device + tariffs box and tariff calculators that open the partner's results
* Product pages and category hubs with structured data (schema.org), breadcrumbs and FAQ
* Automatic links (optional, off by default): product and category names in your posts become affiliate links
* Optional own redirects (`/go/…`) with server-side click counting – never for Amazon links
* Block editor blocks, shortcode generator, sidebar widget and a post check for unavailable products
* Elementor widgets and modules for Divi, WPBakery Page Builder and Beaver Builder (only loaded when the builder is active)
* Click statistics per box type (daily totals only, no cookies, no IP addresses), A/B test for button texts, optional hand-over of clicks to your own Matomo, Google Analytics 4, Tag Manager or Umami
* Multisite support, settings export and import, WP-CLI commands
* Migration from Affiliate Toolkit, AAWP, AffiliateTheme, Lasso, AmaLinks Pro, ASA and from Amazon links in posts (SiteStripe, amzn.to), with preview and undo
* Fast and fail-safe: cached data, background refresh, last known data when the API is unreachable

= Amazon Associates =

If your affilinode account uses Amazon, the plugin follows the Amazon Associates Program Policies: Amazon prices are never recorded or shown in price histories, and **price history, price alerts, deal lists and price signals are switched off** (policy 6(y)) unless you confirm in the settings that Amazon has granted you a written exception.

= Shortcodes =

All boxes are available as shortcodes `[affilinode_product]`, `[affilinode_products]`, `[affilinode_offers]`, `[affilinode_compare]`, `[affilinode_button]`, `[affilinode_list]`, `[affilinode_deals]`, `[affilinode_link]`, `[affilinode_field]` and more, and as blocks. The shortcode generator in the editor writes them for you. Up to version 0.29 the shortcodes were called `[ac_product]`, `[ac_list]` and so on; these names keep working until version 1.0. All shortcodes and attributes are documented in the help center: https://affilinode.com/hilfe/shortcodes.html

= External services =

This plugin is a client for the affilinode product data service. It does not contact any external server until you enter an affilinode API key (or configure one of the optional services below). Demo mode works offline with bundled sample data.

**affilinode API (https://api.affilinode.com)** – used to fetch product data, offers, prices, lists, comparison tables, price history, spare parts, accessories, alternatives, key values, "A vs B" comparisons, mobile contract offers (tariffs), deals and vouchers, to search the catalog, to request new products, to show your site's affiliate reports and to migrate data from other plugins.
When: when a page with an affilinode shortcode or block is rendered and the cached data is missing or expired (also in the background via WP-Cron); when editors use the block editor, shortcode generator, product list, product import, statistics or migration screens; after a post with new tracking IDs is saved and after a migration (WP-Cron); when "Test connection" is clicked; by the hourly post check; by the optional product page synchronisation; with automatic links switched on, once a day for the list of terms (product titles, brands, category names – your posts are never sent); and when visitors use the comparison picker, the product search, the product advisor, the compatibility check or the deals feed (your server passes the request on).
Data sent: your API key; your site URL and plugin version (User-Agent); product identifiers (affilinode ID, ASIN, EAN/GTIN, MPN); language and country; search terms typed by editors or by visitors, the filters visitors choose in the product search, the answers visitors give in the product advisor and the system chosen in the compatibility check (used to find matching products; advisor answers are only added to daily totals per question and answer, without IP address, cookie or visitor ID); list and category keys; for statistics the date range and post IDs; for product import the lines you enter; on multisite the blog ID, name and URL; for migrations product titles, ASINs, EAN/GTIN, shop IDs, list definitions and post IDs (never keys, secrets, other affiliate links or prices); for the reports the tracking IDs found in your posts and in the settings of the plugins you migrate from (Amazon tracking IDs, Awin clickrefs, eBay campaign IDs, network sub IDs), each with its source; only if "Send posts to affilinode" is switched on, title, address, text (without HTML), post ID and dates of public posts; with the link guard (on by default, switch off under "Link guard: suggest replacements") title, address, post ID, the product IDs in its boxes and its clicks of the last 30 days for each post the post check has checked. Visitor IP addresses and cookies are never sent; price-alert e-mail addresses only with "Sending of price alerts: affilinode" (see below).
Contextual Ads+ (only for posts sent with "Send posts to affilinode" and only if your plan or the site's "AI analysis via credits" setting includes it): affilinode analyses each version of a post once with a language model – its own model or Google Gemini via Google Cloud Vertex AI in the EU – to find matching products. Comment sections, e-mail addresses, phone numbers and links to people are removed and the text is shortened before it is sent; Google does not use the content for training.
Price alert e-mails (optional, Settings → Price alerts → "Sending of price alerts: affilinode", off by default): for every confirmation, notification and unsubscribe confirmation the plugin sends the recipient's e-mail address, the language, the site name, the product title, the current and target price, the cheapest shop and the confirm, unsubscribe and product links to `POST /v1/mail/price-alert`; affilinode sends the e-mail as processor and keeps a delivery record for up to 40 days. With the default "WordPress", nothing of this is sent.
Incoming webhooks (optional): if you configure a webhook secret, affilinode calls `/wp-json/affilinode/v1/webhook` on your site with the IDs of changed products, lists and comparison tables (HMAC-signed) and with addresses that cannot be delivered or reported an e-mail as spam.
Terms of service: https://affilinode.com/agb – Privacy policy: https://affilinode.com/datenschutz

**affilinode media CDN and image proxy (https://media.affilinode.com) and merchant image servers** – product images and shop logos are loaded by the visitor's browser from the URLs supplied by the API. The browser sends its IP address and user agent to these hosts when a page with a product box is viewed. Same terms and privacy policy as above, plus the policies of the respective merchant.

**Amazon short-link services (amzn.to, amzn.eu, amzn.asia, a.co)** – used to find the product behind an Amazon short link in your posts, only when an administrator clicks "Resolve short links" on the Move page (source "Amazon links"). For each short link found in your posts the plugin first reads the service's robots.txt (cached for a day) and then sends one HEAD request (GET if HEAD is refused) without following the redirect, at most five per step with a one-second pause, to learn the Amazon address it points to. Data sent: the short link itself, the user agent `affilinode-WordPress/<version>` and – as with any request – the IP address of your server; no site address, cookies, visitor data or other data. Only targets on Amazon marketplaces are kept. The short-link infrastructure behind amzn.to is operated by Bitly (bitly.com); the plugin uses no Bitly account or service of its own.
Amazon terms: https://www.amazon.com/gp/help/customer/display.html?nodeId=GLSBYFE9MGKKQXXM – Amazon privacy notice: https://www.amazon.com/privacy

**AMP Project script CDN (https://cdn.ampproject.org)** – only on AMP pages of the legacy Reader mode of the AMP plugin that show a box with a form (product search, product advisor, compatibility check, tariff calculator, price alert). The visitor's browser then loads the AMP component script `amp-form` from this CDN, operated by Google. Data sent: the visitor's IP address and the technical request headers (user agent, referrer) that every browser sends when loading a script. Nothing else is sent by the plugin; on normal pages and in AMP Standard/Transitional mode the plugin loads nothing from this host.
AMP project: https://amp.dev – Google terms: https://policies.google.com/terms – Google privacy policy: https://policies.google.com/privacy

**Cloudflare API (https://api.cloudflare.com)** – optional, only if you enter a Cloudflare API token under Settings → Cache & performance. When affilinode reports changed products (webhook), when a missing product appears, when a post is saved and on "Clear page caches now", the plugin looks up the zone of your domain and asks Cloudflare to purge the addresses of the affected posts (WP-Cron). Data sent: your API token, your domain name and the addresses (URLs) of your posts – no visitor data.
Terms: https://www.cloudflare.com/terms/ – Privacy policy: https://www.cloudflare.com/privacypolicy/

**MaxMind GeoLite2 (https://download.maxmind.com)** – optional, only if you enable MaxMind geolocation and enter your MaxMind account ID and license key. The plugin downloads the country database weekly (WP-Cron) or when you click "Update now". Data sent: your account ID and license key. Visitor IP addresses are looked up locally and never sent to MaxMind.
Terms: https://www.maxmind.com/en/geolite2/eula – Privacy policy: https://www.maxmind.com/en/privacy-policy

**Banner servers of affiliate networks (ADCELL, Webgains, Awin, Tradedoubler, eBay and others)** – only for the optional banner box. Banners delivered by the affilinode CDN load nothing from third parties. Banners set to "original after consent" show a placeholder first; only after the visitor clicks "Load banner" (or, with `consent="direct"`, after your consent tool granted marketing consent) does the visitor's browser load the original image from the network's server or show the network's banner code inside a sandboxed iframe, and send its IP address and user agent there. Terms and privacy policy are those of the respective network (see below).

**Affiliate networks, comparison portals and shops (Amazon, eBay, Awin, Tradedoubler, Webgains, CJ and their advertisers, CHECK24, Tarifcheck)** – the plugin only renders links. Nothing is sent until a visitor clicks a link; the link then carries your tracking ID and, where applicable, the product ID, or – for tariff calculators – the postcode and consumption the visitor entered. With the optional own redirects (`/go/…`), the click first goes to your own website, which counts it locally and forwards the visitor to the same link; Amazon links are never redirected.
Amazon Associates: https://affiliate-program.amazon.com/help/operating/policies – Privacy: https://www.amazon.com/privacy
eBay Partner Network: https://partnernetwork.ebay.com/legal – Privacy: https://www.ebay.com/help/policies/member-behaviour-policies/user-privacy-notice-privacy-policy?id=4260
Awin: https://www.awin.com/gb/legal – Privacy: https://www.awin.com/gb/privacy
CHECK24: https://www.check24.de/unternehmen/agb/ – Privacy: https://www.check24.de/unternehmen/datenschutz/
Tarifcheck: https://www.tarifcheck.de/agb/ – Privacy: https://www.tarifcheck.de/datenschutz/

**Your own analytics service: Matomo, Google Analytics 4, Google Tag Manager, Umami** – optional, each target off by default (Settings → Analytics click tracking). If you enable a target, clicks on affiliate links are handed to the tracker that your site already loads (`window._paq` / `window._mtm`, `gtag('event', …)`, `window.dataLayer`, `umami.track(…)`). The data goes to your analytics service, never to affilinode. The plugin loads none of these trackers, sets no cookies and sends nothing itself – if the tracker is missing (or has not been loaded because the visitor has not consented), nothing happens. Data handed over per click: shop name, affilinode product ID, product name (shortened), box type, position in the list, post ID, the domain of the link (never the full affiliate URL) and, if "Event value: Price" is set, price and currency.
Google Analytics terms: https://marketingplatform.google.com/about/analytics/terms/us/ – Google privacy policy: https://policies.google.com/privacy – Matomo: https://matomo.org/privacy-policy/ – Umami: https://umami.is/privacy

= Privacy =

* Price alerts and back-in-stock notifications (off by default) store the subscriber's e-mail address, the product and the target price in your WordPress database (double opt-in, unsubscribe link in every mail). They are included in the WordPress personal data export and erasure tools. By default the mails are sent by WordPress (wp_mail); with "Sending of price alerts: affilinode" affilinode sends them as your processor.
* Click statistics, the A/B test and the optional own redirects store daily totals per box type or link and post only – no cookies, no IP addresses, no user agents.
* Geolocation (for the country of offers) uses the visitor's IP address locally only.
* The product advisor sends the visitor's answers to affilinode to find matching products; only daily totals per question and answer are kept – no IP address, cookie or visitor ID.

= Third-party libraries =

* MaxMind DB Reader (maxmind-db/reader) 1.14.0 – Apache License 2.0 – https://github.com/maxmind/MaxMind-DB-Reader-php (declared in composer.json, bundled in vendor/)

== Installation ==

1. Install and activate the plugin.
2. Go to **affilinode → Settings** and enter the API key of your site (affilinode dashboard → Websites → "Plugin und API-Schlüssel"). Without a key, switch on demo mode to try the plugin with sample products.
3. Click **Test connection**.
4. Insert a product box with the block "affilinode" or the shortcode generator.

On multisite, settings can be made network-wide (Network Admin → affilinode) and overridden per site.

== Frequently Asked Questions ==

= Do I need an affilinode account? =

For live data, yes. Demo mode shows bundled sample products without an account and without any external request.

= Is visitor data sent to affilinode? =

No. The plugin requests product data server-side with your API key. Visitors' browsers only load product images from the affilinode CDN or the merchant (see External services). Only what visitors type or choose in the comparison picker, the product search and the product advisor is passed on by your server – search terms, filters and advisor answers, never IP addresses or cookies.

= What is the small "Made with affilinode" link below the boxes? =

A small "Made with affilinode" link (rel="nofollow") that you can show below each box to support affilinode. The plugin never adds it on its own – on any plan, including the free one. You decide under Settings → Layout ("Show the Made with affilinode link": Default, On or Off). A choice made in the plugin always wins. Every feature works without the link. Text links and inline buttons never show it.

= Why are price history and price alerts not shown? =

Your affilinode account uses Amazon. The Amazon Associates Program Policies do not allow price tracking or price alerts on sites with Amazon links. If Amazon has granted you a written exception, you can confirm that in the settings.

= Who sends the price alert e-mails? =

By default WordPress itself (wp_mail – also through an SMTP plugin). Under Settings → Price alerts you can switch "Sending of price alerts" to affilinode: then affilinode sends them via its mail server, optionally with your own sender domain. Bounces and spam complaints are handled for you, and the affected alerts are switched off.

= Does the plugin work with page caches? =

Yes. Boxes can be rendered server-side (cached together with the page) or loaded via Ajax for always-current prices. With a webhook secret set up, affilinode reports changed products, lists and comparison tables, and the plugin clears the posts with these boxes in LiteSpeed Cache, WP Rocket, W3 Total Cache, WP Super Cache, WP Fastest Cache, SiteGround Optimizer, Breeze, Nginx Helper and Cloudflare (Settings → Cache & performance, on by default). This runs in the background.

For Cloudflare, either use the Cloudflare plugin or enter an API token with "Zone → Zone → Read" and "Zone → Cache Purge → Purge" (stored encrypted). Own cache layers can hook into the action `affilinode_purge_urls` ( $urls, $post_ids ).

= Does affilinode work with AMP? =

Yes. On AMP pages of the official AMP plugin (Standard, Transitional and Reader mode) and of "AMP for WP", every box is rendered on the server and affilinode loads no JavaScript of its own. The styles come as a compact AMP variant, only for the boxes on the page. Product search, product advisor and compatibility check are forms that reload the AMP page with the result; the price alert uses amp-form. Carousels are a row you can swipe. Click tracking, box statistics and the A/B test need JavaScript and do not count on AMP pages; own redirects (/go/…) count clicks on your server. Details are in the help center.

= Does it work with Elementor, Divi, WPBakery or Beaver Builder? =

Yes. With Elementor active, the panel has an "affilinode" category with an "affilinode box" widget for every box type, plus product box, product list and price comparison as their own widgets. Divi, WPBakery and Beaver Builder each get a module "affilinode": choose the box type and only its options are shown. All of them render exactly like the shortcodes (same templates, caching, tracking and click statistics). Without the builder, nothing of this is loaded.

= Can affiliate links go through my own domain (/go/…)? =

Yes, optionally: Settings → Own redirects → "Route affiliate links through your own website" (off by default). Boxes, buttons, text links and automatic links then point to an address on your site such as `/go/samsung-galaxy-s25-otto`. A click is counted on your server and forwarded with a 302 to exactly the affiliate link the box would have shown. `rel="sponsored nofollow"` stays on the link.

* **Amazon links are never redirected.** Amazon requires that links visibly lead to Amazon (Associates Program Policies). Some advertisers in other networks forbid redirects too – check their terms.
* Not counted: bots and link previews, browser prefetching and prerendering. The figures are daily totals per link and post – no IP address, no cookie, no user agent is stored, and nothing is sent to affilinode.
* `/go/` answers with `X-Robots-Tag: noindex, nofollow`. If a CDN caches everything (e.g. a Cloudflare "Cache Everything" rule), exclude `/go/*` there.

= Can I use a different Amazon tracking ID for a post? =

Yes. Normally Amazon links carry the tracking ID of your website (affilinode dashboard → Websites → Tracking IDs). To use another one, use the field "Amazon tracking ID for this post" in the editor sidebar, or `tracking="myblog-21"` in a shortcode, e.g. `[affilinode_product id="…" tracking="myblog-21"]`. A tracking ID in the box wins over the one of the post, which wins over the website's. Only the `tag` parameter of links to Amazon marketplaces is replaced. Tracking IDs consist of letters, digits and hyphens (at most 64 characters).

= Do visitors from other countries see the offers of their country? =

Yes, with geolocation (Settings → Loading & geolocation): the country comes from a CDN header (e.g. Cloudflare `CF-IPCountry`), otherwise from the MaxMind GeoLite2 database, otherwise the default country of the site applies. With the loading mode hybrid or Ajax the page swaps the box in the browser for the offers of the visitor's country with its own tracking IDs. Which shops a country shows and which partner comes first is set per website in the affilinode dashboard; a single box can override this with `shops`, `prefer` and `countries`.

= How current are the prices, and what happens with old ones? =

Every offer carries the time of its last price confirmation, and the boxes show "Price updated 2 hr. ago". Prices older than "Maximum price age" (Settings → Cache & performance, 24 hours by default) are hidden and the button reads "Check current price". Amazon prices are never shown when older than 24 hours, even with a higher setting; eBay offers after 6 hours. Per box: `max_age="6"` (hours).

= Can product and category names be linked automatically? =

Yes, under **affilinode → Automatic links** (off by default). Product names link to the best offer or to the first offer of the shops you pick, in your order; category names link to the Amazon search with your tracking ID, to your own category page, or not at all. You can add your own keywords and set the maximum number of links per post. Headings, existing links, code, captions, tables of contents, feeds and the editor are never linked. Automatic links carry `rel="sponsored nofollow noopener"` and click tracking.

= Can I track affiliate clicks in Google Analytics 4 / GTM / Matomo / Umami? =

Yes. Under Settings → Analytics click tracking switch on the targets you use, each on its own and off by default. The plugin does not load any tracker: it hands the click to the tracker your site already loads (`gtag`, `dataLayer`, Matomo, `umami.track`) and does nothing if it is missing. Each click carries shop, product ID, shortened product name, box type, position, post ID and the domain of the link – never the affiliate URL with your tracking parameters. Consent is handled by your consent tool: if it only loads the tracker after consent, no click is reported before.

= Can I change button size, corners, hover and badge colours? =

Yes, under Settings → Layout: "Button size" (small, medium, large), "Corner radius (px)", "Button colour on hover", and one colour each for "test winner" badges, "value for money" badges and all other badges. The preview below the fields shows sample products with your values before you save. Text colours are chosen automatically for sufficient contrast. For anything beyond that, add your own CSS under Appearance → Customize → Additional CSS (or in the Site Editor). The boxes use CSS variables on `.acp`, e.g. `.acp{--acp-radius:4px;--acp-btn-h:48px}` – the full list is in the help center.

= Can I design my own boxes without editing PHP? =

Yes, under affilinode → Templates (administrators). Create a template from the built-in product box, card or list entry (or an empty one) and edit it as HTML with placeholders such as `{{title}}`, `{{brand}}`, `{{price}}`, lists such as `{{#offers}}…{{/offers}}`, conditions such as `{{#if purchasable}}…{{else}}{{status}}{{/if}}` and ready-made parts with three braces: `{{{image}}}`, `{{{stars}}}`, `{{{price_html}}}`, `{{{button}}}`, `{{{disclaimer}}}`. The list next to the editor shows every placeholder; errors are shown with their line, and the preview shows sample products while you type. Then use `[affilinode_product id="…" template="custom:my-box"]` or pick the template as "Layout" in the block or the shortcode generator.

Links to the shop only work through `{{{button}}}` or `<a {{{link_attrs}}}>…</a>` – there is no placeholder with the raw affiliate URL, so tracking IDs, /go/ redirects and click tracking always apply. Every link in a template gets `rel="sponsored nofollow"`. Templates cannot contain scripts, event handlers, style attributes or style elements: the HTML is always filtered with a fixed list of allowed tags and attributes, for every user. Values are escaped automatically; there is no PHP and no `eval`. Style your templates with the CSS of the theme or the Additional CSS of the Customizer, starting your selectors with `.acp-tpl--<slug>`. Templates are part of the settings export.

= Can I override the templates with PHP? =

Yes. Copy a file from `templates/` into `your-theme/affilinode/` and adjust it. All template variables are also available in the `$args` array. Escape every value when you output it; for the HTML returned by the `View` helpers use `wp_kses( …, View::allowed_html() )`.

= Can I copy my settings to another website? =

Yes. At the bottom of affilinode → Settings, "Export and import settings" downloads all settings of the site as a JSON file – including automatic linking, the tariff calculators and your own templates. Secret keys (API key, webhook secret, Cloudflare token, MaxMind licence key) are left out unless you tick "Include secret keys". "Check file" uploads a file on the other website and shows a table of every value that would change before anything is saved. Every value is checked like a value entered in the form. In a multisite network, the network admin exports and imports the network settings. With WP-CLI: `wp affilinode settings export` and `wp affilinode settings import <file>`.

= Does affilinode support WP-CLI? =

Yes. `wp help affilinode` lists all commands; they do the same as the buttons in the admin: `wp affilinode status`, `cache flush`, `sync`, `migrate <source>`, `settings export|import`, `tracking sync` and `legacy status|rewrite|undo`. The commands are only loaded when WP-CLI runs. In a multisite network, choose the site with `--url=…` as usual.

= I used the plugin before version 0.30 ("affiliate-central") – what do I need to do? =

Nothing right away: the old names still work (shortcodes `[ac_product]`, the blocks `affiliate-central/…`, the hooks `affiliate_central_…`, the REST namespace `affiliate-central/v1` and the template folder `your-theme/affiliate-central/`). They are deprecated and will be removed in version 1.0. affilinode → Old shortcodes lists the posts that still contain old shortcodes or blocks; "Rewrite all" changes only the names, saves a revision before each post is changed and can undo every change. Hooks cannot be rewritten automatically: rename them to `affilinode_…` (same arguments).

= I am coming from Affiliate Toolkit, AAWP, AffiliateTheme, Lasso, AmaLinks Pro or ASA =

Open affilinode → Move and choose the source. The analysis lists the posts with the old shortcodes and the ASINs and products found; the transfer requests products unknown to affilinode (counted against the daily request quota). Your posts are not changed. Once the old plugin is deactivated, affilinode renders its shortcodes with its own boxes, for example AAWP `[amazon box]`, `[amazon link]`, `[amazon fields]` and `[amazon table]`, Lasso `[lasso id="…"]`, AmaLinks Pro `[amalinkspro …]` and ASA `[asa]`/`[asa2]`; the old tracking IDs are kept. Optionally, "Convert posts" replaces the old shortcodes by affilinode shortcodes for good, with a preview and undo via revisions. Settings → Compatibility switches each mode on or off. Shortcode names that another active plugin already uses are never taken over.

= Can affilinode take over the Amazon links in my posts (SiteStripe, amzn.to)? =

Yes. affilinode → Move → "Amazon links (SiteStripe)" finds text and image links to Amazon and short links (amzn.to, amzn.eu), and lists each with post, ASIN and tracking ID. Optionally the links can be converted into affilinode text links or boxes (preview, undo via revisions); the tracking ID of the link can be kept. Short links only reveal their product after asking the short link service – only when you click "Resolve short links" (see External services).

More questions are answered in the help center: https://affilinode.com/hilfe

== Screenshots ==

1. Product box with price comparison
2. Comparison table
3. Shortcode generator

== Upgrade Notice ==

= 0.72.0 =
Adds "Amazon as a link only" (a button without a price) for websites that do not have the Amazon interface yet, and makes title and title_style work in nine more shortcodes.

= 0.68.0 =
Fixes a fatal error on page load that could occur in 0.67.0 ("Call to undefined function wp_salt()"), seen on multisite.

= 0.66.0 =
The API key is now stored encrypted (converted automatically; after changing the salts in wp-config.php enter it again). The old affiliate-central names ([ac_…] shortcodes, blocks, hooks) will be removed in 1.0.

= 0.65.0 =
Security update: fixes price alert confirmation and unsubscribe links, limits confirmation emails per address and restricts reporting to editors. Please update.

= 0.64.0 =
New: "A vs B" comparisons, boxes in the language of the page (Polylang, WPML, TranslatePress), "Price updated … ago" under prices, successor hints, geo short links. Amazon prices older than 24 hours are no longer shown.

= 0.63.0 =
New: offers per visitor country (shop selection and preferred partner per box), "Commission (30 days)" column in the post list, "Back in stock" notification (off by default, never for Amazon). The price alert table is updated automatically.

= 0.62.0 =
Fixes boxes that stayed empty or outdated for visitors on fully cached sites (background tasks not running). New: page caches (LiteSpeed, Cloudflare, WP Rocket …) are cleared after product changes, link guard, comparison tables from the product search.

= 0.61.1 =
Fixes "HTTP 502" in the product search of the shortcode generator: searches in the editor may take up to 12 seconds instead of 3 and no longer pause the boxes of the whole website after a slow answer.

= 0.61.0 =
Fixes frequent "not valid JSON" errors in the product search of the shortcode generator. New: pack sizes box and pack tabs in the price comparison (off by default), price alert e-mails via affilinode or your own SMTP server.

= 0.60.0 =
Voucher box, SEO building blocks (FAQ, breadcrumbs, category hubs, related product pages) and importing new products directly in the shortcode generator. FAQ and related product pages are on by default on product pages (Settings → Product pages).

= 0.59.1 =
Fixes a fatal error when activating the plugin on multisite installations with pretty permalinks. Please update.

= 0.59.0 =
Smaller improvements: tracking IDs in Divi/WPBakery/Beaver modules are recognised, own templates in the shortcode generator, AAWP sorting and filter attributes are carried over.

= 0.58.0 =
Native modules for Divi, WPBakery and Beaver Builder: every affilinode box with its settings and a server-rendered preview in the builder.

= 0.57.0 =
Template editor: design your own product boxes, cards and list rows in the admin (affilinode → Templates) with placeholders, code editor and live preview – no PHP. Use them with template="custom:<name>".

= 0.56.0 =
AMP support: on AMP pages (official AMP plugin, AMP for WP) all boxes are rendered on the server without JavaScript, with AMP-compliant CSS; interactive boxes fall back to simple forms.

= 0.55.0 =
Export and import of settings, WP-CLI commands (`wp affilinode …`), carousel view for lists, optional mini card over text links and optional "add to Amazon cart" buttons (all new options off by default).

= 0.54.0 =
New running-costs box: [affilinode_energy] calculates electricity (and water) costs per year and over several years from the EU energy label, optionally compared with a second device; visitors can adjust price and usage.

= 0.53.0 =
New value-for-money chart: [affilinode_scatter] plots price against a key value of a product type, highlights your product and links every point to its offer (with an accessible table). Needs the matching affilinode server update.

= 0.52.0 =
New "at a glance" box: [affilinode_glance] shows a product's key values as tiles and how they compare with the product type ("better than 80 % of smartphones"); optionally inside every product box (off by default). Needs the matching affilinode server update.

= 0.51.0 =
New "best in category" box: [affilinode_top] picks the top 3 of a product type automatically by test score, value for money or a technical value, shown as a podium. Needs the matching affilinode server update.

= 0.50.0 =
New alternatives box: [affilinode_alternatives] shows a cheaper alternative, a better-equipped one and the successor with reasons (optionally below every product box, off by default). Needs the matching affilinode server update.

= 0.49.0 =
New compatibility check: [affilinode_compat] shows products that work with a chosen system (Home Assistant, Zigbee2MQTT, Matter, a battery platform, CPU socket, lens mount …) or answers "Does this product work with my system?" with the source. Needs the matching affilinode server update.

= 0.48.0 =
New product advisor: [affilinode_advisor] asks a few questions and shows the best-matching products with "why it fits". Advisors are set up in the affilinode dashboard; needs the matching affilinode server update.

= 0.47.0 =
Move from Lasso, AmaLinks Pro and AmazonSimpleAdmin (ASA1/ASA2): their shortcodes keep working (compatibility, off while the original plugin is active), products are transferred by ASIN, and Amazon links from SiteStripe can be found and converted with preview and undo.

= 0.46.0 =
New product search with filters: [affilinode_search] (also as block, Elementor widget and in the shortcode generator) with live results, facets for brand, price, availability and technical data. Needs the affilinode server update with the product search endpoint.

= 0.45.0 =
New classic sidebar widget "affilinode" and optional own redirects (/go/…) with click counting on your server (off by default; Amazon links are never redirected).

= 0.44.0 =
Appearance: button size, corner radius, hover and badge colours with live preview. Optional Amazon sales rank (Amazon no longer provides Prime eligibility, so there is no Prime badge).

= 0.43.0 =
Optional automatic linking of product and category names in your posts (off by default; affilinode → Automatic linking). Needs the affilinode server update with the autolink terms endpoint.

= 0.42.0 =
Sort and filter lists per shortcode (sort, only_available, min_discount, brand) and optionally hide single boxes of unavailable products.

= 0.41.0 =
Test ratings: [affilinode_rating] and the block "Test rating" show your score, test date, verdict, criteria, pros/cons and badge; optional review schema (off by default). Scores are maintained in the affilinode dashboard or per post.

= 0.40.0 =
eBay offers from the eBay API are shown in their own "On eBay" block (eBay's terms forbid mixing them with other shops). Needs the affilinode server update with the eBay connector.

= 0.39.0 =
Affiliate clicks can now also go to Google Analytics 4, Google Tag Manager and Umami (Settings → Click tracking to analytics, all off by default). The plugin only uses trackers your site already loads.

= 0.38.0 =
Tracking IDs, clickrefs, campaign IDs and sub IDs found in your posts and in AAWP/Affiliate Toolkit are reported to affilinode, so that sales are assigned to the right website. Needs the matching affilinode server update.

= 0.37.0 =
Comparison tables saved in the affilinode dashboard ([affilinode_compare table="…"]) with your own rows, yes/no rows and a highlighted test winner. Needs the affilinode server update with saved comparison tables.

= 0.36.0 =
Use a different Amazon tracking ID per box (attribute `tracking`) or per post. AAWP's `tracking_id` is now kept instead of being dropped.

= 0.35.0 =
Own shortcodes, blocks and PHP functions for text links and single product fields ([affilinode_link], [affilinode_field]), plus an "affilinode link" button in the paragraph toolbar.

= 0.34.0 =
Dynamic Amazon bestseller and new-release lists (also for AAWP's [amazon bestseller] and [amazon new]), more AAWP fields, and optionally sending your posts to affilinode for "Related to this article" (off by default).

= 0.33.0 =
Product pages for every product, a new product details box and a clearer product page: description, your text, price comparison, technical data. Existing product pages get the new sections automatically; each can be switched off under Settings → Product pages.

= 0.32.0 =
Earnings per box type: affiliate links now also carry the box type (Awin clickref4, eBay custom ID), so Reporting can show which boxes earn money. Existing link parameters are never overwritten.

= 0.31.0 =
New Elementor widgets for all affilinode boxes. Nothing changes on sites without Elementor.

= 0.30.0 =
Options, tables, scheduled tasks, hooks and shortcodes now use the prefix "affilinode_". Existing data is converted automatically on the first page load after the update; old shortcodes like [ac_product], old blocks and the old webhook address keep working.

= 0.29.0 =
The plugin folder is now "affilinode". If the old "affiliate-central" folder is still installed, deactivate and delete it – all settings are kept.

== Changelog ==

= 0.72.0 =
* New: Amazon as a link only. A product can carry an Amazon link without any Amazon data: all boxes show a button "View at Amazon" without a price, with your tracking ID and the usual disclosure ("Ad", Amazon Associates notice). It never counts for the best price, the order, the price history or the cart button, and never shows a price, image or stock from Amazon. Title, image and prices come from the other shops. The entry is created in the affilinode dashboard (Products → "Add Amazon link"); once your Amazon interface is active, the same link turns into a normal Amazon offer with prices by itself.
* New: Moving Amazon links (SiteStripe) without the Amazon interface. A new option takes the links over as "Amazon link only": each ASIN is attached to the matching product you already have (or one from other shops), nothing is invented for the rest. The move also looks into the fields of page builders (Oxygen, Elementor, Bricks, Beaver Builder, SiteOrigin; filter `affilinode_migration_meta_keys` for own fields), reads the country of a link from its address, and removes the 1×1 counting pixel of the old SiteStripe output when it converts a link. A tracking ID ending such as -21 only decides the country where your website serves exactly one matching country.
* New: `title` and `title_style` now work in `[affilinode_offers]`, `[affilinode_button]`, `[affilinode_price_history]`, `[affilinode_products]` (`title` = heading above the cards), `[affilinode_compare]` (`title` = heading above the table), `[affilinode_compare_picker]`, `[affilinode_spare_parts]`, `[affilinode_accessories]` (`title` with text = own heading) and `[affilinode_tariffs]`. Until now these attributes were ignored there, so the code generator in the dashboard left them out for WordPress.
* New: Move from the Affiliate Toolkit takes over test ratings: test score, test result, test date, pros and cons, badge and review text become the product's test rating in affilinode – only where the score and its scale are clear, and never over an existing rating or text.
* New: Move from the Affiliate Toolkit shows a preview before transferring: products with ratings, dynamic lists and their stored results, content without an equivalent (manual offers, variations, own templates), and the posts that use shortcodes and blocks with the options that are not available in affilinode.
* New: Affiliate Toolkit compatibility now covers the product and list blocks, [atkp ids="1,2,3"], asin="…" and ean="…" instead of id, tracking_id="…", field="…", link="yes", product_ids="…", names instead of numbers as id, and the sidebar widget. Options without an equivalent (random order, pagination, filters) show a note for editors at that place.
* New: [affilinode_field] has the option link="1": the field value (price, title …) is the affiliate link.
* Fixed: Move from the Affiliate Toolkit recognises the list type the way the Affiliate Toolkit stores it: bestsellers, new releases and searches are no longer all treated alike, and a list that was switched back to manual is transferred as a manual list.
* Fixed: Move from the Affiliate Toolkit takes over the stored result of dynamic lists (previously these lists arrived empty) as a fixed list, and tells you that such a list no longer reloads from the shop.
* Fixed: Move from the Affiliate Toolkit reads up to ten offers per product (previously five), skips list entries whose product is in the trash, and reports entries that cannot be taken over.
* New: Feature filter for the deals box. `[affilinode_deals filter="matter=native"]` shows only products that have this feature; several values of one feature are separated by commas, several features by semicolons (`filter="matter=native;matter_version=1.3,1.4"`). Products without the feature are left out. The filter is also available in the deals block and in the shortcode generator.
* New: Price context in the deals box. Each deal can carry a note such as "Lowest price in the last 90 days" or "12.00 € below the average of other shops" (only shown when the recorded history or the number of comparable shops supports it). New attributes `best="90"` (only deals whose price is the lowest of the last 7–365 days) and `min_offers="2"` (at least that many shops with a current price) on `[affilinode_deals]`, in the deals block and in the shortcode generator.
* Changed: Price comparison and best price now only contain new goods; used, refurbished and B-stock offers are delivered separately by the API (`usedOffers`).
* New: "Used" tab next to "New" in the price comparison (open box, B-stock, refurbished with condition labels; pack size tabs stay inside "New"), and a note "Also available used from …" under the price in the product box. Used prices never count as best price and carry no savings.
* New: Optional price comparison dialog on the product box. `[affilinode_product id="…" popup="1"]` adds a "Compare all prices" button that opens the comparison with one tab per pack size and the "Used" tab. Native dialog (keyboard, focus trap, Esc), full screen on phones. Off by default; also in the shortcode generator.
* New: Colour swatches in the variant picker now use the colour the affilinode platform recognised for each variant (white, black, anthracite, rose gold, black/white …) instead of guessing from the name, so a variant called "Nachtschwarz" or "Space Grey" gets the right swatch. Products that only differ by colour are suggested as variants in the dashboard.

= 0.71.0 =
* Removed: The free "Custom CSS" field in the settings and the CSS field of custom templates. Colours, button size, corner radius and badge colours stay in the settings; for your own styles use Appearance → Customize → Additional CSS. CSS you entered earlier is no longer applied; the settings and template pages show it once so you can copy it.
* Changed: Custom templates are always filtered to a fixed list of HTML elements and attributes, for every user – no scripts, event attributes, inline styles or style elements.
* Changed: The previews in the settings, the template editor and the shortcode generator load as a separate preview page with the normal WordPress style handling.
* Changed: WP-CLI `settings export` prints to the standard output; with `--file=<name>` it writes to wp-content/uploads/affilinode/. `settings import` reads from there or from the standard input. The MaxMind database is stored in the same folder.
* Changed: Notices of the plugin only appear on its own pages and can be dismissed. The hint asking for the "Made with affilinode" link on the settings page is gone.
* Fixed: Permission and nonce are checked before any form data is read in all admin actions, and every output is escaped where it is printed.
* Fixed: The address shown for the webhook uses the REST address of your site.

= 0.70.2 =
* Fixed: Hardened the scripts of the product search, product advisor, comparison picker, price alert, back-in-stock notification, coupons, tariff calculator and variant picker against manipulated markup in posts. They only talk to your own website and only take content from it.
* Fixed: Hardened the automatic rel fix of the disclosure check. Posts changed by the plugin (disclosure check, link guard, converting old shortcodes) are cleaned like a normal save unless you or the author may use unfiltered HTML.
* Fixed: Price updates only pause when the affilinode service is actually unavailable. The public product search only accepts valid product types, and the deals feed limits new queries per visitor and per hour.
* Changed: The links in price alert and back-in-stock emails open a page with a button – confirming or deleting only happens with a click, so mail scanners that open links no longer confirm anything. Unconfirmed links expire after seven days. One-click unsubscribe from the mail program still works.
* Changed: Signing up again for a product with a running price alert keeps the running alert until the new sign-up is confirmed.
* Changed: Choosing a match or closing a request in the product import requires the right to publish posts; contributors see the matches with a note.
* Changed: Templates of administrators without the unfiltered HTML capability no longer keep data: addresses (except images) or configuration attributes of the plugin scripts.
* Changed: Behind a proxy or CDN, rate limits can count the real visitor address via the filter `affilinode_client_ip`.
* Changed: The settings export says more clearly that secret keys (now also listing the Cloudflare token) are only included when you tick "Include secret keys".

= 0.70.1 =
* Fixed: A box whose product data could not be loaded (API key missing, rejected or unreachable) stayed completely empty, so the block editor only said "Block rendered as empty." Editors now see why, and visitors get the box loaded afterwards again.
* Changed: Blocks that have nothing to show now explain it in the editor, with a link to the affilinode settings. The note for an unknown product mentions that it may belong to another account or no longer be active.

= 0.70.0 =
* New: Product advisor: questions can depend on earlier answers – a question only appears if an earlier answer matches ("only ask if …" in the dashboard). Progress, question numbers and the "Next" button follow the questions that are actually asked; answers to skipped questions are ignored, even in an old link.
* New: Product advisor: the dashboard shows where visitors drop out – per question how many saw it and how many left afterwards ("Question 3 loses 40 %"), plus suggestions such as shortening the options. Only anonymous daily totals per question are counted, without cookies or IP addresses; shared links do not count.
* New: Product advisor: "Show prices" per advisor. Switched off, the result shows the product, the reasons and the button to the offer, but no price.
* Improved: Product advisor: the link to the answers is also offered after the result has loaded without a page reload.
* Changed: Reviews with source: star ratings are only shown together with their source note (source, date, number of reviews and a note on whether they are checked for authenticity). The stars only appear when the source is approved and "Show reviews" is switched on for the website.
* New: Move from Affiliate Toolkit: optionally takes over the texts of the product posts as product descriptions (and excerpts as short descriptions; without an excerpt the short description is made from the start of the description). Shortcodes, scripts, images and affiliate links are removed before the transfer, existing texts in affilinode are never overwritten, and your posts stay unchanged. The preview shows how many posts have a text.
* New: Product box: `docs="1"` shows a "Downloads" list below the box (data sheet, user manual, quick start guide, energy label, declaration of conformity) with links to the original source and, for energy labels, the EPREL entry.
* Changed: The running-cost calculator now uses the operating power value when a data sheet lists power consumption separately for operating, idle, standby and off.
* Changed: Price alerts sent via affilinode are only emailed after a real, lasting price drop (the price has held for several hours and is clearly below the usual price of the previous 30 days, based on affilinode's own price record). An alert that has reached its target price but not yet passed this check stays active and is checked again the next hour. When the record backs it up, the email states how far the price is below the 30-day average. Alerts sent through WordPress (wp_mail) are unchanged.

= 0.69.0 =
* New: "Add to the Amazon cart" can now be switched on or off per box – shortcode attribute `cart="1"` or `cart="0"` on product boxes, grids, lists, comparisons, the price comparison and `[affilinode_button]` (also in the block editor and the shortcode generator). Without the attribute the setting under Display applies as before.
* Changed: The cart button only appears where Amazon can actually credit it – for offers with your Amazon partner tag. Amazon links from seller networks, links without a tag and short links stay normal buttons with their normal label.
* New: Device + tariffs box with three views: `view="full"` (default), `view="compact"` ("Phone + tariff": the device and a few tariffs in slim rows) and `view="details"` ("Tariff details": a data sheet with every known value – provider, network, data allowance, calls and text flat rates, 5G/LTE, speed, EU roaming, Wi-Fi calling, VoLTE, eSIM, multi-SIM, hotspot, term, cancellation, prices, bonus, note of the provider). Values that are unknown are not shown – never guessed as "no".
* New: `[affilinode_tariffs]` can be limited to one provider or network (`provider="telekom"`, `network="o2"`; also in the block and the generator).
* Changed: Tariff prices are labelled exactly: "monthly", "one-off", "incl. connection fee", term in months, a promotional price for the first months and the total cost over the term; the effective monthly price is calculated with the promotional price.
* Changed: Amazon links from seller networks (Levanta, PartnerBoost, Archer Affiliates) are output exactly as the API delivers them – the tracking ID of a post or shortcode is no longer added to them, and they never run through your own redirects. The "As an Amazon Associate …" notice appears under a box, in link previews and in the notice check only for offers that go through your Amazon partner tag; seller-network links get the general affiliate notice only. The notice check now recognises seller-network links as affiliate links.
* Changed: Clearer texts in the settings: the help text of "Test connection" no longer names technical details, and the German connection message speaks of your account.
* New: Model products. A product that stands for a whole model (“Apple iPhone 18 Pro”) groups its variants – colours and storage sizes. Its product box shows the lowest price (“from …”) and a variant picker with chips for colour and storage; choosing a chip switches the image, price, shipping details and the button to that variant without reloading. Without JavaScript and on AMP pages the list of variant links stays. The picker appears on its own for model products; `variants="0"` turns it off, `variants="1"` still shows the link list for classic parent products.
* New: Cards, rows and every other box show “from <lowest price>” for model products; the button leads to the cheapest offer in the visitor’s country.
* Changed: The "Made with affilinode" link is never forced – on any plan, including the free one. The setting "Show the Made with affilinode link" (Settings → Layout) is now always visible and editable (Default / On / Off), with or without API key. A choice made here wins in both directions; with "Default" the link is off, or follows the switch of the website in the affilinode dashboard (paid plans). There is only one plugin build now (no separate WordPress.org build). An existing "on" setting stays on.
* Changed: Requires WordPress 6.5 or newer (the plugin already used `array_is_list()`; Plugin Check reported this as an error with 6.4).
* Fixed: Checks of the official Plugin Check (strip_tags, parse_url, suppress_filters, missing translators comment, escaping of an exception message) – no change in behaviour; the template name in the template editor is now sanitized with `sanitize_text_field()`.

= 0.68.0 =
* New: Accessories – `[affilinode_accessories id="…"]` and the block "Accessories" (also in the shortcode generator) show the accessories assigned to a product (case, screen protector, charger, cable, holder …), grouped by type with price and button, like the spare parts box but with its own heading ("Accessories for …"). Accessories are not spare parts: they are sold alongside and fit many devices. Variants show the accessories of their main product. Accessories are assigned in the affilinode dashboard (product → "Accessories", bulk action "Assign as accessory …") or suggested automatically from the product data. Own box type "Accessories" in the click statistics.
* Fixed: Fatal error "Call to undefined function wp_salt()" when the plugin loads on a site (seen on multisite) with a stored API key – introduced in 0.67.0. The encrypted API key is now only read once WordPress has loaded its salts; earlier it counts as not yet readable.

= 0.67.0 =
* Changed: Readme "External services" – Contextual Ads+ analyses submitted posts with affilinode's own model or Google Gemini via Vertex AI (EU); comments, e-mail addresses, phone numbers and links to people are removed first.
* New: WordPress.org build of the plugin: the "Made with affilinode" link only appears after you switch it on under Settings → Layout ("Show the Made with affilinode link", default off) – on every plan, including the free one. On the free plan the settings page shows a friendly, dismissible note asking for support; no feature depends on it.
* New: Small "Made with affilinode" link below boxes (product box, comparison, lists, tables, bestsellers, search, vouchers, context boxes and more) – always on the free plan, optional on paid plans (default off, switched per site in the affilinode dashboard). It is not shown below text links, inline buttons or in demo mode. Accessible (new-tab hint for screen readers), follows the box colour scheme including dark mode.
* Changed: "Test connection" now also refreshes plan, policies and the "Made with affilinode" setting right away instead of after up to 12 hours.
* New: Banner box `[affilinode_banner]`: an ad banner of your partner programs (imported from ADCELL and Webgains, uploaded for Awin, Tradedoubler, eBay or your own) in the format that fits – by banner ID, shop, program or network, with `format`, `max_width`, `label` and `consent`; block "Banner", Elementor and shortcode generator. Marked as an ad, `rel="sponsored"`, tracking link with box type "banner". Never from Amazon.
* New: Banners on affilinode's CDN are a responsive `<picture>` (one size per screen width, lazy loading) – no third-party request until the click. Banners delivered by the network show a placeholder with "Load banner" and only load after the click, with `consent="direct"`, `window.affilinodeConsent = true` or the `affilinode:consent` event; original HTML code only in a sandboxed iframe. AMP pages show CDN banners only, without extra CSS.
* New: Filter `affilinode_banner_consent` adds `cons=1`/`cons=0` to Awin banner links; in the browser `window.affilinodeConsent` does the same.
* New: Views and clicks per banner (with box statistics on): counted in the browser, summed up per day and sent to affilinode at most every 10 minutes without blocking the page.
* New: "Shop my look" `[affilinode_look id="…"]`: a picture from the affilinode dashboard with numbered spots on the products shown and the product list below it – by the code of the look or its copied address, with `title` and `heading`; block "Shop my look" and shortcode generator. Works without JavaScript: the spots are anchors to their entry in the list (price, shop, button), keyboard and screen reader friendly.
* New: Products of a look are routed by the visitor's country like on affilinode bio pages; Amazon buttons link directly to Amazon ("View on Amazon"), Amazon prices are shown only from the API and at most 24 hours old (also from the cache). Other clicks are counted per spot in the affilinode dashboard (source "WordPress plugin"). Marked as an ad with the Amazon Associates notice where needed. AMP pages show the pictures and the list without spots and without extra CSS.
* New: Voucher box shows your own discount codes (affilinode dashboard → Links → Discount codes) first, also for sponsors without a shop; copying such a code is counted anonymously ("Code copied", only the code ID via the site's REST route, never on AMP).
* New: Social assistant (Products → Geo short link) offers ready-to-copy texts with your own discount codes and the new short link.
* Fixed: A shop released only for one country (e.g. Austria) no longer appears for visitors from another country (e.g. Germany) – the API now applies each shop's country release to all offers, best prices and lists.
* Fixed: Automatic Amazon search links no longer fall back to the marketplace of another country; without an Amazon shop for the page's country no category link is created.
* Changed: Detecting other affiliate plugins (AAWP, Affiliate Toolkit, AffiliateTheme, Lasso, AmaLinks Pro, ASA) no longer scans the posts table during a visitor request. Visitors get the last known result (nothing known yet: not detected) and the check is renewed in the background (single wp-cron event); the admin area and WP-CLI still check immediately.
* Changed: The account policies and plan features are no longer requested while a visitor waits. The last stored state is used and renewed in the background; in the admin area (first setup, “Test connection”) it is still requested immediately.
* Changed: The rate limit of the lazy loader, redirects and coupon copy reports uses the persistent object cache when one exists (no more database rows per call).
* Changed: Search, advisor and compatibility boxes limit new (uncached) queries per visitor and per hour and site, and long address parameters are shortened, so made-up query strings cannot create unlimited cache entries and API requests (filter `affilinode_query_budget`, default 300 per hour and kind).
* Changed: Shortcodes in active text, block and HTML widgets and in block templates / template parts edited in the Site Editor are now loaded together with the post's products in one request (one batch instead of one request per shortcode after a cache flush).
* Changed: All blocks now use block API version 3, so the post editor can run in an iframe (WordPress 6.3+) and is no longer held back by affilinode blocks.
* Added: Banner boxes read the marketing consent from the WP Consent API, Complianz, Borlabs Cookie and Cookiebot (read-only) in addition to `window.affilinodeConsent` and the `affilinode:consent` event, and load the original banners as soon as consent is given.
* Changed: Faster page loads without a persistent object cache – settings, cache generation and the table/rule markers are now autoloaded options (one query less each, existing sites are converted once), and the cached products of a page and the transients of the plugin detection (AAWP, ATKP, Lasso and others) are preloaded with a single database query instead of two per entry.
* Changed: If the affilinode API times out or answers with a server error while loading products for a page, the remaining batches are no longer requested (visitors waited up to n × 3 seconds before).
* Changed: The block editor data (field descriptions and strings of all blocks) and the style handles for the editor are only prepared in the admin area, and the front end only looks for shortcodes that are really used in a post.
* Fixed: Deactivating the plugin now also removes scheduled background tasks with arguments (product refreshes, content sync, page cache checks); deleting the plugin also removes the banner statistics, price alert statistics, shop notes and versus rules options.
* Fixed: The disclosure check no longer fails on servers without the PHP extension mbstring.

= Earlier versions =
* See changelog.txt for older versions.
* See https://affilinode.com/wordpress/changelog
