{"id":374087,"date":"2026-09-28T18:16:50","date_gmt":"2026-09-28T18:16:50","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/share-cart-by-yindle\/"},"modified":"2026-09-28T17:54:22","modified_gmt":"2026-09-28T17:54:22","slug":"yindle-share-cart","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/yindle-share-cart\/","author":23572266,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.4","stable_tag":"1.0.4","tested":"7.1.2","requires":"6.4","requires_php":"8.1","requires_plugins":null,"header_name":"Yindle Share Cart","header_author":"Yindle B.V.","header_description":"Let customers share a WooCommerce cart with a secure, expiring link. Recipients preview current prices and availability, then deliberately replace or merge their own cart. Works with the classic cart and the Cart Block.","assets_banners_color":"fbfbfc","last_updated":"2026-09-28 17:54:22","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/yindle.com\/downloads\/yindle-share-cart\/","header_author_uri":"https:\/\/yindle.com","rating":0,"author_block_rating":0,"active_installs":0,"downloads":42,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.4":{"tag":"1.0.4","author":"yindle","date":"2026-09-28 17:54:22","revision":3717715}},"upgrade_notice":{"1.0.4":"<p>Security: removes stored capability keys that could hold a copy of your WordPress AUTH salt. Share and revoke links created with earlier versions stop working; recipients need a new link. Shared carts and settings are kept.<\/p>","1.0.3":"<p>Adds atomic rate admission and capability-key initialization, durable multisite\nprivacy cleanup and paged exports. Isolates Free implementation symbols for safe\nedition activation. Existing links, options and data remain readable.<\/p>","1.0.2":"<p>Renamed to Yindle Share Cart (<code>yindle-share-cart<\/code>). Follow the migration steps\nbefore deleting the old plugin. Uses WordPress language packs; all included\nsharing functionality is available without upgrades or unlocks.<\/p>","1.0.1":"<p>Uses distinctive Free runtime class names. Existing carts, links, settings and\nPro compatibility are preserved.<\/p>","1.0.0":"<p>Initial free release. Back up your site before changing editions; existing paid\ninstallations should use the Pro package to retain their paid controls.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3717715,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3717715,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3717715,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3717715,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3717715,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.4"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[3047,215551,210011,20977,286],"plugin_category":[45],"plugin_contributors":[283243],"plugin_business_model":[],"class_list":["post-374087","plugin","type-plugin","status-publish","hentry","plugin_tags-cart","plugin_tags-cart-sharing","plugin_tags-share-cart","plugin_tags-share-link","plugin_tags-woocommerce","plugin_category-ecommerce","plugin_contributors-yindle","plugin_committers-yindle"],"banners":{"banner":"https:\/\/ps.w.org\/yindle-share-cart\/assets\/banner-772x250.png?rev=3717715","banner_2x":"https:\/\/ps.w.org\/yindle-share-cart\/assets\/banner-1544x500.png?rev=3717715","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/yindle-share-cart\/assets\/icon.svg?rev=3717715","icon":"https:\/\/ps.w.org\/yindle-share-cart\/assets\/icon.svg?rev=3717715","icon_2x":false,"generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Yindle Share Cart adds a <strong>Share Cart<\/strong> button to the WooCommerce cart. It\ncreates a link that carries only the products, variations and quantities that\nwere in the cart \u2014 never prices, coupons, customer details or session data.<\/p>\n\n<p>Opening the link shows a preview built from the shop's <strong>current<\/strong> catalogue:\ntoday's prices, today's stock, today's purchase rules. Nothing is added to the\nrecipient's cart until they choose <strong>Replace my current cart<\/strong> or <strong>Merge with\nmy current cart<\/strong> and submit the form.<\/p>\n\n<p>All free features listed below are included and enabled. There is no paid usage\nquota, expiring trial, telemetry, Yindle account requirement or forced credit\nlink on your storefront. Short rate limits protect the public sharing endpoint\nfrom abuse; they do not require payment to reset.<\/p>\n\n<h4>What it does<\/h4>\n\n<ul>\n<li><strong>Share Cart button<\/strong> on the classic cart and the WooCommerce Cart Block.<\/li>\n<li><strong>Capability links.<\/strong> The public link is a 64-character random capability.\nOnly a purpose-separated HMAC-SHA-256 hash of it is ever stored, so a database\ncopy does not hand anyone a working link.<\/li>\n<li><strong>Current-price preview.<\/strong> Prices and availability come from live product\nobjects at the moment the link is opened, not from the snapshot.<\/li>\n<li><strong>Deliberate replace or merge.<\/strong> A GET request only ever renders the preview.\nImporting needs a WordPress nonce, an explicit mode choice and a signed\nsingle-use intent.<\/li>\n<li><strong>Guest revocation.<\/strong> Creating a link also hands the sender a separate\nmanagement capability. It can revoke the link but cannot read the cart, and\nthe read capability cannot revoke anything.<\/li>\n<li><strong>Expiry.<\/strong> 1\u2013365 days, 30 by default, rechecked in the database on every\nrequest rather than relying on a cron run.<\/li>\n<li><strong>Atomic import.<\/strong> The whole plan is validated before the cart is touched. A\nfailure restores the previous cart, its coupons and its session data.<\/li>\n<li><strong>Stock and purchase rules.<\/strong> Product existence, published state, variation\nownership, purchasability, sold-individually, maximum quantity and combined\nmerge quantities are all revalidated at import time.<\/li>\n<li><strong>Privacy.<\/strong> Registered with WordPress's personal-data eraser, and user\ndeletion removes the matching rows.<\/li>\n<li><strong>Classic and Blocks.<\/strong> One server-side service behind both cart renderers.<\/li>\n<\/ul>\n\n<h4>Separate Pro plugin<\/h4>\n\n<p>Share Cart Pro by Yindle is a separate plugin available from Yindle, with named\nsaved carts, account management and printing. These implementations are not\nincluded or locked inside this directory package. Existing published links and\nshared data remain readable when switching editions.<\/p>\n\n<h4>Moving from Share Cart by Yindle 1.0.1<\/h4>\n\n<p>The directory name is now Yindle Share Cart and its folder is <code>yindle-share-cart<\/code>.\nThis is a manual replacement: the older <code>share-cart-by-yindle<\/code> installation\ncannot receive an automatic update across the folder change.<\/p>\n\n<ol>\n<li>Back up your database and plugin files.<\/li>\n<li>In WooCommerce settings, turn off <strong>Delete data on uninstall<\/strong> before\nremoving the old installation. Keep it off when removing an older Pro\ninstallation too; older uninstall scripts do not recognize this new folder.<\/li>\n<li>Install Yindle Share Cart, then deactivate the old Free copy without deleting\nit and activate the new copy. If both remain active, the new copy stands by\nuntil the old Free copy is deactivated. Pro takes precedence when active.<\/li>\n<li>Verify your existing share links and settings.\nDelete it only after confirming deletion is disabled. Keeping it inactive is\nalso safe. Do not reset capability secrets or remove shared database tables.<\/li>\n<\/ol>\n\n<p>When this new plugin is active it protects shared data during companion\nuninstallation without changing the saved deletion preference. That protection\ncannot run while it is inactive. Deactivation always preserves data.<\/p>\n\n<h3>Privacy<\/h3>\n\n<p>Share snapshots store product and variation IDs, selected attributes, quantities,\ncreation and expiry times, hashed link capabilities and, for signed-in creators,\ntheir WordPress user ID. Prices, coupons, addresses, payment information and\nWooCommerce session contents are not included in the shared snapshot.<\/p>\n\n<p>The plugin uses the shop's WooCommerce session to bind import confirmation to\nthe current visitor and may ask WooCommerce to create its session cookie when\nopening a share preview. The creator's browser stores one revocation capability\nin local storage (<code>yindleCartManagementToken<\/code>); it is replaced by the next share\nand removed when revoked or when the visitor clears site data.<\/p>\n\n<p>Abuse prevention uses short-lived local counters keyed by a salted hash of the\nvisitor's session\/user identity and peer IP address, with a five-minute default\nwindow. The raw IP address is not stored by this plugin. One-use import markers\nexpire after one day. Shared links expire after the configured 1\u2013365 days\n(default 30); scheduled cleanup removes expired records that are not referenced\nby a retained saved cart.<\/p>\n\n<p>WordPress's privacy export includes your saved-cart names and owned product\nselections without link tokens or keys. The eraser and user-deletion hooks remove\nsaved-cart relations and anonymise creator IDs. Network deletions use bounded\nbackground jobs; per-site orphan cleanup retries when the plugin and cron are\navailable, including data from former memberships. Product selections may remain when another\nsaved cart references them. Store owners should describe this behavior in their\nshop's privacy notice.<\/p>\n\n<h3>Third-party assets<\/h3>\n\n<p>Plus Jakarta Sans and Geist Mono fonts are bundled under the SIL Open Font\nLicense 1.1. Lucide icons are bundled under the ISC license. Their notices and\nsource provenance are included in <code>assets\/yindle\/<\/code>. Runtime JavaScript is\nhuman-readable and uses WordPress\/WooCommerce-provided libraries.<\/p>\n\n<h4>Translations<\/h4>\n\n<p>This directory package uses WordPress language packs from translate.wordpress.org\nfor PHP and Cart Block strings. It ships no bundled translation catalogues and\nneeds no custom translation loader. Until a language pack is available, English\nsource strings remain usable. Community translations are welcome.<\/p>\n\n<!--section=installation-->\n<p>For the existing Free 1.0.2 and sold Pro 2.0.0 upgrade path, deactivate Free\nwithout deleting it before activating the paid ZIP. Keep shared data deletion off.<\/p>\n\n<ol>\n<li>Upload the plugin folder to <code>\/wp-content\/plugins\/<\/code>, or install the ZIP under\n<strong>Plugins \u2192 Add New \u2192 Upload Plugin<\/strong>.<\/li>\n<li>Install and activate WooCommerce 8.0 or later, then activate this plugin.<\/li>\n<li>Configure it under <strong>WooCommerce \u2192 Settings \u2192 Yindle Share Cart<\/strong>.<\/li>\n<\/ol>\n\n<p>If Share Cart Pro by Yindle is already active, this edition stands by and\ndoes not load its sharing runtime. It retains compatibility declarations and\na standby notice. The Pro edition contains every free feature.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20the%20link%20contain%20prices%3F\"><h3>Does the link contain prices?<\/h3><\/dt>\n<dd><p>No. The stored snapshot holds product IDs, variation IDs, quantities and the\nselected variation attributes. Prices, coupons, totals, tax, customer details\nand session data are rejected by the schema before anything is saved.<\/p><\/dd>\n<dt id=\"can%20a%20recipient%27s%20cart%20be%20changed%20just%20by%20opening%20the%20link%3F\"><h3>Can a recipient's cart be changed just by opening the link?<\/h3><\/dt>\n<dd><p>No. Opening the link renders a preview and changes nothing. The cart is only\nmodified by a POST that carries a valid nonce, an explicit replace\/merge choice\nand a signed single-use import intent.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20a%20product%20sold%20out%20after%20the%20link%20was%20created%3F\"><h3>What happens if a product sold out after the link was created?<\/h3><\/dt>\n<dd><p>The preview reports that the shared cart can no longer be imported, and nothing\nis added. Partial imports are not possible: the plan is validated in full first.<\/p><\/dd>\n<dt id=\"does%20an%20expired%20licence%20disable%20anything%3F\"><h3>Does an expired licence disable anything?<\/h3><\/dt>\n<dd><p>This edition has no licence client at all. In the Pro edition, a licence governs\nupdates and support only and never disables an installed feature.<\/p><\/dd>\n<dt id=\"is%20any%20data%20sent%20anywhere%3F\"><h3>Is any data sent anywhere?<\/h3><\/dt>\n<dd><p>Sharing and importing contact only the current shop. This edition has no\nexternal service, telemetry, Yindle account, licence check or custom updater.\nFonts, styles, scripts and icons are bundled locally. WordPress itself can\ncontact WordPress.org for normal plugin updates and translations.<\/p><\/dd>\n<dt id=\"which%20product%20types%20are%20supported%3F\"><h3>Which product types are supported?<\/h3><\/dt>\n<dd><p>Simple and variable WooCommerce products are supported. Extensions that add\ncustom cart item data need a compatible adapter. An unsupported cart is\nrejected with an explanation; its extra selections are not silently discarded.<\/p><\/dd>\n<dt id=\"how%20should%20i%20configure%20caching%3F\"><h3>How should I configure caching?<\/h3><\/dt>\n<dd><p>Exclude the configured share URL path (by default <code>\/cart\/&lt;share-key&gt;\/<\/code>) from\nfull-page and CDN caching. The plugin sends private, no-store and noindex\nheaders for these pages. Verify that your cache honors them with two separate\nguest sessions. Treat a share URL as a secret: anyone with it can preview and\nimport its product selections until it expires or is revoked.<\/p><\/dd>\n<dt id=\"what%20happens%20when%20i%20deactivate%20or%20delete%20the%20plugin%3F\"><h3>What happens when I deactivate or delete the plugin?<\/h3><\/dt>\n<dd><p>Deactivation retains data. Deleting the plugin also retains data by default.\nThe optional <strong>Delete data on uninstall<\/strong> setting enables permanent cleanup.\nFree preserves shared data if Pro is installed or saved cart\/licence data\nindicates a Pro installation, even when that setting is enabled.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.4<\/h4>\n\n<ul>\n<li>Security: stop retaining a copy of the WordPress AUTH key and salt. The capability\nkey moves to a new random <code>yindle_cart_capability_key<\/code> option. Both earlier\n  yindle_cart_capability_pepper options are deleted by name on first load. Their\nvalues are never read or written into queries. Loading fails closed if they cannot be removed.<\/li>\n<li>Remove the verification fallback to a retired key. Share and revoke links created\nby every earlier version, including 1.0.3, no longer resolve. Stored carts,\nexpiry and revocations are unchanged. Unmigrated plaintext 1.x links still migrate.<\/li>\n<\/ul>\n\n<h4>1.0.3<\/h4>\n\n<ul>\n<li>Make first capability-key creation, legacy rotation and rate admission atomic.<\/li>\n<li>Reject exhausted peers before creating new identity counters and expire\ndatabase counters when a persistent object cache is active.<\/li>\n<li>Add paged personal-data exports and durable deletion across relevant sites,\nincluding former memberships and an unloaded network-hook fallback.<\/li>\n<li>Isolate Free implementation functions and constants as well as classes.<\/li>\n<li>Preserve shared privacy and expiry jobs when another edition remains.<\/li>\n<li>Verify separate native WordPress activation, real two-process MySQL\/Redis\nraces, multisite rollback\/retry and independently composed runtime packages.<\/li>\n<\/ul>\n\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>Use the distinctive Yindle Share Cart name and yindle-share-cart directory.<\/li>\n<li>Remove unused saved-cart creation, issuance, account and paid styling code.<\/li>\n<li>Use standard WordPress language packs instead of bundled catalogues\/loaders.<\/li>\n<li>Protect old\/new edition transitions and document safe removal of older copies.<\/li>\n<li>Clarify that bundled asset provenance does not restrict modification rights.<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Give all nine Free runtime classes the distinctive YindleShareCart_ prefix.<\/li>\n<li>Register bundled translations at init for older supported WordPress versions.<\/li>\n<li>Compile bundled catalogues compatibly with the WordPress 6.4 translation reader.<\/li>\n<li>Link the plugin header to the verified public product page.<\/li>\n<li>Preserve shared storage, hooks and capability links; Pro files are unchanged.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial free release of Yindle Share Cart.<\/li>\n<li>Declares WooCommerce as a plugin dependency.<\/li>\n<li>Documents local privacy, browser storage, caching and edition changes.<\/li>\n<li>Contains the complete share service: capability links, current-price preview,\ndeliberate replace\/merge, guest revocation, expiry, rate limiting, atomic\nimport and the privacy eraser.<\/li>\n<li>Contains no licence client, no update client and no paid feature code.<\/li>\n<\/ul>","raw_excerpt":"Share WooCommerce carts with secure, expiring links. Recipients preview current prices and stock before choosing to replace or merge their cart.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/374087","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=374087"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/yindle"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=374087"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=374087"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=374087"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=374087"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=374087"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=374087"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}