BuddyPilot Withdrawal

Description

BuddyPilot Withdrawal for WooCommerce implements the mandatory withdrawal function required by Article 11a of EU Directive 2023/2673 for online traders selling to EU consumers.

From 19 June 2026, every WooCommerce store with EU customers must provide a clearly visible, easily accessible withdrawal function (“withdraw from contract here” button) alongside the existing right of withdrawal informational requirements.

What the plugin does

Customer-facing

  • Article 11a compliant “Withdraw from contract here” button on the My Account order detail page
  • Two-step withdrawal form: item selection, declaration preview, one-click confirm
  • Variable product support: each variant (size, colour, etc.) appears with its full attribute labels as a separate line in the withdrawal form
  • Guest checkout support via direct verification flow (email + order number, no login required)
  • My Account withdrawal history list and declaration detail page
  • Article 16(m) consent capture at checkout for digital and virtual goods (configurable: required, optional, or hidden)
  • Customer declaration email serving as the durable-medium acknowledgement required by Article 11a(3)
  • Withdrawal resolved email sent to the customer after the operator closes the declaration

Operator-facing

  • Order edit metabox for registering declarations received via phone, mail or in person
  • Standalone “Add new declaration” page for high-volume operator queues without leaving the declarations list
  • Declarations list with search, filtering and sorting in WooCommerce admin
  • Declaration detail page with full audit trail and status management
  • Admin notification email sent immediately when a customer submits a withdrawal

Legal and compliance

  • Custom order status wc-withdrawal (optional, plugin-registered) with a full change history logged as WooCommerce order notes
  • Annex I(A) withdrawal information page available to generate with one click from Settings
  • Annex I(B) model withdrawal form page available to generate with one click from Settings, published as a WordPress page and auto-linked from order emails and My Account
  • Configurable refund period (default 14 days, matches your contract terms)
  • Configurable “delivered” statuses that start the withdrawal clock
  • Return cost attribution (consumer pays or trader pays, per Annex I(A) requirements)
  • GDPR personal data export and anonymisation compatible with WordPress privacy tools
  • HPOS compatibility (High-Performance Order Storage) and legacy post-meta mode
  • WCAG 2.2 AA accessibility compliance on all customer-facing forms
  • Polish and English translations included

Pro addon

Extended functionality is available via the BuddyPilot Withdrawal Pro addon:

  • Operator-approved automatic refund built from declared items (one click from the declaration screen)
  • Download-count verification: restores withdrawal right when a digital product was never actually downloaded, reducing unjustified refusal of refunds
  • WooCommerce Subscriptions support: cancels future renewals, prorates the current billing period per Article 9(2)(b)(iii)
  • WooCommerce Product Bundles support: automatic handling by bundle type; for per-item bundles with a configured discount, choose whether partial returns keep the paid amount or forfeit the entire bundle discount
  • PDF export of the legal withdrawal declaration
  • Country-specific Annex I(B) form generation

Installation

  1. Upload the plugin folder to /wp-content/plugins/, or install via Plugins > Add New.
  2. Activate the plugin through the Plugins menu in WordPress.
  3. Go to WooCommerce > Settings > Withdrawal and configure:
    • General: withdrawal period, grace period, delivered statuses
    • Trader details: name, address, return address, return cost responsibility
    • Customer experience: consent mode for digital goods, withdrawal information page
  4. In the Customer experience section click “Create withdrawal information page” to publish an EU-compliant Annex I(A) notice and Annex I(B) model form. The page URL is auto-linked from order emails and the My Account view-order screen.
  5. Customers eligible to withdraw will see a “Withdraw from contract here” call-to-action on their order page. The form works without JavaScript.

FAQ

Does the plugin work with guest checkout?

Yes. Guest customers verify their identity via email + order number on the public withdrawal page. No login required.

Does the plugin process refunds automatically?

The free version records the withdrawal declaration and changes the order status to wc-withdrawal. The operator processes the refund using native WooCommerce tools. One-click automatic refund built from declared items is available in the Pro addon.

What does the plugin NOT do?

The plugin records withdrawal declarations as legal artifacts and notifies both the customer and operator. It does not automatically refund money, verify return shipments, enforce refund deadlines, or handle accounting and VAT. The shop operator is responsible for processing the refund within the legally required period (14 days by default, configurable under WooCommerce > Settings > Withdrawal > General).

Does the plugin support variable products?

Yes, with no extra configuration needed. Variable products (different sizes, colours, etc.) are fully supported in the free version. Each variant appears in the withdrawal form as a separate line with its full attribute labels (e.g. T-shirt — Size: L, Colour: Black), so the customer specifies exactly what they are returning and the operator sees the same detail on the declarations list and declaration detail page.

Does the plugin work with WooCommerce Subscriptions or Product Bundles?

Subscription, bundle and composite product handling (cancel renewals, proration, bundle refund modes) is part of the Pro addon. The free version treats them as standard products.

Does the plugin cover Article 16(m) consent for digital goods?

Yes. The plugin adds an explicit consent checkbox at checkout when the cart contains downloadable or virtual products. The operator can choose between “required before purchase”, “optional” or “hidden” (trader waives the exclusion). Consent is recorded on the order and displayed in the withdrawal form.

When does the withdrawal clock start?

The clock starts from the exact moment the order status changes to one of the “delivered” statuses configured under WooCommerce > Settings > Withdrawal > General. The plugin records the precise timestamp of that status change. As long as the deadline has not passed, the customer sees how many days remain in the withdrawal form — once the deadline passes, the withdrawal button is no longer shown. Any built-in or custom WooCommerce order status can be mapped as a “delivered” trigger (e.g. “Completed”, a custom “Shipped” status, etc.). Leaving the list empty means the clock never starts — useful during testing or when you want withdrawal to be available indefinitely.

Is the plugin HPOS-compatible?

Yes. The plugin is fully compatible with WooCommerce High-Performance Order Storage (HPOS) and falls back to legacy post-meta mode automatically.

Reviews

There are no reviews for this plugin.

Contributors & Developers

“BuddyPilot Withdrawal” is open source software. The following people have contributed to this plugin.

Contributors

Changelog

1.0.2

  • Code: renamed all short bpw_ / bpw- identifiers to the full buddypilot_withdrawal_ / buddypilot-withdrawal- prefix throughout — affects AJAX/admin-post action names, script handles, localized JS object, metabox ID, WooCommerce field type, nonce field names, lock keys and GET parameters. Resolves WordPress.org unique-prefix review requirement.

1.0.1

  • Security: all admin and AJAX request handlers now verify user permissions before nonce verification, consistent with WordPress security guidelines.
  • Security: the AJAX path in the operator registration handler now uses check_ajax_referer() instead of check_admin_referer(), returning a proper AJAX error response on nonce failure.
  • Security: added current_user_can() gate to the admin notice handler for info-page creation status.
  • Security: currency symbol and separator values from localized price format data are now escaped on the JavaScript side before insertion into the DOM.
  • Code: moved inline JavaScript from the operator registration template to an enqueued file (assets/js/admin/operator-registration.js); strings passed via wp_localize_script().
  • Code: removed load_plugin_textdomain() call; WordPress 4.6 and later loads translations automatically for plugins hosted on WordPress.org.

1.0.0

  • First stable release. Full implementation of the Article 11a withdrawal function: two-step form, guest verification, operator manual registration, declarations admin list, configurable period and delivered statuses, Article 16(m) consent capture, Annex I(A)/(B) page generator, customer and admin emails, My Account withdrawal history, HPOS support, GDPR hooks, WCAG 2.2 AA compliance, Polish and English translations.