{"id":312715,"date":"2026-05-15T09:28:50","date_gmt":"2026-05-15T09:28:50","guid":{"rendered":"https:\/\/es.wordpress.org\/plugins\/eu-withdrawal-compliance\/"},"modified":"2026-09-22T13:47:23","modified_gmt":"2026-09-22T13:47:23","slug":"eu-withdrawal-compliance","status":"publish","type":"plugin","link":"https:\/\/gax.wordpress.org\/plugins\/eu-withdrawal-compliance\/","author":1320655,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"2.3.0","stable_tag":"2.3.0","tested":"7.1.2","requires":"6.0","requires_php":"7.4","requires_plugins":null,"header_name":"EU Withdrawal and Legal Guarantee Compliance","header_author":"Fernando Tellado","header_description":"Adds the EU online withdrawal function required by Directive (EU) 2023\/2673 from June 19, 2026. Includes a shortcode, a Gutenberg-friendly form, a WooCommerce \"My account\" endpoint and a full admin log.","assets_banners_color":"05339b","last_updated":"2026-09-22 13:47:23","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/servicios.ayudawp.com","header_author_uri":"https:\/\/tellado.es","rating":5,"author_block_rating":0,"active_installs":1000,"downloads":13311,"num_ratings":17,"support_threads":9,"support_threads_resolved":9,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.4.0":{"tag":"1.4.0","author":"fernandot","date":"2026-05-15 17:32:54","revision":3533273},"1.4.1":{"tag":"1.4.1","author":"fernandot","date":"2026-05-16 07:55:07","revision":3533628},"1.5.0":{"tag":"1.5.0","author":"fernandot","date":"2026-05-16 23:53:15","revision":3534106},"1.6.0":{"tag":"1.6.0","author":"fernandot","date":"2026-05-18 08:37:36","revision":3535309},"1.6.1":{"tag":"1.6.1","author":"fernandot","date":"2026-05-18 12:04:18","revision":3535598},"1.7.0":{"tag":"1.7.0","author":"fernandot","date":"2026-05-30 11:29:56","revision":3554657},"1.8.0":{"tag":"1.8.0","author":"fernandot","date":"2026-06-04 17:04:46","revision":3561333},"1.8.1":{"tag":"1.8.1","author":"fernandot","date":"2026-06-05 11:47:43","revision":3562312},"1.9.0":{"tag":"1.9.0","author":"fernandot","date":"2026-06-16 18:04:38","revision":3574868},"2.0.0":{"tag":"2.0.0","author":"fernandot","date":"2026-06-25 09:46:53","revision":3585969},"2.0.1":{"tag":"2.0.1","author":"fernandot","date":"2026-07-10 12:22:35","revision":3602797},"2.1.0":{"tag":"2.1.0","author":"fernandot","date":"2026-07-17 22:30:19","revision":3612037},"2.1.1":{"tag":"2.1.1","author":"fernandot","date":"2026-07-30 13:49:17","revision":3628679},"2.1.2":{"tag":"2.1.2","author":"fernandot","date":"2026-08-05 18:57:38","revision":3635744},"2.2.0":{"tag":"2.2.0","author":"fernandot","date":"2026-08-13 21:13:01","revision":3646292},"2.2.1":{"tag":"2.2.1","author":"fernandot","date":"2026-08-20 15:17:36","revision":3657206},"2.2.2":{"tag":"2.2.2","author":"fernandot","date":"2026-09-04 09:35:43","revision":3680969},"2.2.3":{"tag":"2.2.3","author":"fernandot","date":"2026-09-16 10:22:56","revision":3698355},"2.3.0":{"tag":"2.3.0","author":"fernandot","date":"2026-09-22 13:47:23","revision":3707465}},"upgrade_notice":{"2.3.0":"<p>New module for the EU harmonised legal guarantee notice, mandatory from 27 September 2026: the official notice in 24 languages at the checkout and in your order emails, with the PDF attached. It arrives switched off, with a notice in your dashboard to turn it on.<\/p>"},"ratings":{"1":0,"2":0,"3":0,"4":0,"5":17},"assets_icons":{"icon-128x128.jpg":{"filename":"icon-128x128.jpg","revision":3535925,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.jpg":{"filename":"icon-256x256.jpg","revision":3535925,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500-es.jpg":{"filename":"banner-1544x500-es.jpg","revision":3535925,"resolution":"1544x500","location":"assets","locale":"es","width":1544,"height":500},"banner-1544x500.jpg":{"filename":"banner-1544x500.jpg","revision":3535925,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250-es.jpg":{"filename":"banner-772x250-es.jpg","revision":3535925,"resolution":"772x250","location":"assets","locale":"es","width":772,"height":250},"banner-772x250.jpg":{"filename":"banner-772x250.jpg","revision":3535925,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{"blueprint.json":{"filename":"blueprint.json","revision":3707466,"resolution":false,"location":"assets","locale":"","contents":"{\"landingPage\":\"\\\/wp-admin\\\/plugins.php\",\"preferredVersions\":{\"php\":\"latest\",\"wp\":\"latest\"},\"steps\":[{\"step\":\"login\",\"username\":\"admin\"},{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"woocommerce\"},\"options\":{\"activate\":false}},{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"eu-withdrawal-compliance\"},\"options\":{\"activate\":true}}]}"}},"all_blocks":[],"tagged_versions":["1.4.0","1.4.1","1.5.0","1.6.0","1.6.1","1.7.0","1.8.0","1.8.1","1.9.0","2.0.0","2.0.1","2.1.0","2.1.1","2.1.2","2.2.0","2.2.1","2.2.2","2.2.3","2.3.0"],"block_files":[],"assets_screenshots":{"screenshot-1-es.jpg":{"filename":"screenshot-1-es.jpg","revision":3534419,"resolution":"1","location":"assets","locale":"es","width":1920,"height":1387},"screenshot-1.jpg":{"filename":"screenshot-1.jpg","revision":3534419,"resolution":"1","location":"assets","locale":"","width":1920,"height":1387},"screenshot-10-es.jpg":{"filename":"screenshot-10-es.jpg","revision":3534419,"resolution":"10","location":"assets","locale":"es","width":1920,"height":1337},"screenshot-10.jpg":{"filename":"screenshot-10.jpg","revision":3534419,"resolution":"10","location":"assets","locale":"","width":1920,"height":1316},"screenshot-11-es.jpg":{"filename":"screenshot-11-es.jpg","revision":3534419,"resolution":"11","location":"assets","locale":"es","width":1920,"height":1359},"screenshot-11.jpg":{"filename":"screenshot-11.jpg","revision":3534419,"resolution":"11","location":"assets","locale":"","width":1920,"height":1349},"screenshot-12-es.jpg":{"filename":"screenshot-12-es.jpg","revision":3534419,"resolution":"12","location":"assets","locale":"es","width":1920,"height":2572},"screenshot-12.jpg":{"filename":"screenshot-12.jpg","revision":3534419,"resolution":"12","location":"assets","locale":"","width":1920,"height":2572},"screenshot-2-es.jpg":{"filename":"screenshot-2-es.jpg","revision":3534419,"resolution":"2","location":"assets","locale":"es","width":1920,"height":971},"screenshot-2.jpg":{"filename":"screenshot-2.jpg","revision":3534419,"resolution":"2","location":"assets","locale":"","width":1920,"height":962},"screenshot-3-es.jpg":{"filename":"screenshot-3-es.jpg","revision":3534419,"resolution":"3","location":"assets","locale":"es","width":1920,"height":971},"screenshot-3.jpg":{"filename":"screenshot-3.jpg","revision":3534419,"resolution":"3","location":"assets","locale":"","width":1920,"height":971},"screenshot-4-es.jpg":{"filename":"screenshot-4-es.jpg","revision":3534419,"resolution":"4","location":"assets","locale":"es","width":1920,"height":1136},"screenshot-4.jpg":{"filename":"screenshot-4.jpg","revision":3534419,"resolution":"4","location":"assets","locale":"","width":1920,"height":1129},"screenshot-5-es.jpg":{"filename":"screenshot-5-es.jpg","revision":3534419,"resolution":"5","location":"assets","locale":"es","width":1920,"height":3584},"screenshot-5.jpg":{"filename":"screenshot-5.jpg","revision":3534419,"resolution":"5","location":"assets","locale":"","width":1920,"height":3464},"screenshot-6-es.jpg":{"filename":"screenshot-6-es.jpg","revision":3534419,"resolution":"6","location":"assets","locale":"es","width":1920,"height":2643},"screenshot-6.jpg":{"filename":"screenshot-6.jpg","revision":3534419,"resolution":"6","location":"assets","locale":"","width":1920,"height":2545},"screenshot-7-es.jpg":{"filename":"screenshot-7-es.jpg","revision":3534419,"resolution":"7","location":"assets","locale":"es","width":1920,"height":1070},"screenshot-7.jpg":{"filename":"screenshot-7.jpg","revision":3534419,"resolution":"7","location":"assets","locale":"","width":1920,"height":1019},"screenshot-8-es.jpg":{"filename":"screenshot-8-es.jpg","revision":3534419,"resolution":"8","location":"assets","locale":"es","width":1920,"height":1227},"screenshot-8.jpg":{"filename":"screenshot-8.jpg","revision":3534419,"resolution":"8","location":"assets","locale":"","width":1920,"height":1227},"screenshot-9-es.jpg":{"filename":"screenshot-9-es.jpg","revision":3534419,"resolution":"9","location":"assets","locale":"es","width":1920,"height":1170},"screenshot-9.jpg":{"filename":"screenshot-9.jpg","revision":3534419,"resolution":"9","location":"assets","locale":"","width":1920,"height":1214}},"screenshots":{"1":"Public withdrawal form with all required fields.","2":"Withdrawal log inside the WordPress admin.","3":"Per-request detail screen with status management, including the captured checkout consents (text, accepted\/declined, timestamp, IP, user agent).","4":"WooCommerce My Account integration with per-order Withdraw button.","5":"EU Withdrawal Settings Page (WooCommerce active), with the Checkout consent, Annex I.B model and Excluded products notice sections.","6":"EU Withdrawal Settings Page (Standalone).","7":"Per-product \"Withdrawal status\" dropdown in the WooCommerce product editor (General tab), with the inheritance notice when the value is pulled from the product's category.","8":"Per-category \"Withdrawal status\" dropdown in Products \u2192 Categories edit screen.","9":"Excluded products notice rendered on the public single product page (between price and add-to-cart button).","10":"Mandatory digital-content consent (Art. 16(m)) shown at the WooCommerce checkout.","11":"Optional service-start consent (Art. 14(4)(a)) shown at the WooCommerce checkout.","12":"Annex I.B model withdrawal form rendered as a collapsible block below the public withdrawal form, with a printable view link.","13":"Two-step confirmation screen (Article 11a(3)): read-only summary of the declaration with the dedicated \"Confirm withdrawal\" button, shown before the request is registered.","14":"Export withdrawals page: filtered CSV export of the request log by status and date range for accounting and consumer-protection audits."}},"plugin_section":[],"plugin_tags":[255182,276020,275335,245590,286],"plugin_category":[45],"plugin_contributors":[245779,133550],"plugin_business_model":[],"class_list":["post-312715","plugin","type-plugin","status-publish","hentry","plugin_tags-consumer-rights","plugin_tags-garan","plugin_tags-legal-guarantee","plugin_tags-withdrawal","plugin_tags-woocommerce","plugin_category-ecommerce","plugin_contributors-ayudawp","plugin_contributors-fernandot","plugin_committers-ayudawp","plugin_committers-fernandot","plugin_support_reps-ayudawp"],"banners":{"banner":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/banner-772x250.jpg?rev=3535925","banner_2x":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/banner-1544x500.jpg?rev=3535925","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/icon-128x128.jpg?rev=3535925","icon_2x":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/icon-256x256.jpg?rev=3535925","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/screenshot-1.jpg?rev=3534419","caption":"Public withdrawal form with all required fields."},{"src":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/screenshot-2.jpg?rev=3534419","caption":"Withdrawal log inside the WordPress admin."},{"src":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/screenshot-3.jpg?rev=3534419","caption":"Per-request detail screen with status management, including the captured checkout consents (text, accepted\/declined, timestamp, IP, user agent)."},{"src":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/screenshot-4.jpg?rev=3534419","caption":"WooCommerce My Account integration with per-order Withdraw button."},{"src":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/screenshot-5.jpg?rev=3534419","caption":"EU Withdrawal Settings Page (WooCommerce active), with the Checkout consent, Annex I.B model and Excluded products notice sections."},{"src":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/screenshot-6.jpg?rev=3534419","caption":"EU Withdrawal Settings Page (Standalone)."},{"src":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/screenshot-7.jpg?rev=3534419","caption":"Per-product \"Withdrawal status\" dropdown in the WooCommerce product editor (General tab), with the inheritance notice when the value is pulled from the product's category."},{"src":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/screenshot-8.jpg?rev=3534419","caption":"Per-category \"Withdrawal status\" dropdown in Products \u2192 Categories edit screen."},{"src":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/screenshot-9.jpg?rev=3534419","caption":"Excluded products notice rendered on the public single product page (between price and add-to-cart button)."},{"src":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/screenshot-10.jpg?rev=3534419","caption":"Mandatory digital-content consent (Art. 16(m)) shown at the WooCommerce checkout."},{"src":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/screenshot-11.jpg?rev=3534419","caption":"Optional service-start consent (Art. 14(4)(a)) shown at the WooCommerce checkout."},{"src":"https:\/\/ps.w.org\/eu-withdrawal-compliance\/assets\/screenshot-12.jpg?rev=3534419","caption":"Annex I.B model withdrawal form rendered as a collapsible block below the public withdrawal form, with a printable view link."}],"raw_content":"<!--section=description-->\n<p>Two EU deadlines, one plugin. From <strong>19 June 2026<\/strong>, Directive 2023\/2673 obliges every online retailer in the EU to offer a digital withdrawal function at least as easy to use as the purchase flow. From <strong>27 September 2026<\/strong>, Directive (EU) 2024\/825 and Implementing Regulation (EU) 2025\/1960 oblige every shop selling goods to display the harmonised notice on the legal guarantee of conformity. Most plugins in the directory stop at \"a withdrawal button\". This one covers both, free and complete.<\/p>\n\n<h4>The legal guarantee notice<\/h4>\n\n<p>The official notice ships bundled in the 24 EU languages and is shown unedited, as the regulation requires: above the place-order button of both the classic and the block checkout, and in your order emails with the official PDF attached, so it survives the mail clients that block remote images. Three display modes (the whole notice, a disclosure, or a native popover for narrow columns), the Spanish three-year note where it applies, a shortcode for your own guarantee page, a footer link, and a private order note recording which notice each buyer saw. Only shown when the cart holds goods: the notice does not cover services or digital content.<\/p>\n\n<h4>The withdrawal function<\/h4>\n\n<ul>\n<li><strong>Two-step confirmation (Art. 11a(3))<\/strong>: the form leads to a review screen with a read-only summary and a \"Confirm withdrawal\" button, and the request is registered only when that button is pressed. Held server-side in a single-use token, so it works without JavaScript.<\/li>\n<li><strong>Durable-medium acknowledgement (Art. 11a(4))<\/strong>: the confirmation email reproduces the full declaration and the exact date and time of submission, with a <strong>verifiable SHA-256 receipt hash<\/strong> recomputable from the stored fields if a dispute arises.<\/li>\n<li><strong>Annex I.B model withdrawal form<\/strong> generated from your shop data, collapsible below the public form and printable from the same URL. Meets the information obligation of Art. 6(1)(h), which the new directive does not replace.<\/li>\n<li><strong>Two consent checkboxes at the WooCommerce checkout<\/strong>: the mandatory one for digital content (Art. 16(m)), which blocks the order until accepted, and the optional one for services started inside the 14-day window (Art. 14(4)(a)), which enables pro-rated billing. Both are persisted on the order with the exact text shown, accepted or declined, timestamp, IP and user agent.<\/li>\n<li><strong>One \"Withdrawal status\" dropdown per product and per category<\/strong>, with four options, driving the Article 16 exclusion and the matching checkout consent at once, with full subcategory inheritance. Competing plugins gate this behind a paid tier.<\/li>\n<li><strong>Configurable notice on excluded products<\/strong>, between price and add-to-cart, with its own title and body per type of exception.<\/li>\n<li><strong>Native GDPR integration<\/strong>: Privacy Policy snippet, personal-data exporter and eraser, all keyed on the customer email.<\/li>\n<li><strong>Standalone mode<\/strong>: form, shortcode, request log, emails, receipt hash, Annex I.B and GDPR all run without WooCommerce, in the same <strong>Withdrawals<\/strong> menu on every install.<\/li>\n<\/ul>\n\n<h4>On the front end<\/h4>\n\n<ul>\n<li>A withdrawal page created on activation, with a neutral template ready to publish and the reminder to review it with a lawyer kept in the dashboard rather than in the page.<\/li>\n<li><code>[ayudawp_withdrawal_form]<\/code> for the form, <code>[ayudawp_withdrawal_link]<\/code> for a permanent link to it from any footer or widget area, <code>[ayudawp_guarantee_notice]<\/code> for the guarantee notice, <code>[ayudawp_guarantee_link]<\/code> for its page, and <code>[ayudawp_withdrawal_excluded_notice]<\/code> for page builders that skip the standard WooCommerce hooks.<\/li>\n<li>Semantic form with HTML5 validation, honeypot, escaped output, sanitized input and CSRF nonces, plus a privacy-policy checkbox linked to your configured page.<\/li>\n<\/ul>\n\n<h4>With WooCommerce<\/h4>\n\n<ul>\n<li><strong>My Account \u2192 Right of withdrawal<\/strong>, with a per-order \"Withdraw\" button while the order is in an eligible status, deep-linked to the form with the order pre-filled.<\/li>\n<li><strong>Request tracking for the customer<\/strong>: the same screen lists their requests with date, order, scope, status, your resolution note and the receipt code, and the order row shows an open request instead of an empty slot.<\/li>\n<li><strong>Withdrawal notice in the transactional emails<\/strong>, with a direct link to the form. Eligible statuses configurable; admin emails never receive it.<\/li>\n<li><strong>Automatic verification of the order and email pair<\/strong>, gated by the configured statuses. The 14-day deadline is an advisory flag for you, not an automatic rejection, because the period runs from delivery. Basis and grace days configurable, with an optional strict mode.<\/li>\n<li><strong>Optional \"Accept unmatched requests\"<\/strong> mode: register what does not match an order as <em>Unverified<\/em> for manual review instead of rejecting it. Off by default.<\/li>\n<li><strong>Order-number compatibility<\/strong> with Sequential Order Numbers and Custom Order Numbers (Tyche and WPFactory), plus a filter for any other scheme.<\/li>\n<li><strong>\"Withdrawal\" column<\/strong> on the orders screen, private order notes at every step, and HPOS compatibility declared.<\/li>\n<\/ul>\n\n<h4>In the admin<\/h4>\n\n<ul>\n<li><strong>Full request log<\/strong> as a private post type with its status lifecycle, customer details, scope, IP, user agent and UTC timestamp.<\/li>\n<li><strong>CSV export<\/strong> for accounting and consumer-protection audits, by bulk action or filtered by status and date range, with cells escaped against formula injection.<\/li>\n<li><strong>Audit trail per request<\/strong>: resolution timestamp on every status change and whether the acknowledgement was accepted for delivery, in the detail screen and in the CSV.<\/li>\n<li><strong>Bulk actions<\/strong>, a status metabox with a required comment when rejecting, and the captured checkout consents on file.<\/li>\n<li><strong>Emails<\/strong>: acknowledgement to the customer, notification to the shop with reply-to set to the customer, and a follow-up on every status change.<\/li>\n<li><strong>Legal disclaimer<\/strong> in the settings page, and a Mandatory \/ Recommended \/ Optional tag on every setting.<\/li>\n<\/ul>\n\n<h4>Multilingual stores: WPML and Polylang<\/h4>\n\n<p>Compliance cannot depend on the language the customer was browsing in, so both are supported with nothing to configure. Set the withdrawal status once, on the product or category in your original language, and it holds across every translation, with an explicit status on a translation still winning. Every link follows the visitor's language, and so does the guarantee notice. The bundled <code>wpml-config.xml<\/code> exposes your own editable texts to String Translation and marks the request log as non-translatable. See the FAQ for the current limitation on the plugin's own emails.<\/p>\n\n<h4>Built for production<\/h4>\n\n<ul>\n<li>CSS only loads where it is needed: the withdrawal page, the checkout, product pages that actually show a notice, and the plugin's own admin screens.<\/li>\n<li>Delivered as language packs from <a href=\"https:\/\/translate.wordpress.org\/projects\/wp-plugins\/eu-withdrawal-compliance\/\">translate.wordpress.org<\/a>. Follows the WordPress Coding Standards, with escaped output, sanitized input, capability checks and nonces.<\/li>\n<li><strong>19 documented filters and 4 actions<\/strong>, so agencies can extend it without forking.<\/li>\n<li>PHP 7.4+, WordPress 6.0+, WooCommerce 7.0+ (optional).<\/li>\n<\/ul>\n\n<h3>Why this plugin?<\/h3>\n\n<ul>\n<li><strong>Fully free, no paid tier.<\/strong> No premium add-on, no feature behind an upsell, no \"Pro\" version on the horizon.<\/li>\n<li><strong>The only plugin in the directory<\/strong> that issues a SHA-256 receipt hash as durable proof of each request, that ships the Annex I.B model form, that injects the two checkout consents with proof on the order, and that gives you Article 16 exclusions with subcategory inheritance without a paid tier.<\/li>\n<li><strong>The harmonised guarantee notice included<\/strong>, in the 24 languages, at the checkout and in the emails, which is the second obligation landing in 2026 and the one most plugins still ignore.<\/li>\n<li><strong>Real multilingual support<\/strong> with WPML and Polylang, and everything configurable from the settings screen without writing a line of code.<\/li>\n<li><strong>Maintained by a Spanish WordPress trainer with 20+ years on the platform<\/strong>, with the es_ES translation kept up to date by the author, replies on the support forum and an active roadmap of free improvements.<\/li>\n<\/ul>\n\n<h3>Roadmap<\/h3>\n\n<p>Planned for upcoming free versions: the GARAN durability label per product; the checkout consents inside the Checkout block; HTML emails inheriting the WooCommerce theme, and plugin emails in the customer's language; a Gutenberg block and a widget for the withdrawal link; a custom \"Withdrawal requested\" order status; a PDF of the request with its receipt hash; and a dashboard widget.<\/p>\n\n<h3>Privacy<\/h3>\n\n<p>For each request the plugin stores the customer name and email, the order reference and date, the IP address and User-Agent, the UTC submission timestamp and the SHA-256 receipt hash. All of it serves the legal traceability the directive asks for and lets the shop handle the request.<\/p>\n\n<p>Data lives in a private custom post type (<code>ayudawp_withdrawal<\/code>) reachable only by the roles you authorise. Nothing is sent to third-party services: everything happens between your shop and your customer through standard WordPress emails.<\/p>\n\n<p>Add a section to your privacy policy describing this storage. The plugin contributes a suggested snippet you can paste from <strong>Settings \u2192 Privacy \u2192 Policy Guide<\/strong>, and withdrawal data is exposed to <strong>Tools \u2192 Export Personal Data<\/strong> and <strong>Tools \u2192 Erase Personal Data<\/strong>, filtered by customer email.<\/p>\n\n<h3>Support<\/h3>\n\n<p>Need private support or custom development?<\/p>\n\n<p>Do you need one-on-one help, priority troubleshooting, or a custom feature, integration, or tweak built specifically for your site? I offer private support and custom development. Just <a href=\"mailto:eu-withdrawal-compliance@ayudawp.com\">contact me<\/a> and tell me what you need.<\/p>\n\n<p>Need help or have suggestions?<\/p>\n\n<ul>\n<li><a href=\"https:\/\/servicios.ayudawp.com\">Official website<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.org\/support\/plugin\/eu-withdrawal-compliance\/\">WordPress support forum<\/a><\/li>\n<li><a href=\"https:\/\/www.youtube.com\/AyudaWordPressES\">YouTube channel<\/a><\/li>\n<li><a href=\"https:\/\/ayudawp.com\">Documentation and tutorials<\/a><\/li>\n<\/ul>\n\n<p>Love the plugin? Please leave us a 5-star review and help spread the word!<\/p>\n\n<h3>About AyudaWP.com<\/h3>\n\n<p>We are specialists in WordPress security, SEO, AI and performance optimization plugins. We create tools that solve real problems for WordPress site owners while maintaining the highest coding standards and accessibility requirements.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate the plugin from the <strong>Plugins<\/strong> screen.<\/li>\n<li>The plugin creates a \"Right of withdrawal\" page automatically with a sample legal template. Review and edit it from <strong>Pages<\/strong>.<\/li>\n<li>Go to <strong>EU Compliance \u2192 Settings<\/strong> to configure the notification email address and the page that hosts the form.<\/li>\n<li>Add the URL of the withdrawal page to your footer or to the legal links section so it is visible from any page on your site.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"what%20is%20the%20harmonised%20legal%20guarantee%20notice%2C%20and%20do%20i%20have%20to%20show%20it%3F\"><h3>What is the harmonised legal guarantee notice, and do I have to show it?<\/h3><\/dt>\n<dd><p>It is the official EU notice on the legal guarantee of conformity: the one headed \"LEGAL GUARANTEE\", with the QR code and the GARAN label. Article 22a of Directive 2011\/83\/EU, added by Directive (EU) 2024\/825, makes it mandatory from <strong>27 September 2026<\/strong> for everyone selling goods to consumers in the EU, and Implementing Regulation (EU) 2025\/1960 fixes its design. It does not cover B2B sales, services or digital content, so the plugin only shows it when the cart or the order holds at least one product that is not virtual.<\/p>\n\n<p>Online it has to be in colour, in full, unedited, legible at the default display size, in a prominent place and with a clickable link to the same destination as its QR code. The plugin does all of that, in the 24 EU languages, at both checkouts and in your order emails.<\/p>\n\n<p>It arrives <strong>switched off on sites updating from an earlier version<\/strong>, with a notice in the dashboard, because it changes what your customers see at the checkout. New installs start with it on. Switch it on under <strong>EU Compliance \u2192 Settings \u2192 EU legal guarantee notice (GARAN)<\/strong>.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20show%20the%20garan%20label%3F\"><h3>Does the plugin show the GARAN label?<\/h3><\/dt>\n<dd><p>Not yet, and most shops do not need it. GARAN is a different thing from the notice: the notice covers the <strong>legal<\/strong> guarantee and every shop selling goods has to display it, while GARAN stands for a <strong>commercial durability guarantee<\/strong> that a <em>producer<\/em> chooses to offer. It is mandatory only when that guarantee costs the consumer nothing, covers the whole product and lasts more than two years. When it does, the producer must use the label and you, as the seller, have to show it on the products that carry one, which in many catalogues is none of them.<\/p>\n\n<p>It cannot ship bundled the way the notice does, because the producer fills in the years, the trademark and the model identifier. Per-product GARAN fields are the next step for this module. Unlike the notice, the label may be shown online in a nested format that expands on the first click.<\/p><\/dd>\n<dt id=\"where%20do%20the%20notice%20files%20come%20from%2C%20and%20under%20what%20licence%3F\"><h3>Where do the notice files come from, and under what licence?<\/h3><\/dt>\n<dd><p>They are the official files from the European Commission <a href=\"https:\/\/commission.europa.eu\/publications\/practical-guidelines-and-high-resolution-vector-files-eu-notice-and-label-product-guarantees_en\">guidelines page<\/a>, bundled unmodified under <code>assets\/guarantee-notice\/<\/code> with the md5 of each one in <code>CHECKSUMS.txt<\/code> so you can check that nothing was touched. The one exception is the English PNG: the Commission's PNG package ships 23 languages and no English, so that single file is rendered from the official English PDF at the same size as the other 23, with nothing edited, cropped or added. Its origin is recorded in the same file.<\/p>\n\n<p>\u00a9 European Union, 2025. Reused under the <a href=\"https:\/\/creativecommons.org\/licenses\/by\/4.0\/\">CC BY 4.0 licence<\/a>, the Commission reuse policy implemented by Decision 2011\/833\/EU.<\/p><\/dd>\n<dt id=\"the%20notice%20is%20too%20big%2C%20or%20too%20small%2C%20in%20my%20checkout.%20what%20do%20i%20do%3F\"><h3>The notice is too big, or too small, in my checkout. What do I do?<\/h3><\/dt>\n<dd><p>Pick another display mode under <strong>EU Compliance \u2192 Settings \u2192 EU legal guarantee notice (GARAN)<\/strong>:<\/p>\n\n<ul>\n<li><strong>The whole notice<\/strong> (default). The reading nobody disputes: the guidelines do accept showing it behind a first click, but the regulation describes that nested format only for the GARAN label.<\/li>\n<li><strong>A disclosure<\/strong>: a line that expands into the notice, with the native <code>&lt;details&gt;<\/code> element.<\/li>\n<li><strong>A popover<\/strong>: a button that opens the notice large over the page. This is the one for narrow columns, such as the Storefront order review at about 279px, where a full-width notice comes out too small to read.<\/li>\n<li><strong>Nothing at the checkout<\/strong>, for shops that place it themselves. Emails and footer link keep working.<\/li>\n<\/ul>\n\n<p>On phones the full notice is around 330px wide, so the image always links to the full-size file.<\/p><\/dd>\n<dt id=\"the%20notice%20says%20two%20years%20and%20in%20spain%20the%20legal%20guarantee%20is%20three.%20isn%27t%20that%20wrong%3F\"><h3>The notice says two years and in Spain the legal guarantee is three. Isn't that wrong?<\/h3><\/dt>\n<dd><p>The notice says \"minimum two years\" because that is the EU floor, and it cannot be edited: the regulation requires it unaltered. Spain raised the legal guarantee on new goods to three years from delivery (Art. 120.1 TRLGDCU), so the plugin prints a short line <strong>next to<\/strong> the notice, never inside it, linking to your terms and conditions page and, if you write the <code>id<\/code> of its heading in the settings, to the exact section. Automatic when your WooCommerce base country is Spain, and forceable either way for shops selling into Spain from elsewhere. Second-hand goods can carry a shorter period, never under one year, and the official notice already says so.<\/p><\/dd>\n<dt id=\"can%20i%20publish%20the%20notice%20on%20its%20own%20page%2C%20or%20link%20it%20from%20my%20footer%3F\"><h3>Can I publish the notice on its own page, or link it from my footer?<\/h3><\/dt>\n<dd><p>Yes. Put <code>[ayudawp_guarantee_notice]<\/code> on a page for the notice in full (<code>mode=\"details\"<\/code> or <code>mode=\"popover\"<\/code> for the other two), select that page in the settings, and <code>[ayudawp_guarantee_link]<\/code> gives you a permanent link to it, exactly like <code>[ayudawp_withdrawal_link]<\/code> does for the withdrawal page. Both accept <code>text<\/code> and <code>class<\/code>.<\/p>\n\n<p>You can also replace the bundled file per language from your media library, in the same settings section, for example to serve it from your own CDN. Whatever you pick is shown unedited, so it has to be the official notice in that language, in colour and complete.<\/p><\/dd>\n<dt id=\"in%20which%20language%20is%20the%20notice%20shown%3F\"><h3>In which language is the notice shown?<\/h3><\/dt>\n<dd><p>In the language of the page, and in the language of the order for the emails, on shops running WPML or Polylang. The Commission publishes it in the 24 official EU languages; a shop in a language that is not one of them gets the official language of its own member state, so Catalan, Basque and Galician get the Spanish notice and Luxembourgish the French one. Anything else falls back to the language you pick in settings. The <code>ayudawp_euw_guarantee_fallback_lang<\/code> and <code>ayudawp_euw_guarantee_language_aliases<\/code> filters change both rules.<\/p><\/dd>\n<dt id=\"woocommerce%20ships%20its%20own%20order%20withdrawal%20page.%20do%20i%20still%20need%20this%20plugin%3F\"><h3>WooCommerce ships its own order withdrawal page. Do I still need this plugin?<\/h3><\/dt>\n<dd><p>They solve different halves of the same obligation: the native feature is a form, and this plugin is the toolkit around it.<\/p>\n\n<p>WooCommerce 11.1 added <code>order_withdrawal<\/code> (off by default, under <strong>WooCommerce &gt; Settings &gt; Advanced &gt; Features<\/strong>): a two-step public form on its own My Account endpoint, with a review screen and an acknowledgement email. What it does not do is link that form from anywhere: no My Account entry, no button on the order row, no line in the transactional emails, no footer link, which is the part Article 11a is actually about. It also keeps no record you can work with (no statuses, no notes, no export), and knows nothing about the Article 16 exceptions, the checkout consents, the Annex I.B model, the deadline of each order or the legal guarantee notice.<\/p>\n\n<p>With both switched on, your shop answers with two forms at two addresses, each keeping its own record and sending its own acknowledgement, and nothing merges them. The settings page warns you when that happens. Keep one of the two.<\/p><\/dd>\n<dt id=\"can%20customers%20see%20what%20happened%20to%20a%20request%20they%20sent%3F\"><h3>Can customers see what happened to a request they sent?<\/h3><\/dt>\n<dd><p>Yes, on WooCommerce sites and for customers with an account. <strong>My Account \u2192 Right of withdrawal<\/strong> opens with their own requests: date, order, scope, current status, the note you write when you resolve it and the receipt code. The row of an order that already has a request shows that status where the button was, and a rejected request keeps its \"Contest the rejection\" button.<\/p>\n\n<p>A request is listed when the customer sent it while signed in, or when it is linked to one of their own orders. The address of the account is deliberately not used: WooCommerce lets a customer change it without confirming the new one, so listing by address would expose requests sent as a guest from any address with no account. For guests the trace is the acknowledgement and the status emails, which is the durable medium the directive asks for. You can switch the whole thing off under <strong>EU Compliance \u2192 Settings \u2192 General<\/strong>.<\/p><\/dd>\n<dt id=\"can%20i%20move%20the%20checkout%20consent%20checkboxes%20somewhere%20else%3F\"><h3>Can I move the checkout consent checkboxes somewhere else?<\/h3><\/dt>\n<dd><p>Yes, with <code>ayudawp_euw_consent_hook<\/code>, but read the trade-off first. They render on <code>woocommerce_after_order_notes<\/code>, in the customer-details column, which WooCommerce renders once and leaves alone. The order-review panel next to the terms acceptance looks like the natural home, but WooCommerce re-renders it on every AJAX refresh, so a checkbox placed there is duplicated and loses what the customer already ticked whenever they change address, shipping or payment.<\/p>\n\n<pre><code>add_filter( 'ayudawp_euw_consent_hook', function () { return 'woocommerce_review_order_before_submit'; } );\n<\/code><\/pre>\n\n<p>Returning an empty string suppresses the render entirely. <code>ayudawp_euw_consent_applies<\/code> decides per cart and <code>ayudawp_euw_consent_is_required<\/code> makes either one mandatory.<\/p><\/dd>\n<dt id=\"will%20the%20form%20check%20the%2014-day%20deadline%3F\"><h3>Will the form check the 14-day deadline?<\/h3><\/dt>\n<dd><p>It does not auto-reject on it. The period legally runs from delivery (or, for digital content, from the start of the download), a date the shop cannot detect, so rejecting on the order date would turn away customers still inside their real window. Requests that look late are <strong>flagged<\/strong> in the admin notification instead, and you check the real delivery date and decide.<\/p>\n\n<p>You can tune the calculation under <strong>EU Compliance \u2192 Settings<\/strong>: order date or completion date as the basis, plus grace days. If your start date is reliable (services, digital content, shop pickup), switch <strong>Deadline enforcement<\/strong> from <em>Advisory<\/em> to <em>Strict<\/em> and late requests are blocked outright. Advisory is the default and the safe choice for goods.<\/p><\/dd>\n<dt id=\"how%20do%20i%20mark%20products%20that%20are%20excluded%20from%20the%20right%20of%20withdrawal%20%28article%2016%29%3F\"><h3>How do I mark products that are excluded from the right of withdrawal (Article 16)?<\/h3><\/dt>\n<dd><p>With a single <strong>Withdrawal status<\/strong> dropdown, set per category (<strong>Products \u2192 Categories<\/strong>) or per product (General tab). A category applies its status to every product underneath and to its descendant categories; a product overrides it. The four options:<\/p>\n\n<ul>\n<li><strong>Standard<\/strong> \u2014 withdrawal applies normally.<\/li>\n<li><strong>Digital content (Art. 16(m))<\/strong> \u2014 excluded, and a mandatory consent checkbox appears at checkout for any cart containing it.<\/li>\n<li><strong>Service started early (Art. 14(4)(a))<\/strong> \u2014 withdrawal still applies, with an optional consent so you can charge a pro-rated amount.<\/li>\n<li><strong>Dated services (Art. 16(l))<\/strong> \u2014 accommodation, transport, car rental, catering, leisure: excluded, no consent needed.<\/li>\n<li><strong>Other Article 16 exception<\/strong> \u2014 perishable, custom-made, hygiene-sealed, sealed media: excluded, no consent needed.<\/li>\n<\/ul>\n\n<p>A request on an order containing excluded items is flagged for you, never auto-rejected, because a partial withdrawal over the rest of the order can still be valid. If the <strong>Excluded products notice<\/strong> is on, a configurable notice also appears on the product page between price and add-to-cart.<\/p><\/dd>\n<dt id=\"the%20excluded-product%20notice%20does%20not%20appear%20with%20my%20page%20builder%20%28divi%2C%20elementor%2C%20bricks%E2%80%A6%29.%20what%20can%20i%20do%3F\"><h3>The excluded-product notice does not appear with my page builder (Divi, Elementor, Bricks\u2026). What can I do?<\/h3><\/dt>\n<dd><p>Page builders such as Divi, Elementor, Bricks or ShopLentor render their own single-product template and skip the standard WooCommerce hook (<code>woocommerce_single_product_summary<\/code>) where the plugin injects the excluded-product notice, so it does not appear automatically. Drop the <code>[ayudawp_withdrawal_excluded_notice]<\/code> shortcode into your product layout (most builders have a \"Shortcode\" element) and the notice will print for the current product whenever that product is flagged as excluded. With no attributes it resolves the product being viewed; pass <code>id=\"123\"<\/code> to target a specific product.<\/p><\/dd>\n<dt id=\"how%20do%20the%20checkout%20consent%20checkboxes%20work%20%28art.%2016%28m%29%20and%20art.%2014%284%29%28a%29%29%3F\"><h3>How do the checkout consent checkboxes work (Art. 16(m) and Art. 14(4)(a))?<\/h3><\/dt>\n<dd><p>The plugin injects them when the cart holds products flagged for them:<\/p>\n\n<ul>\n<li><strong>Type A (mandatory, Art. 16(m))<\/strong>, digital content. The customer must accept it to complete the order; without it recorded, they keep the 14-day right even after accessing the content.<\/li>\n<li><strong>Type B (optional, Art. 14(4)(a))<\/strong>, services started inside the window. Accepted, it lets you charge a pro-rated amount if they withdraw later. Without it, an early withdrawal means a full refund.<\/li>\n<\/ul>\n\n<p>Each flag is set per product or per category, with subcategory inheritance. The exact text shown, the accepted or declined state, the timestamp, the IP and the user agent are persisted on the order as proof, and surfaced in the metabox of each request. Both can be switched off and their text edited under <strong>EU Compliance \u2192 Settings \u2192 Checkout consent<\/strong>.<\/p><\/dd>\n<dt id=\"i%20sell%20to%20businesses%20%28b2b%29.%20can%20i%20exclude%20them%20from%20the%20right%20of%20withdrawal%3F\"><h3>I sell to businesses (B2B). Can I exclude them from the right of withdrawal?<\/h3><\/dt>\n<dd><p>The right of withdrawal protects consumers (natural persons acting outside their trade or profession), not business buyers, but the plugin never decides that for you. Enable <strong>Consumer self-declaration<\/strong> under <strong>EU Compliance \u2192 Settings \u2192 Public withdrawal form<\/strong> and the form shows a required checkbox where the buyer declares they purchased as a consumer; a business that cannot declare it self-excludes, and the declaration is stored with the request as proof. It is off by default. Use the <code>consumer_check=\"yes\"<\/code> shortcode attribute to force it on a specific landing page, or the <code>ayudawp_euw_show_consumer_check<\/code> filter for custom logic (VIES validation, a customer-type field, etc.).<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20include%20the%20annex%20i.b%20model%20withdrawal%20form%20required%20by%20directive%202011%2F83%2Feu%3F\"><h3>Does the plugin include the Annex I.B model withdrawal form required by Directive 2011\/83\/EU?<\/h3><\/dt>\n<dd><p>Yes. The plugin renders the Annex I.B model form dynamically from the shop name, address (from WooCommerce when available) and notification email, with an optional trader phone configurable from settings. It appears as a collapsible block right below the public withdrawal form, with a printable view available from the same page. Providing this model is a pre-contractual information obligation under Art. 6(1)(h) of Directive 2011\/83\/EU \u2014 the online function added by Directive 2023\/2673 complements but does not replace it.<\/p><\/dd>\n<dt id=\"what%20is%20the%20receipt%20verification%20code%20in%20the%20customer%20email%3F\"><h3>What is the receipt verification code in the customer email?<\/h3><\/dt>\n<dd><p>It is a SHA-256 hash computed from the request data (post ID, customer name, email, order reference, scope, order date and submission timestamp). The customer keeps the email as a tamper-evident proof on a durable medium. If a dispute later arises, you can recompute the hash from the stored fields with the <code>ayudawp_euw_compute_receipt_hash()<\/code> helper and confirm the original submission was not altered.<\/p><\/dd>\n<dt id=\"can%20i%20choose%20who%20can%20manage%20withdrawal%20requests%3F\"><h3>Can I choose who can manage withdrawal requests?<\/h3><\/dt>\n<dd><p>Yes, from <strong>EU Compliance \u2192 Settings \u2192 Permissions<\/strong>. Because each request stores personal data (name, email, IP), you pick which user roles, besides the administrator, may view and manage them. The administrator always has access and cannot be unticked. On sites updating from an earlier version, the roles that could already see requests (typically Editor, and Shop manager on WooCommerce) keep their access so nothing breaks; you then untick any you want to remove. New installs start administrator-only.<\/p><\/dd>\n<dt id=\"does%20it%20support%20hpos%20%28high-performance%20order%20storage%29%3F\"><h3>Does it support HPOS (High-Performance Order Storage)?<\/h3><\/dt>\n<dd><p>Yes. The plugin declares HPOS compatibility on load.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20work%20without%20woocommerce%3F\"><h3>Does the plugin work without WooCommerce?<\/h3><\/dt>\n<dd><p>Yes. The form, shortcode, withdrawal request log, email notifications, SHA-256 receipt hash and native GDPR integration all run as a standalone tool, with their own top-level <strong>Withdrawals<\/strong> menu in the admin and a <strong>Settings<\/strong> submenu. The plugin layers extra features on top automatically when WooCommerce is active: order\/email validation gated by eligible order statuses (with an advisory deadline flag for the admin), \"My Account\" withdrawal endpoint, withdrawal notice injected into transactional emails, \"Withdrawal\" column in the orders screen, private order notes on every status change, and Article 16 exclusions by product\/category. Activating WooCommerce later lights those features up; deactivating it leaves the standalone features intact.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20plugins%20that%20change%20the%20woocommerce%20order%20number%20%28sequential%20order%20numbers%2C%20custom%20order%20numbers%2C%20etc.%29%3F\"><h3>Does it work with plugins that change the WooCommerce order number (Sequential Order Numbers, Custom Order Numbers, etc.)?<\/h3><\/dt>\n<dd><p>Yes. The form accepts both the internal WooCommerce order ID and the displayed order number. The resolver checks a list of known meta keys: the standard <code>_order_number<\/code> and <code>_order_number_formatted<\/code> (WooCommerce Sequential Order Numbers, free and Pro), plus <code>_alg_wc_full_custom_order_number<\/code> and <code>_alg_wc_custom_order_number<\/code> (Tyche \/ WPFactory \"Custom Order Numbers for WooCommerce\"). Add other numbering plugins with the <code>ayudawp_euw_order_number_meta_keys<\/code> filter; for schemes computed on the fly (e.g. YITH Sequential Order Number, custom integrations), short-circuit the lookup with the <code>ayudawp_euw_pre_resolve_wc_order<\/code> filter.<\/p><\/dd>\n<dt id=\"the%20form%20says%20it%20cannot%20match%20the%20email%20with%20the%20order%20number.%20can%20i%20accept%20those%20requests%20anyway%3F\"><h3>The form says it cannot match the email with the order number. Can I accept those requests anyway?<\/h3><\/dt>\n<dd><p>Yes, with <strong>Accept unmatched requests<\/strong> under <strong>EU Compliance \u2192 Settings \u2192 Eligible order statuses<\/strong>. By default the form rejects a submission whose order number and email match no order. With the option on it is registered anyway and flagged as <em>Unverified<\/em>: the customer sees a notice inviting them to check the reference and can still confirm, and the request arrives highlighted in the notification email, in the list and in its detail screen, so you verify it against your records before deciding. Unverified requests are never linked to an order, and the acknowledgement is still sent. Off by default.<\/p><\/dd>\n<dt id=\"the%20form%20says%20the%20request%20is%20no%20longer%20awaiting%20confirmation%2C%20right%20after%20the%20customer%20submitted%20it.%20why%3F\"><h3>The form says the request is no longer awaiting confirmation, right after the customer submitted it. Why?<\/h3><\/dt>\n<dd><p>The two-step flow keeps the validated declaration on the server, in a 15-minute single-use transient, between the form and the review screen. When an object cache does not store transients reliably (a misconfigured Redis or Memcached drop-in, or a cache plugin flushing them aggressively) the declaration is gone by the time the customer confirms. Disable the object cache for a moment and submit again: if the flow completes, that was it. Carrying the declaration in the URL instead would break the guarantee that what gets registered is exactly what was validated, so the fix belongs to the cache configuration.<\/p><\/dd>\n<dt id=\"will%20the%20notice%20appear%20on%20every%20woocommerce%20email%3F\"><h3>Will the notice appear on every WooCommerce email?<\/h3><\/dt>\n<dd><p>No. By default the notice is only added to the customer-facing emails relevant to the withdrawal window: order processing, completed and customer invoice (the manually triggered one). Admin emails never receive the notice. The notice is also gated by the configured list of eligible order statuses (default: Processing and Completed) so the manual invoice email only carries it when the order is in one of those statuses. You can change the email list with the <code>ayudawp_euw_email_ids<\/code> filter and the status list under <strong>EU Compliance \u2192 Settings \u2192 Eligible order statuses<\/strong> or with the <code>ayudawp_euw_allowed_statuses<\/code> filter.<\/p><\/dd>\n<dt id=\"can%20i%20make%20the%20withdrawal%20notice%20in%20the%20emails%20more%20discreet%3F\"><h3>Can I make the withdrawal notice in the emails more discreet?<\/h3><\/dt>\n<dd><p>Yes. Return an empty array from the <code>ayudawp_euw_email_ids<\/code> filter to remove the notice block (heading, text and button) from every order email:<\/p>\n\n<pre><code>add_filter( 'ayudawp_euw_email_ids', '__return_empty_array' );\n<\/code><\/pre>\n\n<p>The My Account button, the public form and the footer link keep working, so the withdrawal function stays accessible as Article 11a requires. You can then add your own wording with WooCommerce's per-email <strong>Additional content<\/strong> field (<strong>WooCommerce \u2192 Settings \u2192 Emails<\/strong>). Point it at your withdrawal page, and add the <code>{order_number}<\/code> placeholder to keep the order pre-filled, for example <code>...\/withdrawal\/?order_id={order_number}<\/code>. Do keep some reference in the order confirmation: it is the contract confirmation on a durable medium, so the withdrawal information should stay reachable from it, just not necessarily as a prominent button.<\/p><\/dd>\n<dt id=\"does%20it%20work%20on%20multilingual%20sites%20%28wpml%2C%20polylang%29%3F\"><h3>Does it work on multilingual sites (WPML, Polylang)?<\/h3><\/dt>\n<dd><p>Yes. The withdrawal status is set once, on the product or category in the site original language, and applies to every translation: excluded-product notice, checkout consents and excluded items on the order all resolve back to the original. An explicit status on a translation still wins. Links to the withdrawal page follow the visitor language whenever a translation exists, and so does the guarantee notice.<\/p>\n\n<p>The bundled <code>wpml-config.xml<\/code> turns the settings that hold customer-facing copy into translatable strings under <strong>WPML \u2192 String Translation<\/strong> or <strong>Languages \u2192 Translations<\/strong>. A setting shows up there once you write your own text in it: left empty, the text comes from the language pack of each locale and already follows the visitor.<\/p>\n\n<p>One limitation: the plugin's own emails (acknowledgement, admin notification, status changes) are composed in the site default language, because they are generated outside the language routing of both plugins. The notices injected into the WooCommerce order emails, both the withdrawal one and the guarantee one, do follow the order language. Per-customer language for the plugin's own emails is on the roadmap.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20pass%20gdpr%20requirements%3F\"><h3>Does the plugin pass GDPR requirements?<\/h3><\/dt>\n<dd><p>The plugin asks for explicit privacy policy acceptance before submission and stores the visitor IP and user agent only for the purpose of legal traceability of the request. See the <strong>Privacy<\/strong> section above for the full list of stored fields. The plugin also integrates natively with the WordPress GDPR tools: a suggested Privacy Policy snippet appears in <strong>Settings \u2192 Privacy \u2192 Policy Guide<\/strong>, and withdrawal data is exposed to <strong>Tools \u2192 Export Personal Data<\/strong> and <strong>Tools \u2192 Erase Personal Data<\/strong> so admins can fulfil access and erasure requests without leaving the WordPress admin.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20the%20customer%20deletes%20their%20wordpress%20user%20account%3F\"><h3>What happens if the customer deletes their WordPress user account?<\/h3><\/dt>\n<dd><p>The withdrawal log is independent of the WordPress user table \u2014 it lives as a private custom post type indexed by the customer email. Deleting the user account does not delete the log automatically; the customer must request erasure through <strong>Tools \u2192 Erase Personal Data<\/strong> (where the plugin registers an eraser that removes every withdrawal request matching the customer email) or you can delete the corresponding <code>ayudawp_withdrawal<\/code> entries manually if your retention policy requires it.<\/p><\/dd>\n<dt id=\"can%20i%20customise%20the%20emails%3F\"><h3>Can I customise the emails?<\/h3><\/dt>\n<dd><p>Yes. From <strong>EU Compliance \u2192 Settings \u2192 Withdrawal emails<\/strong> you can set the sender (\"From name\" and \"From address\") for the plugin's emails and edit the body of the accepted, rejected and completed status emails; left empty, each text falls back to the bundled default. The admin notification can be tailored with the <code>ayudawp_euw_admin_email_lines<\/code> filter, and all strings remain translatable through the standard WordPress text-domain. The emails are sent in plain text; HTML templates that inherit the WooCommerce email theme are planned for a later release.<\/p><\/dd>\n<dt id=\"which%20hooks%20does%20the%20plugin%20expose%20for%20developers%3F\"><h3>Which hooks does the plugin expose for developers?<\/h3><\/dt>\n<dd><p>19 filters and 4 actions. The withdrawal side: <code>ayudawp_euw_grace_days<\/code> (extra days on the deadline), <code>ayudawp_euw_allowed_statuses<\/code> (order statuses that get the button and the notice), <code>ayudawp_euw_email_ids<\/code> (emails carrying the withdrawal notice), <code>ayudawp_euw_allow_unverified_order<\/code>, <code>ayudawp_euw_pre_resolve_wc_order<\/code> and <code>ayudawp_euw_resolve_wc_order<\/code> (short-circuit or audit the order resolver), <code>ayudawp_euw_order_number_meta_keys<\/code> (meta keys checked when matching a typed order number), <code>ayudawp_euw_admin_email_lines<\/code>, <code>ayudawp_euw_validation_result<\/code> (reject a submission, for a captcha) and <code>ayudawp_euw_show_consumer_check<\/code>. The checkout consents: <code>ayudawp_euw_consent_hook<\/code>, <code>ayudawp_euw_consent_hook_priority<\/code>, <code>ayudawp_euw_consent_applies<\/code> and <code>ayudawp_euw_consent_is_required<\/code>. The guarantee notice: <code>ayudawp_euw_guarantee_email_ids<\/code>, <code>ayudawp_euw_guarantee_notice_html<\/code>, <code>ayudawp_euw_guarantee_image_id<\/code>, <code>ayudawp_euw_guarantee_fallback_lang<\/code> and <code>ayudawp_euw_guarantee_language_aliases<\/code>.<\/p>\n\n<p>Actions: <code>ayudawp_euw_after_submission<\/code> (CPT ID, submission data), <code>ayudawp_euw_after_status_change<\/code> (CPT ID, new status, comment), <code>ayudawp_euw_after_form<\/code> (inside the form wrapper, after <code>&lt;\/form&gt;<\/code>) and <code>ayudawp_euw_form_before_submit<\/code> (before the submit button, for a captcha or an extra field).<\/p>\n\n<pre><code>ayudawp_euw_skip_deadline_check is kept for back-compat and has no effect: the deadline is advisory and gates nothing.\n<\/code><\/pre><\/dd>\n<dt id=\"is%20this%20plugin%20enough%20to%20comply%20with%20eu%20directive%202023%2F2673%3F\"><h3>Is this plugin enough to comply with EU Directive 2023\/2673?<\/h3><\/dt>\n<dd><p>It covers the functional requirements the directive imposes EU-wide from 19 June 2026: a discoverable digital withdrawal function, eligibility by order status with an advisory deadline flag, Article 16 exclusions with inheritance, durable proof through the SHA-256 receipt hash, the Annex I.B model form and the two checkout consents. It adds the operational tools the directive does not mandate but that make requests workable, and the harmonised guarantee notice that becomes mandatory in September.<\/p>\n\n<p>Member States can layer national requirements on top: the two-step confirmation expected by the strictest of them is built in. <strong>Compliance ultimately depends on your business model, catalogue and jurisdiction; the plugin provides the building blocks, not legal advice. Consult a consumer-law specialist for your case.<\/strong><\/p><\/dd>\n<dt id=\"is%20this%20plugin%20related%20to%20the%20eu%20omnibus%20directive%3F\"><h3>Is this plugin related to the EU Omnibus Directive?<\/h3><\/dt>\n<dd><p>Partially. This plugin implements the right of withdrawal requirements of Directive 2011\/83\/EU on consumer rights, one of the directives amended by Directive (EU) 2019\/2161 (the Omnibus Directive).<\/p>\n\n<p>It does not cover other Omnibus Directive obligations, such as displaying the lowest price of the last 30 days in price reductions or verifying customer reviews. Those requirements need their own dedicated solutions.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>2.3.0<\/h4>\n\n<p>New module for the EU harmonised legal guarantee notice, mandatory from 27 September 2026: the official notice in 24 languages at the checkout and in your order emails, with the PDF attached. It arrives switched off, with a notice in your dashboard to turn it on.<\/p>\n\n<ul>\n<li>New: The EU harmonised notice on the legal guarantee of conformity, which Article 22a of Directive 2011\/83\/EU (added by Directive (EU) 2024\/825) makes mandatory from 27 September 2026, with the design fixed by Implementing Regulation (EU) 2025\/1960. The plugin bundles the official file in the 24 EU languages and shows it unedited, as the regulation requires: above the place-order button of both the classic and the block checkout, and in the customer order emails with the official PDF attached, which is what reaches the customer when their mail client blocks remote images. The caption links to the Your Europe guarantees page in their language, the destination of the QR code printed on the notice. It is shown only when the cart or the order holds goods, because the notice does not apply to services or digital content.<\/li>\n<li>New: Three display modes for the notice, plus the option of placing it yourself. The whole notice by default, which is the reading nobody disputes; a native disclosure; and a native popover that opens it large over the page, for narrow checkout columns such as the Storefront order review, where a full-width notice comes out too small to read. All three are built with plain HTML, no JavaScript, so they also work inside the block checkout.<\/li>\n<li>New: The Spanish three-year note. The official notice says \"minimum two years\" because that is the EU floor and it cannot be edited, while Spain raised the legal guarantee on new goods to three years from delivery (Art. 120.1 TRLGDCU). The plugin prints that difference next to the notice, never inside it, with a link to your terms and conditions page and, if you want, to the exact section of it. Automatic when your shop base country is Spain, and forceable either way.<\/li>\n<li>New: A \"Legal guarantee\" page of your own, with the [ayudawp_guarantee_notice] shortcode for the notice in full and [ayudawp_guarantee_link] for a permanent link to it from your footer, the same pair the withdrawal page already had. Plus a private order note recording the language and the display mode of the notice each buyer was shown, which is what lets you answer an inspection about an order placed months ago.<\/li>\n<li>New: Five developer filters for the notice: the emails that carry it, its markup, the media-library file served instead of the bundled one, the fallback language and the map of languages with no official file. The settings screen also lets you replace the bundled file per language from your media library.<\/li>\n<li>Improved: On a site updating from an earlier version the module arrives switched off, and says so in the dashboard with a button that switches it on. It changes what your customers see at the checkout, which is not a decision to take on someone else's behalf while they are not looking. New installs start with it on.<\/li>\n<li>Improved: The plugin is now around 5 MB, up from 560 KB, because the official notice ships bundled in 24 languages as an image and as a PDF. Nothing is downloaded at runtime and nothing leaves your server: the regulation does not allow altering the files, so they travel as the Commission publishes them.<\/li>\n<li>Improved: The admin menu is now called EU Compliance, with a new icon. It used to say Withdrawals, which named half of what the plugin does now that the legal guarantee notice hangs from the same menu. Inside, everything keeps its name: Withdrawals for the request list, Settings and Export withdrawals.<\/li>\n<li>Improved: Plugin renamed as EU Withdrawal and Legal Guarantee Compliance. It covered one directive and now covers two, and the old name said nothing about the half that becomes mandatory in September. Nothing moves: same slug, same folder, same settings and same translations, only the name you see in the plugins list and in the directory.<\/li>\n<li>Improved: Tested up to WooCommerce 11.1.<\/li>\n<\/ul>\n\n<p>For older changelog entries, please check the <a href=\"https:\/\/plugins.svn.wordpress.org\/eu-withdrawal-compliance\/trunk\/changelog.txt\">changelog.txt<\/a> file<\/p>","raw_excerpt":"Free EU consumer-rights toolkit: withdrawal function, harmonised legal guarantee notice (GARAN), checkout consents, Article 16 exclusions.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/312715","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=312715"}],"author":[{"embeddable":true,"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/fernandot"}],"wp:attachment":[{"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=312715"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=312715"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=312715"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=312715"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=312715"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=312715"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}