| 开发者 |
fernandot
ayudawp |
|---|---|
| 更新时间 | 2026年10月2日 06:01 |
| PHP版本: | 7.4 及以上 |
| WordPress版本: | 7.1 |
| 版权: | GPLv2 or later |
| 版权网址: | 版权信息 |
[ayudawp_withdrawal_form] for the form, [ayudawp_withdrawal_link] for a permanent link to it from any footer or widget area, [ayudawp_guarantee_notice] for the guarantee notice, [ayudawp_guarantee_link] for its page, and [ayudawp_withdrawal_excluded_notice] for page builders that skip the standard WooCommerce hooks.wpml-config.xml 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.
Built for production
/wp-content/plugins/.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 27 September 2026 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. Online the law asks for it in colour, unedited and in a prominent place, and the Commission's guidelines add that it should be shown in full, legible at the default display size 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. It arrives switched off on sites updating from an earlier version, 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 EU Compliance → Settings → EU legal guarantee notice (GARAN).
Not yet, and most shops do not need it. GARAN is a different thing from the notice: the notice covers the legal guarantee and every shop selling goods has to display it, while GARAN stands for a commercial durability guarantee that a producer 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. 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.
They are the official files from the European Commission guidelines page, bundled unmodified under assets/guarantee-notice/ with the md5 of each one in CHECKSUMS.txt 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.
© European Union, 2025. Reused under the CC BY 4.0 licence, the Commission reuse policy implemented by Decision 2011/833/EU.
Pick another display mode under EU Compliance → Settings → EU legal guarantee notice (GARAN):
<details> element.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 next to the notice, never inside it, linking to your terms and conditions page and, if you write the id 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.
Yes. Put [ayudawp_guarantee_notice] on a page for the notice in full (mode="details" or mode="popover" for the other two), select that page in the settings, and [ayudawp_guarantee_link] gives you a permanent link to it, exactly like [ayudawp_withdrawal_link] does for the withdrawal page. Both accept text and class.
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.
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 ayudawp_euw_guarantee_fallback_lang and ayudawp_euw_guarantee_language_aliases filters change both rules.
They solve different halves of the same obligation: the native feature is a form, and this plugin is the toolkit around it.
WooCommerce 11.1 added order_withdrawal (off by default, under WooCommerce > Settings > Advanced > Features): 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.
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.
Yes, on WooCommerce sites and for customers with an account. My Account → Right of withdrawal 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. 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 EU Compliance → Settings → General.
Yes, with ayudawp_euw_consent_hook, but read the trade-off first. They render on woocommerce_after_order_notes, 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.
add_filter( 'ayudawp_euw_consent_hook', function () { return 'woocommerce_review_order_before_submit'; } );
Returning an empty string suppresses the render entirely. ayudawp_euw_consent_applies decides per cart and ayudawp_euw_consent_is_required makes either one mandatory.
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 flagged in the admin notification instead, and you check the real delivery date and decide. You can tune the calculation under EU Compliance → Settings: order date or completion date as the basis, plus grace days. If your start date is reliable (services, digital content, shop pickup), switch Deadline enforcement from Advisory to Strict and late requests are blocked outright. Advisory is the default and the safe choice for goods.
With a single Withdrawal status dropdown, set per category (Products → Categories) 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:
Page builders such as Divi, Elementor, Bricks or ShopLentor render their own single-product template and skip the standard WooCommerce hook (woocommerce_single_product_summary) where the plugin injects the excluded-product notice, so it does not appear automatically. Drop the [ayudawp_withdrawal_excluded_notice] 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 id="123" to target a specific product.
The plugin injects them when the cart holds products flagged for them:
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 Consumer self-declaration under EU Compliance → Settings → Public withdrawal form 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 consumer_check="yes" shortcode attribute to force it on a specific landing page, or the ayudawp_euw_show_consumer_check filter for custom logic (VIES validation, a customer-type field, etc.).
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 — the online function added by Directive 2023/2673 complements but does not replace it.
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.
Yes, from EU Compliance → Settings → Permissions. 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.
Yes. The plugin declares HPOS compatibility on load.
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 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.
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 _order_number and _order_number_formatted (WooCommerce Sequential Order Numbers, free and Pro), plus _alg_wc_full_custom_order_number and _alg_wc_custom_order_number (Tyche / WPFactory "Custom Order Numbers for WooCommerce"). Add other numbering plugins with the ayudawp_euw_order_number_meta_keys filter; for schemes computed on the fly (e.g. YITH Sequential Order Number, custom integrations), short-circuit the lookup with the ayudawp_euw_pre_resolve_wc_order filter.
Yes, with Accept unmatched requests under EU Compliance → Settings → Eligible order statuses. 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 Unverified: 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.
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.
No. The notice goes into the customer email WooCommerce sends for each order status ticked under EU Compliance → Settings → Eligible order statuses: Processing and Completed by default, plus On hold or Refunded if you tick them. So does the manual invoice email, for orders in those statuses. Admin emails never receive it. Change the email list with the ayudawp_euw_email_ids filter and the status list with ayudawp_euw_allowed_statuses.
Yes. Return an empty array from the ayudawp_euw_email_ids filter to remove the notice block (heading, text and button) from every order email:
add_filter( 'ayudawp_euw_email_ids', '__return_empty_array' );
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 Additional content field (WooCommerce → Settings → Emails). Point it at your withdrawal page, and add the {order_number} placeholder to keep the order pre-filled, for example .../withdrawal/?order_id={order_number}. 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.
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.
The bundled wpml-config.xml turns the settings that hold customer-facing copy into translatable strings under WPML → String Translation or Languages → Translations. 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.
The acknowledgement of receipt follows the language of the page the customer sent the form from, provided the language is part of the URL; the notification to the shop, the request title and the order note stay in the site default language. One limitation: the status-change emails (accepted, rejected, completed) are still composed in the site default language, with per-customer language on the roadmap. The notices injected into the WooCommerce order emails, withdrawal and guarantee alike, follow the order language.
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. 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.
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.
Yes. From EU Compliance → Settings → Withdrawal emails 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 ayudawp_euw_admin_email_lines 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.
21 filters and 4 actions. The withdrawal side: ayudawp_euw_grace_days (extra days on the deadline), ayudawp_euw_allowed_statuses (order statuses that get the button and the notice), ayudawp_euw_show_withdrawal (hide both for specific orders, or bring them back on an order that only holds excluded products), ayudawp_euw_email_ids (emails carrying the withdrawal notice), ayudawp_euw_allow_unverified_order, ayudawp_euw_pre_resolve_wc_order and ayudawp_euw_resolve_wc_order (short-circuit or audit the order resolver), ayudawp_euw_order_number_meta_keys (meta keys checked when matching a typed order number), ayudawp_euw_admin_email_lines, ayudawp_euw_validation_result (reject a submission, for a captcha), ayudawp_euw_form_via_admin_post (send the form through admin-post.php again) and ayudawp_euw_show_consumer_check. The checkout consents: ayudawp_euw_consent_hook, ayudawp_euw_consent_hook_priority, ayudawp_euw_consent_applies and ayudawp_euw_consent_is_required. The guarantee notice: ayudawp_euw_guarantee_email_ids, ayudawp_euw_guarantee_notice_html, ayudawp_euw_guarantee_image_id, ayudawp_euw_guarantee_fallback_lang and ayudawp_euw_guarantee_language_aliases.
Actions: ayudawp_euw_after_submission (CPT ID, submission data), ayudawp_euw_after_status_change (CPT ID, new status, comment), ayudawp_euw_after_form (inside the form wrapper, after </form>) and ayudawp_euw_form_before_submit (before the submit button, for a captcha or an extra field).
ayudawp_euw_skip_deadline_check is kept for back-compat and has no effect: the deadline is advisory and gates nothing.
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. Member States can layer national requirements on top: the two-step confirmation expected by the strictest of them is built in. 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.
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). 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.
ayudawp_euw_show_withdrawal filter can now bring the button and the notice back on an order that only holds excluded products. It still cannot offer them on an order in a status you left out, or past the deadline in strict mode.ayudawp_euw_show_withdrawal keeps the withdrawal button and the email notice off specific orders, for example a course that starts once the withdrawal period is over. ayudawp_euw_form_via_admin_post sends the form through admin-post.php again, in case something in front of a site refuses a POST to a public page.ayudawp_euw_validation_result is its place.