=== Kukuriya ===
Contributors: piftoworks
Tags: affiliate, amazon, rakuten, yahoo
Requires at least: 6.6
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 0.12.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Manage affiliate links from multiple ASPs as one product. Search and insert in the Block Editor, register by URL paste, auto-update prices.

== Description ==

**Kukuriya** is a WordPress plugin that bundles product links from multiple affiliate service providers (ASPs) into a single "product" and manages them in one place. It is fully integrated with the Block Editor, covering everything from product search to card rendering, comparison tables, and automatic price updates.

It is aimed at people migrating from Pochipp, affiliate marketers struggling with the Amazon API entry barrier, and anyone who wants to manage multiple ASPs across one site.

= Key features =

* **Universal Link**: one product = a set of offers from multiple ASPs. A data model that lets you serve the best link depending on user, stock, and price
* **Connector architecture**: every ASP integration is an isolated connector module. Five official connectors ship built in and can be toggled per site, and third-party connectors can be added as separate plugins via a public hook
* **Modern Block Editor**: product search modal, block insertion, and attribute editing UI built with TypeScript + React 18 + `@wordpress/scripts`
* **One-action registration by URL paste**: paste a Rakuten or Amazon product page URL into the Block Editor to identify, fetch, and register the product CPT automatically. SiteStripe short URLs (`amzn.to` / `amzn.asia`) are expanded automatically. Also useful as a rescue path for products that do not appear in search results
* **5 built-in card templates**: Simple / Card / Compact / Pochipp compatible (visual parity for migrating users), plus a comparison table block for up to 10 products
* **Comparison tables you can actually shape**: reorder the rows, add your own from custom fields or free text, mark cells with ◎ ○ △ ×, turn a cell into a bullet list, highlight the one that decides it, put the products down the side instead of across the top, give each column its own button text and colour, and add a heading above the table
* **Design controls**: 4 visual presets (Neo / Outline / Glass / Bold), custom card frames (width / color), button styles (solid / outlined / gradient / raised), an optional "See reviews" link, and animated frame and button effects (glow, pulse, shine, aurora) that pause automatically for visitors who prefer reduced motion — configurable site-wide or per block
* **Custom fields**: add per-product spec fields in 5 types (text / number / select / boolean / date) with editing and CSV round-trip support
* **CSV import / export**: full CSV round-trip including custom fields, with dry-run validation
* **Pochipp migration**: import products and affiliate URLs from an existing Pochipp install (CPT `pochipps`). Amazon ASIN / Rakuten item code / Yahoo seller_id + itemcode are mapped automatically
* **Automatic price refresh cron**: re-fetches Amazon / Rakuten / Yahoo prices every 6 hours. Failed items are retried with interval protection for stable operation
* **Click tracking on your own site (anonymized)**: a small script reports purchase-button clicks to your site's own REST API and the dashboard shows which products, stores and posts get clicked. IP / UA are hashed with HMAC-SHA256, referrers keep the host only, no cookies. Can be switched off under "Measurement"
* **Automatic product description generation (external API)**: a Composer Service that can call a vendor-neutral Messages-style API. Users configure their own API key
* **Optional credit**: off by default. If you want to show where the cards come from, a switch under Design adds a small mark and the name "Kukuriya" at the bottom right of cards and comparison tables. It is never a link, and nothing about the plugin depends on it
* **Internationalization**: every string is translatable (text domain: `kukuriya`). Translation contributions via translate.wordpress.org are welcome

= Supported ASPs (all built in — enable the ones you use) =

* **Amazon** (Creators API, 15 marketplaces)
* **Rakuten Ichiba** (Rakuten IchibaItem Search API v2)
* **Yahoo! Shopping** (Shopping Web Service V3 + ValueCommerce affiliate URL support)
* **Moshimo Affiliate** (link conversion; an alternative route without Amazon keys)
* **Mercari** (Mercari Ambassador: your afid is appended to Mercari links — search links and per-product links)
* **Manual entry (A8.net / afb / ValueCommerce, etc.)** (a generic connector for ASPs without a product API)

= Usage notes =

* The Amazon Creators API requires per-account credentials (a central proxy model is not permitted under its licence)
* Amazon grants API access only to accounts with at least 10 qualifying sales in the trailing 30 days. The Moshimo Affiliate route can be used as an alternative
* Please follow the terms of service of each ASP

== External services ==

This plugin talks to the shopping services whose connectors you turn on, using API keys that you supply. Nothing is sent anywhere until you enter credentials and enable a connector, and no data is ever sent to the plugin author.

= Amazon Product Advertising / Creators API (Login with Amazon) =

This plugin connects to Amazon's product API to search Amazon's catalogue and to obtain a product's title, image, price and availability. It is needed to show the product cards you place in your posts and to keep their prices current. It is used only if you turn on the Amazon connector and enter your own credentials.

It sends your Client ID and Client Secret to obtain an access token (`api.amazon.com`, `api.amazon.co.jp` or `api.amazon.co.uk`, depending on the marketplace you choose), and then, on each product search, scheduled price refresh and card render that misses the cache, it sends the search keyword or product ASIN together with that token and your Associates tag. The scheduled refresh runs every 6 hours for products you have registered. If you paste a SiteStripe short URL (`amzn.to` or `amzn.asia`) into the editor, your site also makes one request to that address to find out which product it points to.

This service is provided by "Amazon.com, Inc.": [terms of use](https://affiliate.amazon.co.jp/help/operating/agreement), [privacy policy](https://www.amazon.co.jp/gp/help/customer/display.html?nodeId=GX7NJQ4ZB8MHFRNJ).

= Rakuten Web Service (Rakuten Ichiba Item Search API) =

This plugin connects to the Rakuten Ichiba Item Search API at `openapi.rakuten.co.jp` to search Rakuten Ichiba and to obtain a product's title, image, price and availability. It is needed to show the product cards you place in your posts and to keep their prices current. It is used only if you turn on the Rakuten connector and enter your own Application ID and Affiliate ID.

It sends your Application ID and Affiliate ID together with the search keyword or item code, on each product search, scheduled price refresh and card render that misses the cache. The scheduled refresh runs every 6 hours for products you have registered.

This service is provided by "Rakuten Group, Inc.": [terms of use](https://webservice.rakuten.co.jp/guide/rule), [privacy policy](https://privacy.rakuten.co.jp/).

= Yahoo! Shopping Web Service =

This plugin connects to the Yahoo! Shopping Web Service at `shopping.yahooapis.jp` to search Yahoo! Shopping and to obtain a product's title, image, price and availability. It is needed to show the product cards you place in your posts and to keep their prices current. It is used only if you turn on the Yahoo connector and enter your own Client ID.

It sends your Client ID together with the search keyword or item code, on each product search, scheduled price refresh and card render that misses the cache. The scheduled refresh runs every 6 hours for products you have registered.

This service is provided by "LY Corporation": [terms of use](https://www.lycorp.co.jp/ja/company/terms/), [privacy policy](https://www.lycorp.co.jp/ja/company/privacypolicy/), [developer guidelines](https://developer.yahoo.co.jp/guideline/).

= A text generation API of your choosing (optional, off by default) =

The optional "generate a product description" button sends a prompt to an API endpoint that **you** enter in the settings. The plugin does not pick a provider for you and ships no endpoint, no key and no default address of its own. If you leave the setting empty, nothing is ever sent and the button does nothing.

It sends, only when you press that button, a prompt containing the product's title, price and categories, plus the API key you entered, to the endpoint you entered.

This service is provided by whichever company you configure. Its terms of use and privacy policy are that company's own. Please read them before entering an endpoint and a key.

= Your analytics service (optional, off by default) =

If you turn on click measurement under "Measurement", clicks on purchase buttons are reported to the analytics service whose tag is already installed on your site by you or your theme. This plugin bundles no analytics tag and adds none; your server sends nothing. The reader's browser reports the click through that existing tag.

It sends, on a click — the product ID, the product name (first 60 characters), which store was clicked, whether the link went to a product page or to search results, and which card in the article it was. The affiliate URL, IP addresses, user agents and post content are never included.

This service is provided by whichever analytics company you already use. Its terms of use and privacy policy are that company's own.

= Services this plugin does NOT contact =

Moshimo Affiliate, A8.net, afb, ValueCommerce and Mercari are supported by building the correct affiliate URL on your own server, from the IDs you enter. The plugin makes no request to any of them, and sends them no data. Their addresses appear in the source code only as the destination your visitors' own browsers go to when they click a link.

== Source code and build ==

The admin screens and editor blocks are written in TypeScript and SCSS and compiled with `@wordpress/scripts` (webpack). The uncompiled sources are included in this plugin under `assets/src/`, next to the compiled output in `build/`, together with `package.json`, `webpack.config.js` and `tsconfig.json`.

To reproduce the compiled files, with Node.js 20 or later:

`npm install`
`npm run build`

No third-party JavaScript libraries are bundled. Everything the scripts use at runtime (`@wordpress/element`, `@wordpress/components`, and so on) is provided by WordPress itself.

== Installation ==

= Basic setup =

1. Search for `Kukuriya` under "Add New" in the Plugins screen, install, and activate
2. Open the "Kukuriya" admin menu, and in the "Connectors" tab turn on the ASPs you use and enter each connector's API keys (for example, Rakuten needs an Application ID and an Affiliate ID)
3. Add the "Kukuriya Product" block in the post / page editor, then search and insert

= Admin tabs =

* **Dashboard**: price refresh cron status and recent click summaries
* **Custom fields**: CRUD for your own spec fields
* **CSV import / export**: bulk migration of existing product data
* **Migration**: import from Pochipp

= Using the manual-entry connector route =

ASPs that do not provide a product API, such as A8.net and afb, can be handled with the built-in manual-entry (Generic) connector by registering a URL template manually.

== Frequently Asked Questions ==

= Is it free? =

Yes. Everything in this plugin is free and fully functional GPL v2+ open source, including all five official connectors. Nothing here is locked behind a licence.

A separate paid add-on plugin (Kukuriya Pro, distributed from piftoworks.com) adds sale campaigns and bulk editing. It is not required, and none of its code is part of this plugin.

= Are API keys stored securely? =

Yes. All API keys are encrypted with AES-256-GCM, protected by a key derived from `AUTH_KEY` in `wp-config.php`. Keys are separated per connector ID, so API keys cannot be decrypted even with direct database access.

= Can I migrate from Pochipp? =

Yes. You can import Pochipp data (CPT `pochipps`) from the "Migration" tab in the admin screen. The primary ASP is determined automatically in the order of Amazon ASIN / Rakuten item code / Yahoo `seller_id + itemcode`, and each post is converted into a Kukuriya product with Universal Link offers. A dry-run mode lets you check counts and errors before committing.

Generic CSV import is also supported, so migrating from tools other than Pochipp is flexible as well.

= Does the plugin send data to third parties? =

No data is ever sent to the plugin developer (Pifto Works). Product API calls go directly to each ASP, using the API keys that you configure yourself. See the "External services" section above for exactly what is sent, to whom, and when.

= Does click tracking protect visitor privacy? =

Clicks are recorded in your own database only (the `wp_bcore_clicks` table); nothing is sent to the plugin developer. IP addresses and User-Agents are stored as HMAC-SHA256 hashes (salted from `AUTH_KEY`) and the original values cannot be recovered. Referrers keep the host name only (path / query are discarded). No cookies are used — a per-tab session ID lives in `sessionStorage` and disappears when the tab closes — so cookie consent management is not required. Rows are deleted after 90 days. Recording is on by default and can be switched off under "Measurement".

= What happens to my data when I uninstall? =

By default, the 5 `wp_bcore_*` tables (`credentials` / `offers` / `clicks` / `custom_fields_def` / `custom_fields_value`) and related options / cron events are deleted. To keep the data, set the option `bcore_keep_data_on_uninstall` to `true` before deleting the plugin.

The products and the self-made links you registered are ordinary posts (custom post types `bcore_product` / `bcore_link`) and are left in place, the same way WordPress leaves posts when a plugin is removed. Delete them from the database if you want a clean slate.

= Does it work on Multisite? =

It works technically, but this version targets per-site operation. Network-wide aggregation and cross-site management are not implemented.

= Is there product caching? =

Yes. Each connector's API responses are cached short-term via the WP Transient API. The price refresh cron persists into the `wp_bcore_offers` table independently of the cache, so front-end rendering stays fast at all times.

= Can I write a connector for a new ASP myself? =

Yes. You can distribute an independent WP plugin that implements `PiftoWorks\Kukuriya\Contracts\ConnectorInterface`. Register it with the core via the `kukuriya_register_connectors` hook, and it can use the core's search UI, price refresh cron, click tracking, and other infrastructure as-is.

= Does it work with the Classic Editor? =

The `[bcore_product]` / `[bcore_comparison]` shortcodes render products and comparison tables in the Classic Editor as well. The Block Editor search UI is not available there, so the workflow is to import product data via CSV and then reference it by post_id.

== Privacy Policy ==

Kukuriya stores the following anonymized data for click tracking (in the `wp_bcore_clicks` table):

* HMAC-SHA256 hash of the IP address (64 hex chars)
* HMAC-SHA256 hash of the User-Agent (64 hex chars)
* Referrer host name only (no path / query)
* An opaque per-tab session ID generated client-side in `sessionStorage` (optional)
* Product ID / post ID / which store button / product page or search / card position / timestamp

Raw IPs, raw User-Agents, and full URLs are never stored. No cookies are used. Rows are deleted after 90 days. Recording can be switched off under "Measurement".

By default, external communication happens only with the ASPs you configured, using your own API keys. No data is sent to the plugin developer (Pifto Works) unless you explicitly enable it.

If you enable the automatic product description feature, prompts containing product information (title / price / categories, etc.) are sent to the external generation API endpoint you configured. You choose and configure both the destination endpoint and the API key.

If you enable the opt-in click measurement feature (Kukuriya > Measurement, disabled by default), purchase button clicks are reported to the analytics service whose tag is installed on your site. What is sent: the product ID stored on your site, the product name (truncated to 60 characters), which store button was clicked, whether it linked to a product page or to search results, and which card in the article it was. What is never sent: the affiliate URL itself, IP addresses, user agents, product descriptions, post content, or any user-entered free text. Nothing is transmitted from your server; the reader's browser reports the click through the analytics tag that is already loaded on the page. Turning the setting off stops the transmission immediately.

== Changelog ==

= 0.12.0 =

* New: a price now has a shelf life. A price older than 24 hours is no longer shown as current, and the card falls back to another store whose price is still fresh. Amazon drops API access whenever a site falls under ten qualifying sales in the trailing 30 days, and until now the last price fetched stayed on the page for good.
* New: products whose link has gone are marked in the product list and can be filtered out of it. A dead button becomes a search link for the same product rather than disappearing, so the card keeps its shape.
* New: a product can be tied to the same item at another store by searching for it, instead of pasting the URL by hand. Amazon, Rakuten and Yahoo! Shopping.
* New: a product can be repointed at a different code at the same store, keeping the same product. Posts that already reference it follow along; nothing has to be edited article by article.
* New: the product list shows how many posts use each product, and a product’s own screen lists those posts with a link to each editor.
* New: a Refresh button on a product fetches its price and every one of its offers again, without waiting for the scheduled run.
* New: product categories. Filter the product list by one, see them beside the product name, and add or remove them from the product’s own screen.
* New: a card’s image can be replaced with one from the media library. Remove it and the store’s own image comes back.
* Changed: the card preview on a product’s screen is now clickable, the same as the front end. Affiliate conversion is deliberately not applied — clicking your own links from your own admin screen is not something the ASPs welcome.

= 0.11.0 =

* Fixed: cards that Pochipp kept inside the block itself, rather than in its product list, were left behind when posts were rewritten — and would have vanished the moment Pochipp was switched off. They are now turned into products as the posts are rewritten. The same product used in several posts becomes one product, and a product you have already imported is reused rather than overwritten.
* Added: a card with no product in it is now left in the post untouched, with a line saying why, instead of being passed over in silence.
* Added: the rewrite step can be told to leave those cards alone (the toggle under Step 3).

= 0.10.0 =

* Added: an inline product link can now be aimed at one store (Amazon, Rakuten, and so on) instead of the product's own. The destination is still worked out when the page is drawn, and falls back to the product's own link if that store cannot be reached.
* Added: add-ons can place their own inline product links through the new `kukuriya_inline_link_content` filter. The destination, the affiliate conversion and the click attributes are handled here, so an add-on only marks the text.
* New: a Comparison tables screen lists every comparison table on the site — the post, the products in it, the layout and the heading — and takes you to the post that holds it.
* New: the dashboard lists every post that carries a card, a comparison table, a custom link or an inline product link, with a count of each. Revisions are not counted.
* New: a product's edit screen shows the posts that use it, so you can see what a change will touch.
* Fixed: the card preview on a product's edit screen now draws custom buttons (an official site, for example) with their own label and colour, as the published card does.
* New: change every inline link to one product at once, under Links. Point them at another product, send them to a different store, or take the links off and leave the words. It rewrites the posts, so it runs as a dry run until you say otherwise, and you can try it on one post first.

= 0.9.0 =

* New: comparison tables are now built from a list of rows you control. Reorder the built-in rows (image, name, price, rating, button), add your own from a custom field or by typing the values, and drop a row you do not need.
* New: mark a cell with ◎ ○ △ ×. The symbol is drawn large and pale; when the cell also has a value, the value sits on top of the symbol. Screen readers hear a word, not the symbol.
* New: write one item per line and the cell becomes a list. Start a line with `+`, `-` or `~` to prefix it with ○, × or △.
* New: put the products down the side instead of across the top, for tables with two or three products and many rows.
* New: a heading above the table, read before the table by screen readers.
* New: each column can have its own button text, button colour and label colour.
* New: a short line of copy can sit above a comparison table, the same way it can above a card.
* Changed: ratings now draw five stars and fill them by the share of the maximum, so 4.5 out of 5 reads at a glance.
* Changed: comparison buttons are larger (about 41px tall) and fill the column, in line with Apple's and Google's touch target guidance. The default store colours are a step brighter while keeping white text readable.
* Changed: the product photo in a comparison table is now a link, like the photo on a card.
* Changed: drag the table sideways with the mouse to scroll it. Shift and the wheel still work, and the hint now says so.
* Changed: adding products to a comparison table no longer closes the picker each time. Products already in the table are marked as added.
* Changed: public hook names are now all `kukuriya_*`. If you used one of the old `bcore_*` or `bcore/*` names, rename it; the old names no longer fire.
* Changed: DTOs can be built from an array with `from_array()`. Positional constructors are internal and may gain arguments.
* Changed: the custom fields REST route is now `/kukuriya/v1/custom-fields`.
* Removed: the short link redirect and its post type, and two post types that were registered but never used.
* Added: click measurement now records to your own site as well, with the store, link type and position of the button. Addresses and user agents are hashed, no cookie is set, and rows are pruned after 90 days. It can be turned off under Measurement.
* New: select some text in the editor and turn it into a product link from the toolbar. The selected words become the search term. Only the product is saved in the post — the destination is worked out each time the page is drawn, so changing where your links point does not mean editing posts.

= 0.8.0 =

* Fixed: the animated frame and button effects (glow, pulse, shine, aurora, and the Shine sweep / Glow pulse button styles) could be selected but had no visible result. Their styles were still packaged with the paid add-on. The styles now ship here, which is what 0.7.0 already described.
* Changed: tabs added by add-ons now render their own screen. Previously an add-on could add a tab, but opening it showed the dashboard.
* Added: daily click totals can now be read per day, per store and per post. Nothing is sent anywhere; add-ons and reports use it locally.
* Changed: affiliate code pasted into a custom link is now filtered through an allow list of tags and attributes when it is printed, in addition to the existing permission check when it is saved. Link and banner code from Moshimo, A8.net, afb, ValueCommerce, Rakuten and Amazon is unaffected, including protocol-relative addresses and 1x1 impression images. Code that relies on a script tag is refused when you save it, with the tag named, rather than being dropped silently at display time. A site that needs such code can extend the allow list with the `kukuriya_link_allowed_html` filter.
* Changed: the visitor's address, user agent and referrer are now sanitized as they are read, rather than only being hashed before storage.
* Changed: the compatibility version is declared in this readme only. It was previously repeated in the plugin header, where a different value could have taken precedence.
* Fixed: a product registered from the block editor, by search or by pasting a URL, had no store buttons on its card. The product was saved but its offer was not, and the buttons are built from the offer. Products imported from Pochipp and products added from the admin screen were not affected.
* Added: the product block now previews the finished card in the editor instead of a grey box. Use the toolbar to swap the product or return to the search form.
* Added: the product picker now opens on the products you have already saved, so a product can be reused in another post without searching for it again. The old search is still there on the second tab.
* Changed: the Simple card template now shows the store buttons, like the other templates. It is the default for the block, and a card with nothing to click on is not much use. Its layout is unchanged otherwise: still no brand or rating.

= 0.7.0 =

* Renamed from the previous working title to **Kukuriya**. The text domain and REST namespace changed accordingly.
* Changed: frame and button animation effects (glow, pulse, shine, aurora) are now part of this plugin and work for everyone. They were previously reserved for the paid add-on.
* Removed: the "Cloud integration" tab and its code. The service it talked to is not in operation, so the plugin no longer ships an endpoint it cannot reach.
* Added: the TypeScript / SCSS sources for the bundled admin and block scripts, plus the build configuration, are now included in the plugin so the compiled files can be reproduced.
* Added: an "External services" section in this readme describing every outbound request, what triggers it, and the terms and privacy policy of each service.

= 0.6.0 =

* New: Links. Register text links, banners and ASP-issued code once, place them in articles with a stable key, and change them later from one screen. Articles only hold the key, so changing a link updates every article at once.
* New: Import links already written in articles (scan, dry run, then rewrite). ASP tracking pixels are kept together with their link.
* New: Convert every link reference back to plain HTML before uninstalling, leaving no trace of the plugin in your content.
* New: Links CSV export and import, for moving links between sites by key.
* New (Pro add-on): end dates with automatic pausing, replacement links, and bulk find-and-replace inside links.
* Changed: translations are no longer bundled. Japanese is delivered through translate.wordpress.org.

= 0.5.0 =

First public release on WordPress.org.

* Price refresh now updates the price shown on product cards (not only the Universal Link offers), limits itself to stores that can actually refresh, waits on the local rate gate instead of failing, and backs off on repeated failures
* Database schema is applied on plugin update as well as on activation
* Rakuten / Yahoo! links that are already affiliate links are no longer wrapped twice; the connection test and the route settings now warn when an affiliate ID is missing
* CSV: `offers` column for Universal Link round-trips, partial updates that keep ratings / extra images, unknown `source_id` is rejected, duplicate rows and unreadable prices are reported, Shift_JIS files are detected before upload
* Pochipp migration: rewrites `wp:pochipp/linkbox` blocks and `[pochipp id]` shortcodes in posts, copies API keys / affiliate IDs, runs in batches, keeps your edits on re-run, carries custom buttons over, ignores trashed posts
* Measurement tab shows whether the Analytics CORE tag is detected on the site
* Accessibility: button text colour is chosen by WCAG contrast, product images get a meaningful alt, ratings are announced to screen readers, outline buttons stay readable in dark mode
* Comparison table shows the "as of" note next to prices and respects the hidden-price setting
* Block editor warns when the referenced product has been deleted; wide / full alignment now works
* Click log is pruned after 90 days (filterable); description generation is rate-limited per user

= 0.5.0-beta.7 =

* Fix: the admin stylesheet is now cache-busted by its own file time, so CSS-only updates (like the form spacing fix) reliably reach the browser without a hard refresh

= 0.5.0-beta.6 =

* Admin UI: consistent form spacing across all tabs so each field's help text clearly belongs to its own control (help hugs the control above, larger gap between controls)

= 0.5.0-beta.5 =

* New "move the on-sale store to the front" option (Pro, off by default): while a sale is showing, that store's button is placed first to boost clicks. Campaigns get a "target store" field; the automatic Amazon badge targets Amazon

= 0.5.0-beta.4 =

* Sale campaigns can now recur on days of the month (e.g. Rakuten "5 & 0 days", Yahoo! "5 days") — one-click built-in presets included. The sale shows automatically on those days every month with no date entry, and works on cached pages

= 0.5.0-beta.3 =

* New automatic sale badge (Pro): shows a sale badge when a store's API reports a discount off its list price (Amazon, via the reference price it provides). Only the ASP-provided list price is used, shown live with the "as of" timestamp — no price history is stored, so it stays within each store's API terms

= 0.5.0-beta.2 =

* The product editor preview now shows the sale (ribbon / badge / countdown / coupon) as it will appear on the card
* Apply a sale campaign to many products at once from the Products list (select rows, pick a campaign, apply — or remove the sale from the selection)

= 0.5.0-beta.1 =

* New Sale display (Pro): show a sale badge or corner ribbon, a live countdown, and a tap-to-copy coupon on product cards, with a start/end schedule that switches automatically — even on cached pages
* New Sale tab: define reusable sale campaigns (label, schedule, badge, coupon) once and apply them to products from the Products tab; products can also override any field or run a one-off sale
* The automatic strike-through list price and %OFF badge stay free; the sale campaign layer is Pro

= 0.4.0-beta.5 =

* The product editor preview is now sticky and scales to fit while you scroll through the settings, matching the Design tab

* New Products admin tab: browse and search saved products, rename their display name, and manage per-product card overrides (template / price emphasis / review links). Overrides sit between the site-wide design settings and block-level overrides
* Add offers from other stores by pasting a product page URL — the store's button switches from a search link to a direct product link
* Remove offers per product
* Full per-product design overrides — every design setting (preset, colors, button style, frame & effects, layout) can now be overridden per product, with a live preview using the product's real data
* Per-store link URL overrides and up to 5 custom buttons (label / URL / color) per product, output without affiliate conversion
* Editable offer product-page URLs
* The design form is now a single shared component, so future design options appear in both the Design tab and the product editor automatically

= 0.3.0-beta.7 =

* New "Frame & effects" design settings: give cards a custom frame (width 0-8px, any color) on the Neo / Outline / Glass presets. Bold keeps its signature thick frame
* New frame effects (Pro): Glow (soft breathing light), Pulse (slow blink), Shine (light sweep) and Aurora (rotating gradient frame). All effects pause for visitors who prefer reduced motion
* New button styles: Solid fill / Outlined / Glossy gradient / Raised (3D press) for everyone, plus animated Shine sweep and Glow pulse in Pro. Set site-wide or per block
* One-tap recommended frame recipes in the Design tab
* Review link: an optional "See reviews" link with a speech-bubble icon between the price and the purchase buttons (Amazon via its review page URL, Yahoo! Shopping when the API provides one) — free for everyone
* Click measurement now sends a fixed event name with structured properties (Phase B of the analytics integration); the temporary encoded event names are gone

= 0.2.0-beta.1 =

* All 5 official connectors (Amazon / Rakuten Ichiba / Yahoo! Shopping / Moshimo / manual entry) are now built into the core plugin — no separate connector plugins to install. Each connector can be toggled on or off in the Connectors tab
* New Connectors admin tab: enter and test each ASP's API credentials from an auto-generated settings form
* New monetization routes: choose which connector generates the affiliate link for each source (for example, route Rakuten product links through Moshimo Affiliate)
* Moshimo Affiliate settings now hold a separate set of IDs per merchant (Rakuten Ichiba / Yahoo! Shopping / Amazon), because Moshimo issues different IDs for each partnership — a Rakuten set would not track conversions on Amazon. Paste one ad link per merchant to fill each set, and each source only offers Moshimo as a route once its own set is filled in
* Affiliate URLs are now generated at render time, so changing a route updates existing cards without re-registering products
* Third-party / add-on connectors can still be installed as separate plugins via the `kukuriya_register_connectors` hook

= 0.1.0-beta.1 =

* First beta release
* 5 MVP connectors: Amazon (Creators API) / Rakuten Ichiba / Yahoo! Shopping / Moshimo / manual entry (Generic)
* Block Editor product block + comparison table block
* One-action product registration by URL paste (Rakuten / Amazon / Yahoo product page URLs, plus Amazon SiteStripe short URLs)
* 4 built-in card templates (Simple / Card / Compact / Pochipp compatible)
* Universal Link foundation (`wp_bcore_offers` table)
* WP-Cron automatic price refresh (every 6 hours, with manual trigger)
* Click tracking (anonymized, short URLs, Beacon)
* Automatic product description service (vendor-neutral Messages API)
* Custom fields (text / number / select / boolean / date)
* CSV import / export (custom fields supported, dry-run)
* Pochipp migration (CPT `pochipps` → products + offers)
* Admin dashboard (cron status / click summary / custom field CRUD)
* Cloud integration (Phase 2) skeleton (UI only; backend not yet live)
* Internationalization (all strings translatable via i18n functions)

= 0.1.0-alpha =

* Initial alpha (internal testing)

== Upgrade Notice ==

= 0.12.0 =
Prices older than 24 hours are no longer shown as current; the card uses another store’s fresh price instead. If you would rather keep the old behaviour, the `kukuriya_price_max_age` filter sets the limit (0 for no limit). Nothing you have set up changes.

= 0.11.0 =
If you are moving from Pochipp, run the post rewrite again: cards Pochipp held inside the block instead of its product list are now brought over too. Nothing you have already migrated changes.

= 0.10.0 =
Inline product links can now be aimed at a particular store, and can be changed in bulk from the Links screen. Nothing you have set up changes.

= 0.9.0 =
Comparison tables are rebuilt: rows you choose, ◎ ○ △ × marks, bullet cells, a horizontal layout and bigger buttons. Public hook names are now all `kukuriya_*` — rename any you used, the old ones no longer fire.

= 0.8.0 =
Housekeeping release. Required if you use the paid add-on, which needs this version for its own tabs.

= 0.7.0 =
The plugin is now called Kukuriya. Animated frame and button effects are available to everyone. The unused Cloud integration tab has been removed.

= 0.6.0 =
Adds the Links feature. Translations are no longer bundled: if you need the Japanese admin UI before the language pack is available, place the .mo file in wp-content/languages/plugins/.

= 0.5.0 =

First public release. Existing beta users: prices on cards start refreshing automatically after update; no settings changes needed.

= 0.5.0-beta.1 =

Adds a Pro sale-display layer (badge / countdown / coupon / schedule). No breaking changes.

= 0.3.0-beta.7 =

Adds custom frames, button styles and review links. No breaking changes; existing design settings are kept.

= 0.2.0-beta.1 =

Connectors are now built in. After updating, deactivate and delete the old standalone connector plugins (kukuriya-connector-*); your saved API keys and products are kept.

= 0.1.0-beta.1 =

First beta release. Test thoroughly before applying to a production site.
