=== EU Withdrawal Button for WooCommerce === Contributors: riinagency Tags: woocommerce, eu, withdrawal, consumer rights, returns Requires at least: 6.2 Tested up to: 7.0 Requires PHP: 7.4 Requires Plugins: woocommerce WC requires at least: 7.0 WC tested up to: 9.5 Stable tag: 2.1.0 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Helps WooCommerce store owners implement the withdrawal flow described in EU Directive 2023/2673. == Description == EU Directive 2023/2673 introduces new requirements for online stores regarding consumer withdrawal rights, taking effect on **June 19, 2026**. **EU Withdrawal Button for WooCommerce** helps you implement a clear, accessible withdrawal flow for your customers: = The 4-Step Flow = 1. **Visible Button** — Sticky withdrawal bar (shown across your store by default, configurable per page type; always on My Account) 2. **Withdrawal Form** — Customer enters order number + email for verification; partial withdrawals supported 3. **Confirmation Step** — Order summary with a separate "Confirm withdrawal" button 4. **Notifications** — Confirmation email to customer + notification to merchant = Free features = * Sticky bar with configurable text and button, plus an optional footer link * Modal popup or dedicated page mode * Order validation (order number + email + withdrawal window check) * Partial withdrawals: customers select the items and quantities to withdraw * Optional refund IBAN field — stored encrypted, masked in lists and exports, auto-erased 30 days after completion * Custom WooCommerce order statuses: "Withdrawal Requested" and "Withdrawal Closed" * Withdrawals overview in the WordPress admin * WooCommerce email integration (shows in WooCommerce → Settings → Emails) * Guest-friendly withdrawal link in WooCommerce order emails — no account needed * Return instructions link in the customer confirmation email * WordPress privacy tools integration (GDPR data export and erasure) * Support for custom order number plugins (Sequential Order Numbers, etc.) * WCAG 2.1 AA accessible (keyboard navigation, focus trap, ARIA labels) * Rate limiting for abuse prevention * Translations bundled: Estonian, Finnish, French, Swedish, Italian, Dutch * HPOS (High-Performance Order Storage) compatible = Pro (paid) = * One-click Complete/Reject actions with automatic customer emails * My Account widgets: countdown badges and withdrawal status column * Thank-You page and order-view withdrawal boxes * Custom colors, styling and custom CSS * Excluded categories and product-level exceptions * GDPR consent checkbox on the withdrawal form * Payment-method-aware IBAN field (hide for card payments) * Statistics dashboard, CSV export, REST API * Priority support = Who Is This For? = WooCommerce store owners who sell to EU consumers and want to provide a clear withdrawal process for their customers. = Disclaimer = This plugin is a technical tool that helps implement a withdrawal flow. It does not constitute legal advice and does not guarantee compliance with any specific regulation. Consult a legal professional to ensure your store meets all applicable requirements. == Installation == 1. Upload the `eu-withdrawal-button-for-woocommerce` folder to `/wp-content/plugins/` 2. Activate the plugin through the 'Plugins' menu in WordPress 3. Go to WooCommerce → Settings → Withdrawal Button to configure 4. The withdrawal button will appear on your storefront == Frequently Asked Questions == = What does this plugin do? = It adds a visible withdrawal button to your store, along with a form where customers can submit withdrawal requests. The plugin validates the order, notifies both parties via email, and tracks the request. = What happens when a customer submits a withdrawal? = The customer receives a confirmation email, the merchant receives a notification, an order note is added, and the order status changes to "Withdrawal Requested" (configurable). = Can I exclude certain products? = Product category exclusions and per-product exceptions are available in the Pro version. = What is the difference between the free and Pro versions? = The free version covers the legal essentials: the withdrawal button, the form, order validation, notifications and a read-only withdrawals overview. Pro adds the merchant toolkit — one-click Complete/Reject with automatic customer emails, My Account widgets, styling, exclusions, GDPR consent checkbox, payment-method IBAN rules, statistics, CSV export and the REST API. = Does it work with custom order number plugins? = Yes, the plugin searches by WooCommerce order ID, custom order number meta fields, and order number output — compatible with Sequential Order Numbers and similar plugins. = In which languages is the plugin available? = English plus bundled translations for Estonian, Finnish, French, Swedish, Italian and Dutch. All texts are translation-ready (gettext), and merchant-entered texts can be translated per language with WPML/Polylang. = Is my data sent to third parties? = No. The plugin stores withdrawal data in your own WordPress database and makes no external requests. Refund IBANs are stored encrypted, shown masked, and erased automatically 30 days after a withdrawal is completed. The plugin integrates with the WordPress privacy tools (Tools → Export/Erase Personal Data). == Translations == Bundled translations and their contributors: * Estonian (et) — Riin Agency * Finnish (fi) — Riin Agency * French (fr_FR) — Riin Agency (community review welcome) * Swedish (sv_SE) — Riin Agency (community review welcome) * Italian (it_IT) — contributed by [Cristina Gregolin (Artilabio)](https://www.artilabio.com/) * Dutch (nl_NL) — contributed by [Mark Govaerts (Bepos)](https://bepos.support/) Want to contribute a translation? Email plugin@riin.eu — you will be credited here. == Screenshots == 1. Sticky bar with withdrawal button on the storefront 2. Withdrawal form modal 3. Confirmation step with order summary 4. WooCommerce settings page == Changelog == = 2.1.0 = * **New pricing model**: one free edition + one Pro plan (€79/year) with every paid feature. Existing Basic licenses purchased earlier remain fully valid. * **New: withdrawals overview for everyone** — the free edition now shows the full withdrawals list in the admin (read-only; one-click management actions are Pro). * **New: GDPR consent checkbox (Pro)** — optional privacy notice + required checkbox on the confirmation step, with a `{privacy_policy}` placeholder linking to your privacy policy page. * **New: payment-method-aware IBAN field (Pro)** — optionally show the refund IBAN field only for offline payments (COD, bank transfer, cheque); card payments are refunded via the gateway. * **New: IBAN protection (all plans)** — refund IBANs are now stored encrypted, displayed masked (EE38****5877) with an explicit reveal action, masked in CSV exports and REST responses, and automatically erased 30 days after the withdrawal is completed (with an audit note). * **New: return instructions page** — select the page with your return instructions; the customer confirmation email links to it (falls back to your WooCommerce Terms page). * **New: WordPress privacy tools integration** — withdrawal records are included in the built-in personal data export and erasure (Tools → Export/Erase Personal Data). * **New translations: Italian and Dutch.** Italian contributed by Cristina Gregolin (Artilabio), Dutch contributed by Mark Govaerts (Bepos) — thank you! * Fix: bundled translations now actually load — the `load_plugin_textdomain()` call was lost in the 2.0.0 refactor, so Estonian/Finnish/French/Swedish stores saw English. * Fix: the Export CSV button (Pro) did nothing — its AJAX handler was never registered. * Fix: the My Account countdown badge replaced the order number link; the linked order number is now always shown with the badge next to it. * Fix: bulk "Mark as completed/rejected" now performs the complete flow (order status, order note, customer email, previous-status restore) exactly like the row actions; the REST API complete/reject endpoints too (previously the REST reject restored the wrong status and re-sent WooCommerce status emails). * Fix: products in excluded categories (and Pro product-level exceptions) can no longer be selected in a partial withdrawal — exempt lines are shown unselectable and filtered server-side. * Fix: the withdrawal form no longer fails on sites with full-page caching (the security nonce baked into cached HTML expired; the public endpoints now rely on rate limiting + order/email verification). * Fix: the customer confirmation email no longer promises a refund deadline tied to the (possibly extended) withdrawal window, and only mentions the "withdrawal closed" email when that email actually exists and is enabled. * Fix: fresh installs now show the sticky bar on all page types by default (existing installations keep their settings). * Fix: plain-text emails no longer contain raw HTML; the merchant email order link is HPOS-safe. * Fix: the "Require order validation" setting is now labelled accurately ("Require email match") — the order number was always verified regardless of the toggle. * Performance: frontend CSS/JS and the modal markup now load only on pages with a withdrawal entry point; the admin orders list and My Account column no longer run one query per row. * Developer: `ra_euwb_confirmation_before_actions` action in the form template; `ra_euwb_offline_payment_methods` filter; shared `set_withdrawal_status()` service behind admin, bulk and REST status changes. = 2.0.2 = * Fix: the optional footer "Right of withdrawal" link is now always visible — it previously inherited the theme's footer text colour and could blend into the background. It now sits on a light strip with a clearly coloured link. * New: French (fr_FR), Finnish (fi) and Swedish (sv_SE) translations bundled. = 2.0.1 = * Fix: the withdrawal total on the confirmation step now updates live as the customer checks/unchecks items or changes quantities, instead of always showing the full order total. * Fix: the withdrawal total now reflects only the selected line items — shipping, fees and other order lines are no longer included. * Tweak: the confirmation total is now labelled "Withdrawal total" for clarity. * Compatibility: tested up to WordPress 7.0. = 2.0.0 = * **WordPress.org edition**. First release published on the WordPress.org plugin directory. Feature parity with 1.5.x, Lite tier only. Paid upgrades continue to be distributed via riin.eu. * Code: Full prefix refactor to `ra_euwb_` / `RA_EUWB_` / `ra-euwb-` across options, hooks, CSS classes, JS globals, nonces and admin menu slugs, to comply with the WordPress.org guidelines on unique prefixes. Existing WC order status slugs (`wc-ewb-withdrawn`, `wc-ewb-completed`), the database table (`{prefix}ewb_withdrawals`) and the `_ra_euwb_deactivated_withdrawal` order meta key are preserved so existing installations continue to work without data migration. * Code: Removed all inline `