Linux 软件免费装
Banner图

EU Withdrawal Compliance

开发者 fernandot
ayudawp
更新时间 2026年5月30日 19:29
PHP版本: 7.4 及以上
WordPress版本: 7.0
版权: GPLv2 or later
版权网址: 版权信息

标签

woocommerce gdpr compliance withdrawal consumer-rights

下载

1.4.0 1.4.1 1.5.0 1.6.1 1.6.0 1.7.0

详情介绍:

From June 19, 2026, EU Directive 2023/2673 obliges every online retailer in the European Union to offer a digital withdrawal function that is at least as easy to use as the purchase flow itself. Most plugins in the directory stop at "a button". This one ships the complete toolkit every EU store needs to comply — and a few things competitors don't offer at any price. Only this plugin in the directory ships, all of it, for free Public-facing pieces WooCommerce-specific pieces (auto-activated when WooCommerce is detected) Admin tooling Built for production

安装:

  1. Upload the plugin folder to /wp-content/plugins/.
  2. Activate the plugin from the Plugins screen.
  3. The plugin creates a "Right of withdrawal" page automatically with a sample legal template. Review and edit it from Pages.
  4. Go to Withdrawals → Settings to configure the notification email address and the page that hosts the form.
  5. 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.

屏幕截图:

  • Withdrawal log inside the WordPress admin.
  • Per-request detail screen with status management, including the captured checkout consents (text, accepted/declined, timestamp, IP, user agent).
  • WooCommerce My Account integration with per-order Withdraw button.
  • EU Withdrawal Settings Page (WooCommerce active), with the Checkout consent, Annex I.B model and Excluded products notice sections.
  • EU Withdrawal Settings Page (Standalone).
  • 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.
  • Per-category "Withdrawal status" dropdown in Products → Categories edit screen.
  • Excluded products notice rendered on the public single product page (between price and add-to-cart button).
  • Mandatory digital-content consent (Art. 16(m)) shown at the WooCommerce checkout.
  • Optional service-start consent (Art. 14(4)(a)) shown at the WooCommerce checkout.
  • Annex I.B model withdrawal form rendered as a collapsible block below the public withdrawal form, with a printable view link.
  • 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.
  • Export withdrawals page: filtered CSV export of the request log by status and date range for accounting and consumer-protection audits.

升级注意事项:

1.7.0 Adds the two-step "Confirm withdrawal" function and a complete durable-medium acknowledgement (full declaration content + date and time of submission) required by Article 11a of Directive 2023/2673, plus CSV export of the request log for audits.

常见问题:

Will the form check the 14-day deadline?

Yes, when WooCommerce is active. If the order is older than the configured window the plugin rejects the request with a clear message. You can configure the calculation basis (order date vs. completion date) and add extra grace days directly from Withdrawals → Settings. The legacy ayudawp_euw_grace_days and ayudawp_euw_skip_deadline_check filters still work for programmatic overrides.

How do I mark products that are excluded from the right of withdrawal (Article 16)?

The plugin uses a single Withdrawal status dropdown set per category and per product.

  1. By category: go to Products → Categories, edit the category and pick a "Withdrawal status" — for example Other Article 16 exception for perishable or custom-made goods, or Digital content (Art. 16(m)) for sealed digital content. Every product in that category (and its descendant categories) will inherit the status automatically.
  2. By product: edit the product, scroll to the General tab and pick the "Withdrawal status" there. By default it is set to — Inherit from category; pick any other option (including Standard) to override the inheritance for that product only.
The four possible statuses are:
  • Standard — withdrawal applies normally (default).
  • Digital content (Art. 16(m)) — product is excluded from the withdrawal right, and a mandatory consent checkbox is shown at the WooCommerce checkout for any cart containing the product.
  • Service started early (Art. 14(4)(a)) — withdrawal still applies, and an optional consent checkbox is shown at checkout so the trader can charge a pro-rated amount if the customer withdraws after the service has started.
  • Other Article 16 exception — product is excluded (perishable, custom-made, hygiene-sealed, etc.), no checkout consent needed.
When a withdrawal request lands on an order containing excluded items, the plugin flags it in the admin notification email and on the request detail screen. The request is never auto-rejected, because a partial withdrawal over the non-excluded items in the same order can still be valid. The admin reviews and decides. If the Excluded products notice is enabled (default: yes), a configurable notice will also appear on the single product page between price and add-to-cart button so the consumer reads it before purchasing. Upgrading from earlier versions: any category that was previously listed in the retired "Excluded categories" picker is migrated automatically to the new per-category dropdown (with status Other Article 16 exception) on the next admin request. No configuration is lost.

How do the checkout consent checkboxes work (Art. 16(m) and Art. 14(4)(a))?

From version 1.5.0 the plugin can inject two consent checkboxes at the WooCommerce checkout when the cart contains products flagged for them:

  • Type A (mandatory, Art. 16(m)): digital content. The customer must accept it to complete the order; without acceptance recorded, the customer keeps the 14-day withdrawal right even after accessing the content.
  • Type B (optional, Art. 14(4)(a)): services started within the 14-day window. If accepted, the trader may charge a pro-rated amount when the customer withdraws after the service has started. Without it, an early withdrawal forces a full refund.
Each flag is set per product (General tab) or per category (Edit Category screen), with full subcategory inheritance — the same hierarchy used by the Article 16 exclusions module. The exact text shown to the customer, plus accepted/declined state, timestamp, IP and user agent, is persisted on the order so the trader has durable proof if the customer later contests the request. The metabox of each withdrawal request also surfaces these consents for the linked order. The two checkboxes can be enabled/disabled globally from Withdrawals → Settings → Checkout consent, and their text is fully editable.

Does the plugin include the Annex I.B model withdrawal form required by Directive 2011/83/EU?

Yes, from version 1.5.0. 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 — the online function added by Directive 2023/2673 complements but does not replace it.

What is the receipt verification code in the customer email?

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 ayudawp_euw_compute_receipt_hash() helper and confirm the original submission was not altered.

Where are withdrawal requests stored?

Each request is saved as a private custom post type entry called ayudawp_withdrawal. You can manage them under the top-level Withdrawals menu in your admin area. They are not publicly accessible from the frontend.

Does it support HPOS (High-Performance Order Storage)?

Yes. The plugin declares HPOS compatibility on load.

Does the plugin work without WooCommerce?

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 Withdrawals menu in the admin and a Settings submenu. The plugin layers extra features on top automatically when WooCommerce is active: order/email validation with the 14-day deadline, "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.

Does it work with plugins that change the WooCommerce order number (Sequential Order Numbers, Custom Order Numbers, etc.)?

Yes. The form accepts both the internal WooCommerce order ID and the displayed order number. The resolver looks up the customer-facing number in the standard _order_number post meta, which covers WooCommerce Sequential Order Numbers (free and Pro), Custom Order Numbers for WooCommerce (WPFactory) and any plugin that follows the same convention. For plugins that store the number elsewhere or compute it on the fly (e.g. YITH Sequential Order Number, custom integrations), use the ayudawp_euw_pre_resolve_wc_order filter to provide your own resolver.

Will the notice appear on every WooCommerce email?

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 ayudawp_euw_email_ids filter and the status list under Withdrawals → Settings → Eligible order statuses or with the ayudawp_euw_allowed_statuses filter.

In which languages is the plugin available?

All strings are translation-ready. Translations are managed through the official WordPress.org platform at translate.wordpress.org, so any locale with enough translated strings is delivered automatically to your site when the WordPress site language matches. Contributions to existing or new locales are welcome there.

Does the plugin pass GDPR requirements?

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 Privacy section above for the full list of stored fields. From version 1.4.0 the plugin also integrates natively with the WordPress GDPR tools: a suggested Privacy Policy snippet appears in Settings → Privacy → Policy Guide, and withdrawal data is exposed to Tools → Export Personal Data and Tools → Erase Personal Data so admins can fulfil access and erasure requests without leaving the WordPress admin.

What happens if the customer deletes their WordPress user account?

The withdrawal log is independent of the WordPress user table — 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 Tools → Erase Personal Data (where the plugin registers an eraser that removes every withdrawal request matching the customer email) or you can delete the corresponding ayudawp_withdrawal entries manually if your retention policy requires it.

Can I customise the email subjects and bodies?

Currently the emails are sent in plain text and their copy is translatable through the standard WordPress text-domain. HTML email templates that respect the WooCommerce email theme are planned for a later release. For now, advanced customisation requires hooking into the wp_mail filters.

Which hooks does the plugin expose for developers?

Filters:

  • ayudawp_euw_grace_days — extra days added to the 14-day deadline. The default is the value stored in settings; the filter receives that value, so returning $days + N adds on top of it.
  • ayudawp_euw_skip_deadline_check — return true to disable the deadline check entirely. Receives the WC_Order as second argument.
  • ayudawp_euw_email_ids — array of WooCommerce email IDs where the withdrawal notice is injected.
  • ayudawp_euw_allowed_statuses — array of order statuses (without the wc- prefix) for which the withdrawal button and email notice are offered. Receives the value stored in settings and the current WC_Order (when available).
  • ayudawp_euw_allow_unverified_order — return true to accept submissions whose order number cannot be matched against a real WooCommerce order. Useful for sites that also handle non-WC purchases.
  • ayudawp_euw_pre_resolve_wc_order — short-circuit the order resolver. Return a WC_Order instance to accept, false to reject, or null (default) to fall through to the built-in strategies. Useful for plugins that store the displayed order number outside the standard _order_number post meta (e.g. YITH Sequential Order Number, custom ERP integrations).
  • ayudawp_euw_resolve_wc_order — late filter that receives the resolved WC_Order (or false) and the raw reference, for auditing or last-chance overrides.
Actions:
  • ayudawp_euw_after_submission — fires after a withdrawal request has been processed. Arguments: CPT ID, submission data array.
  • ayudawp_euw_after_status_change — fires after a status change (individual or bulk). Arguments: CPT ID, new status, optional admin comment.
  • ayudawp_euw_after_form — fires inside the public form wrapper, right after the </form> tag, so modules can inject content below the form without coupling. No arguments. Used internally by the Annex I.B model form.

Is this plugin enough to comply with EU Directive 2023/2673?

The plugin covers the functional requirements that Directive 2023/2673 imposes EU-wide from 19 June 2026: a discoverable digital withdrawal function, deadline validation, Article 16 exclusions with subcategory inheritance, durable-medium proof via the SHA-256 receipt hash, the model form from Annex I.B of Directive 2011/83/EU and the double-consent checkboxes at checkout that enable the Art. 16(m) and Art. 14(4)(a) exceptions. On top of that it adds operational tools that the directive does not mandate but that make handling requests practical: per-status email injection, status lifecycle with bulk actions, native GDPR integration, public notice on excluded products and full traceability. Member States can layer extra national requirements on top of the EU baseline — the two-step confirmation flow with an intermediate review page expected by the strictest member states (Germany, for example) ships since version 1.7.0; a future release will adapt to any further requirement in the final Spanish Real Decreto once it is published. Legal compliance ultimately depends on your business model, catalog and jurisdiction; the plugin provides the technical building blocks, not legal advice — consult a consumer-law specialist for your specific case.

更新日志:

1.7.0