Title: BuddyPilot Withdrawal
Author: BuddyPilot
Published: <strong>May 20, 2026</strong>
Last modified: May 20, 2026

---

Search plugins

![](https://ps.w.org/buddypilot-withdrawal/assets/banner-772x250.png?rev=3539945)

![](https://ps.w.org/buddypilot-withdrawal/assets/icon-256x256.png?rev=3539945)

# BuddyPilot Withdrawal

 By [BuddyPilot](https://profiles.wordpress.org/buddypilot/)

[Download](https://downloads.wordpress.org/plugin/buddypilot-withdrawal.1.0.3.zip)

 * [Details](https://wordpress.org/plugins/buddypilot-withdrawal/#description)
 * [Reviews](https://wordpress.org/plugins/buddypilot-withdrawal/#reviews)
 *  [Installation](https://wordpress.org/plugins/buddypilot-withdrawal/#installation)
 * [Development](https://wordpress.org/plugins/buddypilot-withdrawal/#developers)

 [Support](https://wordpress.org/support/plugin/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](https://buddypilot.io/plugins/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:
 4.  * **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
 5. 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.
 6. 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

 *   [ BuddyPilot ](https://profiles.wordpress.org/buddypilot/)
 *   [ Dominik Kawula ](https://profiles.wordpress.org/domkawula/)

[Translate “BuddyPilot Withdrawal” into your language.](https://translate.wordpress.org/projects/wp-plugins/buddypilot-withdrawal)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/buddypilot-withdrawal/),
check out the [SVN repository](https://plugins.svn.wordpress.org/buddypilot-withdrawal/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/buddypilot-withdrawal/)
by [RSS](https://plugins.trac.wordpress.org/log/buddypilot-withdrawal/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 1.0.3

 * Tested and confirmed compatible with WordPress 7.0.
 * Security: nonce is now verified before consuming a rate-limit slot, preventing
   CSRF probes from exhausting a user’s hourly budget.
 * Security: anonymous (guest) rate-limit buckets are now scoped per hashed IP instead
   of a shared `user_id=0` bucket.
 * Security: `sealed_map` and GET presealed IDs are validated against the order 
   before use, preventing crafted requests from attaching sealed confirmations to
   ordinary items.
 * Security: `apply_filters('buddypilot_withdrawal_declaration_items_payload')` 
   output is re-validated: entries with `item_id=0`, negative quantities or non-
   array values are stripped.
 * Security: `PermissionChecker` now explicitly blocks `user_id=0` regardless of
   order `customer_id`.
 * Security: `OperatorRegistration` checks `EXCLUDED_STATUSES` at handler entry 
   and flushes the permission cache after order save.
 * Security: `DeclarationRepository` validates `filing_date` format and rejects 
   zero-date strings.
 * Security: `RateLimit::tally()` returns `PHP_INT_MAX` when the rate-limit table
   is missing, preventing the limiter from silently becoming a no-op.
 * Fix: `round(qty, 10)` in `get_declared_quantities()` prevents IEEE-754 epsilon
   accumulation on fractional product quantities.
 * Fix: removed spurious `user_register` hook from Privacy Manager; only `woocommerce_created_customer`
   is used.

#### 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.

## Meta

 *  Version **1.0.3**
 *  Last updated **19 minutes ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 5.8 or higher **
 *  Tested up to **7.0**
 *  PHP version ** 7.4 or higher **
 * Tags
 * [compliance](https://wordpress.org/plugins/tags/compliance/)[eu](https://wordpress.org/plugins/tags/eu/)
   [right of withdrawal](https://wordpress.org/plugins/tags/right-of-withdrawal/)
   [withdrawal](https://wordpress.org/plugins/tags/withdrawal/)[woocommerce](https://wordpress.org/plugins/tags/woocommerce/)
 *  [Advanced View](https://wordpress.org/plugins/buddypilot-withdrawal/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/buddypilot-withdrawal/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/buddypilot-withdrawal/reviews/)

## Contributors

 *   [ BuddyPilot ](https://profiles.wordpress.org/buddypilot/)
 *   [ Dominik Kawula ](https://profiles.wordpress.org/domkawula/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/buddypilot-withdrawal/)