{"id":319606,"date":"2026-06-01T13:12:48","date_gmt":"2026-06-01T13:12:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/beziworld-withdrawal-for-woocommerce\/"},"modified":"2026-07-10T19:03:43","modified_gmt":"2026-07-10T19:03:43","slug":"beziworld-withdrawal-for-woocommerce","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/beziworld-withdrawal-for-woocommerce\/","author":23394266,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"2.86.0","stable_tag":"2.86.0","tested":"7.0.2","requires":"6.4","requires_php":"7.4","requires_plugins":null,"header_name":"BeziWorld Withdrawal for WooCommerce","header_author":"Kamil \u0106wiertnia","header_description":"EU Directive 2023\/2673 compliant withdrawal-from-contract flow for WooCommerce. One-click form, partial returns, automatic confirmation, configurable refund.","assets_banners_color":"308dbd","last_updated":"2026-07-10 19:03:43","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/beziworld.eu\/","header_plugin_uri":"https:\/\/beziworld.eu\/plugins\/withdrawal-for-woocommerce","header_author_uri":"https:\/\/beziworld.eu","rating":5,"author_block_rating":0,"active_installs":10,"downloads":716,"num_ratings":1,"support_threads":1,"support_threads_resolved":1,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.2":{"tag":"1.0.2","author":"beziworld","date":"2026-06-01 13:12:36"},"1.1.0":{"tag":"1.1.0","author":"beziworld","date":"2026-06-01 14:34:20"},"1.2.0":{"tag":"1.2.0","author":"beziworld","date":"2026-06-01 16:31:25"},"2.15.4":{"tag":"2.15.4","author":"beziworld","date":"2026-06-01 19:35:45"},"2.15.5":{"tag":"2.15.5","author":"beziworld","date":"2026-06-01 20:17:00"},"2.16.0":{"tag":"2.16.0","author":"beziworld","date":"2026-06-01 20:53:43"},"2.17.0":{"tag":"2.17.0","author":"beziworld","date":"2026-06-22 20:13:33"},"2.18.0":{"tag":"2.18.0","author":"beziworld","date":"2026-06-24 16:22:13"},"2.19.0":{"tag":"2.19.0","author":"beziworld","date":"2026-06-24 16:50:16"},"2.20.0":{"tag":"2.20.0","author":"beziworld","date":"2026-06-24 17:04:35"},"2.21.0":{"tag":"2.21.0","author":"beziworld","date":"2026-06-24 17:14:12"},"2.22.0":{"tag":"2.22.0","author":"beziworld","date":"2026-06-24 17:21:45"},"2.23.0":{"tag":"2.23.0","author":"beziworld","date":"2026-06-24 17:57:43"},"2.24.0":{"tag":"2.24.0","author":"beziworld","date":"2026-06-24 18:02:20"},"2.25.0":{"tag":"2.25.0","author":"beziworld","date":"2026-06-24 18:36:34"},"2.26.0":{"tag":"2.26.0","author":"beziworld","date":"2026-06-24 19:22:01"},"2.27.0":{"tag":"2.27.0","author":"beziworld","date":"2026-06-24 19:28:19"},"2.28.0":{"tag":"2.28.0","author":"beziworld","date":"2026-06-24 19:35:12"},"2.29.0":{"tag":"2.29.0","author":"beziworld","date":"2026-06-24 19:40:35"},"2.30.0":{"tag":"2.30.0","author":"beziworld","date":"2026-06-24 19:45:41"},"2.31.0":{"tag":"2.31.0","author":"beziworld","date":"2026-06-24 20:13:13"},"2.32.0":{"tag":"2.32.0","author":"beziworld","date":"2026-06-24 20:19:27"},"2.33.0":{"tag":"2.33.0","author":"beziworld","date":"2026-06-24 20:25:23"},"2.34.0":{"tag":"2.34.0","author":"beziworld","date":"2026-06-24 20:29:26"},"2.35.0":{"tag":"2.35.0","author":"beziworld","date":"2026-06-24 20:35:28"},"2.36.0":{"tag":"2.36.0","author":"beziworld","date":"2026-06-24 20:39:34"},"2.37.0":{"tag":"2.37.0","author":"beziworld","date":"2026-06-24 20:43:37"},"2.38.0":{"tag":"2.38.0","author":"beziworld","date":"2026-06-24 20:49:13"},"2.39.0":{"tag":"2.39.0","author":"beziworld","date":"2026-06-25 07:09:22"},"2.40.0":{"tag":"2.40.0","author":"beziworld","date":"2026-06-25 07:26:24"},"2.41.0":{"tag":"2.41.0","author":"beziworld","date":"2026-06-25 09:18:10"},"2.42.0":{"tag":"2.42.0","author":"beziworld","date":"2026-06-25 09:29:22"},"2.43.0":{"tag":"2.43.0","author":"beziworld","date":"2026-06-25 12:07:41"},"2.44.0":{"tag":"2.44.0","author":"beziworld","date":"2026-06-25 12:43:02"},"2.45.0":{"tag":"2.45.0","author":"beziworld","date":"2026-07-10 11:05:37"},"2.46.0":{"tag":"2.46.0","author":"beziworld","date":"2026-07-10 11:10:46"},"2.47.0":{"tag":"2.47.0","author":"beziworld","date":"2026-07-10 11:17:08"},"2.47.1":{"tag":"2.47.1","author":"beziworld","date":"2026-07-10 11:20:12"},"2.48.0":{"tag":"2.48.0","author":"beziworld","date":"2026-07-10 11:28:09"},"2.49.0":{"tag":"2.49.0","author":"beziworld","date":"2026-07-10 11:33:50"},"2.50.0":{"tag":"2.50.0","author":"beziworld","date":"2026-07-10 11:37:11"},"2.51.0":{"tag":"2.51.0","author":"beziworld","date":"2026-07-10 11:45:34"},"2.52.0":{"tag":"2.52.0","author":"beziworld","date":"2026-07-10 11:52:00"},"2.53.0":{"tag":"2.53.0","author":"beziworld","date":"2026-07-10 11:58:17"},"2.54.0":{"tag":"2.54.0","author":"beziworld","date":"2026-07-10 12:04:39"},"2.55.0":{"tag":"2.55.0","author":"beziworld","date":"2026-07-10 12:15:57"},"2.56.0":{"tag":"2.56.0","author":"beziworld","date":"2026-07-10 12:20:33"},"2.57.0":{"tag":"2.57.0","author":"beziworld","date":"2026-07-10 12:24:58"},"2.58.0":{"tag":"2.58.0","author":"beziworld","date":"2026-07-10 12:29:25"},"2.59.0":{"tag":"2.59.0","author":"beziworld","date":"2026-07-10 12:38:27"},"2.60.0":{"tag":"2.60.0","author":"beziworld","date":"2026-07-10 12:44:56"},"2.61.0":{"tag":"2.61.0","author":"beziworld","date":"2026-07-10 12:48:15"},"2.62.0":{"tag":"2.62.0","author":"beziworld","date":"2026-07-10 12:54:59"},"2.63.0":{"tag":"2.63.0","author":"beziworld","date":"2026-07-10 13:00:28"},"2.64.0":{"tag":"2.64.0","author":"beziworld","date":"2026-07-10 13:05:36"},"2.65.0":{"tag":"2.65.0","author":"beziworld","date":"2026-07-10 13:10:48"},"2.66.0":{"tag":"2.66.0","author":"beziworld","date":"2026-07-10 13:19:58"},"2.67.0":{"tag":"2.67.0","author":"beziworld","date":"2026-07-10 13:24:07"},"2.68.0":{"tag":"2.68.0","author":"beziworld","date":"2026-07-10 13:41:46"},"2.69.0":{"tag":"2.69.0","author":"beziworld","date":"2026-07-10 13:46:30"},"2.70.0":{"tag":"2.70.0","author":"beziworld","date":"2026-07-10 13:51:32"},"2.71.0":{"tag":"2.71.0","author":"beziworld","date":"2026-07-10 13:54:55"},"2.72.0":{"tag":"2.72.0","author":"beziworld","date":"2026-07-10 14:08:51"},"2.73.0":{"tag":"2.73.0","author":"beziworld","date":"2026-07-10 14:12:52"},"2.74.0":{"tag":"2.74.0","author":"beziworld","date":"2026-07-10 14:41:42"},"2.75.0":{"tag":"2.75.0","author":"beziworld","date":"2026-07-10 14:46:37"},"2.76.0":{"tag":"2.76.0","author":"beziworld","date":"2026-07-10 14:53:44"},"2.77.0":{"tag":"2.77.0","author":"beziworld","date":"2026-07-10 15:00:24"},"2.78.0":{"tag":"2.78.0","author":"beziworld","date":"2026-07-10 15:06:51"},"2.79.0":{"tag":"2.79.0","author":"beziworld","date":"2026-07-10 15:12:13"},"2.80.0":{"tag":"2.80.0","author":"beziworld","date":"2026-07-10 15:18:34"},"2.81.0":{"tag":"2.81.0","author":"beziworld","date":"2026-07-10 15:26:18"},"2.82.0":{"tag":"2.82.0","author":"beziworld","date":"2026-07-10 15:30:56"},"2.83.0":{"tag":"2.83.0","author":"beziworld","date":"2026-07-10 15:36:23"},"2.84.0":{"tag":"2.84.0","author":"beziworld","date":"2026-07-10 15:41:46"},"2.85.0":{"tag":"2.85.0","author":"beziworld","date":"2026-07-10 18:57:51"},"2.86.0":{"tag":"2.86.0","author":"beziworld","date":"2026-07-10 19:03:43"}},"upgrade_notice":{"2.86.0":"<p>Order emails now confirm the Article 16(m) digital-content consent to the consumer (Article 8(7) durable medium). Safe upgrade.<\/p>","2.85.0":"<p>The customer UI now uses CSS logical properties for correct right-to-left (RTL) layout. LTR unchanged; safe upgrade.<\/p>","2.84.0":"<p>Adds a print\/save button and print styles to the success page. Safe upgrade.<\/p>","2.83.0":"<p>Adds a refund SLA report (on-time % against the 14-day deadline, aging buckets). Safe upgrade.<\/p>","2.82.0":"<p>Adds a select-all\/none toggle and selected-item count to the withdrawal form for large orders. Safe upgrade.<\/p>","2.81.0":"<p>The notification webhook now fires on received\/refunded\/rejected too, not only on submission. Opt-in; safe upgrade.<\/p>","2.80.0":"<p>Adds a REST API v2 with withdrawal status, cancel and schema endpoints. v1 unchanged; safe upgrade.<\/p>","2.79.0":"<p>Multi-shipment orders now start the withdrawal window from the last parcel delivered (Art. 9(2)(b)). Single-shipment unaffected; safe upgrade.<\/p>","2.78.0":"<p>Adds search and a date-range filter to the withdrawals admin list. Safe upgrade.<\/p>","2.77.0":"<p>Adds a &quot;Resend acknowledgement&quot; action on the withdrawal admin screen. Safe upgrade.<\/p>","2.76.0":"<p>Adds an Import \/ export tab for moving plugin settings between sites as JSON. Safe upgrade.<\/p>","2.75.0":"<p>Adds a <code>wp bzww doctor<\/code> read-only health-check command. Safe upgrade.<\/p>","2.74.0":"<p>Adds an extensible custom-field-type registry (developer filters). Built-in field types unchanged; safe upgrade.<\/p>","2.73.0":"<p>More precise Netherlands transposition citation in the Jurisdiction panel. Safe upgrade.<\/p>","2.72.0":"<p>Adds a one-time post-update &quot;what&#039;s new&quot; admin notice. Safe upgrade.<\/p>","2.71.0":"<p>Readme\/listing SEO and new FAQ entries. No functional change; safe upgrade.<\/p>","2.70.0":"<p>Adds a one-time, dismissible review invitation shown only after real usage. Safe upgrade.<\/p>","2.69.0":"<p>Adds rate limiting to the certificate document endpoint and an order-scoped guest-submission limit. Recommended update.<\/p>","2.68.0":"<p>Stronger CSV formula-injection protection and a masked webhook secret field. Recommended update.<\/p>","2.67.0":"<p>Gender-neutral, consistent Polish wording in the customer-facing texts and emails. Safe upgrade.<\/p>","2.66.0":"<p>Adds a one-click evidence-pack ZIP (declaration, acknowledgement, PDF certificate, audit chain) to each withdrawal. Safe upgrade.<\/p>","2.65.0":"<p>Security hardening headers on the certificate document and added IDOR test coverage. Recommended update.<\/p>","2.64.0":"<p>Withdrawal is no longer offered on subscription renewal orders (only the original order). A setting can re-enable it. Safe upgrade.<\/p>","2.63.0":"<p>Field manager gets move up\/down ordering controls and a Required-needs-Shown guard. Safe upgrade; no-JS fallback preserved.<\/p>","2.62.0":"<p>Compliance panel &quot;Fix this&quot; deep-links and confirmation prompts before bulk refunds\/rejections\/deletions. Safe upgrade.<\/p>","2.61.0":"<p>Dark-mode, high-contrast and forced-colours support, plus site-wide styling for the access button. Safe upgrade.<\/p>","2.60.0":"<p>Accessibility: the status timeline now conveys state with symbols and screen-reader text, not colour alone. Safe upgrade.<\/p>","2.59.0":"<p>Consumers can now withdraw before delivery (Article 9); the 14-day deadline starts on delivery. Recommended update. A setting restores the old behaviour if needed.<\/p>","2.58.0":"<p>Clearer, neutral explanations and a recovery link on the &quot;withdrawal not available&quot; screen. Safe upgrade.<\/p>","2.57.0":"<p>The block-checkout digital-content consent now shows only for carts with digital items. Safe upgrade; server-side enforcement unchanged.<\/p>","2.56.0":"<p>The withdrawal notice now also appears on the block cart. Safe upgrade; classic themes unaffected.<\/p>","2.55.0":"<p>Adds a configurable return address and instructions (Article 6(1)(i)) shown to consumers. Safe upgrade.<\/p>","2.54.0":"<p>Adds email preview, test-send and a placeholder-token guard to the email editors. Safe upgrade.<\/p>","2.53.0":"<p>Adds an append-only, tamper-evident audit chain per withdrawal, with an admin badge and a verify-chain CLI command. Safe upgrade.<\/p>","2.52.0":"<p>Adds a real downloadable PDF of the acknowledgement certificate and a friendlier presentation of the verification code. Safe upgrade.<\/p>","2.51.0":"<p>The confirmation email now attaches a self-contained HTML acknowledgement as a durable-medium record. New attachment only; safe upgrade.<\/p>","2.50.0":"<p>Eligibility no longer refuses a withdrawal when the configured start date is missing; it falls back through the other order dates. Only ever lengthens the window; safe upgrade.<\/p>","2.49.0":"<p>Adds an optional Article 10 twelve-month window extension for consumers who were not informed of the right of withdrawal. Off by default; existing deadlines are unchanged unless enabled.<\/p>","2.48.0":"<p>More consistent Polish wording (&quot;wtyczka&quot;) and internal translation-quality tooling. No behaviour change; safe upgrade.<\/p>","2.47.0":"<p>Consistent consumer-facing withdrawal-status wording across the account list and timeline, plus a Polish consent-record wording fix. No behaviour change; safe upgrade.<\/p>","2.46.0":"<p>Corrects two Polish interface mistranslations (field &quot;Order\/Kolejno\u015b\u0107&quot;; the Refunds vs Returns tabs). Cosmetic, no behaviour change; safe upgrade.<\/p>","2.45.0":"<p>Internal translation-toolchain improvement and a new mistranslation guard. No changes to your settings or the customer-facing flow; safe upgrade.<\/p>","2.20.0":"<p>The withdrawal\/confirmation buttons now default to the exact statutory wording for your site language (DE\/FR\/IT\/PL\/ES\/NL\/EN). Custom labels you set are unchanged.<\/p>","2.19.0":"<p>Adds a withdrawal form field manager (toggle, reorder, require and add custom fields) and a redesigned responsive, tabbed settings screen. Your existing form behaviour, including the IBAN field, is preserved.<\/p>","2.18.0":"<p>Clarifies that the plugin is a technical tool and not legal advice, adds suggested privacy-policy text, and declares the WooCommerce supported-version range. No configuration needed.<\/p>","2.17.0":"<p>Adds a merchant notification email on new withdrawals (on by default, sent to the admin address), a visual editor for every email body, and editable withdrawal-form wording. Safe upgrade; existing emails and forms keep their current text.<\/p>","2.16.0":"<p>Adds an optional expiry for guest withdrawal links (off by default). No action needed unless you want to enable it.<\/p>","2.15.5":"<p>Polishes the settings-screen layout. No configuration needed.<\/p>","2.15.4":"<p>Lets shop managers (not just administrators) save the plugin settings. No configuration needed.<\/p>","2.15.3":"<p>Improves personal-data erasure so in-progress withdrawals are retained until finalised. No configuration needed.<\/p>","2.15.2":"<p>Corrects the timezone handling of recorded delivery dates in the deadline calculation. No configuration needed.<\/p>","2.15.1":"<p>Security fix for the acknowledgement-certificate feature. Updating is recommended.<\/p>","2.15.0":"<p>Documentation-only release: inline developer hook reference. No code changes.<\/p>","2.14.0":"<p>Adds an overdue-refund count to the stats CLI command and REST endpoint. No configuration needed.<\/p>","2.13.0":"<p>Surfaces overdue-reimbursement warnings on the main dashboard widget. No configuration needed.<\/p>","2.12.0":"<p>Corrects Polish plural forms for counted strings. No configuration needed.<\/p>","2.11.0":"<p>Adds a reimbursement-deadline warning on the Withdrawals screen. No configuration needed.<\/p>","2.10.0":"<p>Adds per-status counts to the Withdrawals admin list filters. No configuration needed.<\/p>","2.9.0":"<p>Adds a read-only <code>\/wp-json\/bzww\/v1\/stats<\/code> REST endpoint for monitoring. No configuration needed.<\/p>","2.8.0":"<p>Adds a &quot;Top reasons&quot; breakdown to the dashboard widget. Reasons are recorded from this version onward.<\/p>","2.7.0":"<p>Adds a <code>wp bzww stats<\/code> WP-CLI command. No configuration needed.<\/p>","2.6.0":"<p>Adds a withdrawal-rate figure to the dashboard widget. No configuration needed.<\/p>","2.5.0":"<p>Adds average refund and average time-to-refund to the dashboard widget. No configuration needed.<\/p>","2.4.0":"<p>Adds a &quot;Record delivery date&quot; order action that sets the start of the withdrawal window. Optional; no change to existing behaviour.<\/p>","2.3.0":"<p>Adds a configurable deadline basis (completed \/ order \/ payment date) and optional grace days. Default behaviour (order completed date) is unchanged.<\/p>","2.2.0":"<p>Adds optional Slack\/Discord\/generic webhook notifications on withdrawal submission. Off by default.<\/p>","2.1.0":"<p>Adds optional Article 16(m) digital-content consent capture at the classic checkout. Off by default; no change unless enabled.<\/p>","2.0.0":"<p>Milestone release consolidating the 1.x compliance toolkit and adding an onboarding Help tab. No breaking changes \u2014 safe to upgrade; your settings and records are preserved.<\/p>","1.5.0":"<p>Adds a compliance readiness checklist to the settings screen and refines frontend styling for default themes.<\/p>","1.4.0":"<p>Adds a printable\/PDF-ready acknowledgement certificate linked from the confirmation email and the consumer&#039;s confirmation screen.<\/p>","1.3.0":"<p>Adds a one-click Annex I.A\/I.B legal-text generator and an optional two-step confirmation screen, plus default-theme styling refinements.<\/p>","1.2.0":"<p>Adds always-visible withdrawal access (footer link + optional sticky bar), an optional validated IBAN refund field, and WCAG 2.1 AA accessibility improvements.<\/p>","1.1.0":"<p>Adds a tamper-evident SHA-256 receipt code to the withdrawal acknowledgement, clearer receipt-only wording, and spam\/rate-limit hardening on the public forms. Recommended for all sites.<\/p>","1.0.2":"<p>Follow-up maintenance release addressing the PHPCS escape-output finding on the settings page reported during WordPress.org review.<\/p>","1.0.1":"<p>Maintenance release addressing WordPress.org plugin-directory review feedback (escaping discipline, no inline scripts).<\/p>","1.0.0":"<p>Initial release.<\/p>"},"ratings":{"1":0,"2":0,"3":0,"4":0,"5":1},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3556797,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3556797,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3556797,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3556797,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3556797,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":{"bzww\/withdrawal-form":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"bzww\/withdrawal-form","title":"Withdrawal Form","category":"woocommerce","icon":"undo","description":"Renders the EU 2023\/2673 withdrawal-from-contract form. Same content as the [bzww_withdrawal_form] shortcode.","keywords":["withdrawal","refund","return","woocommerce","eu"],"textdomain":"beziworld-withdrawal-for-woocommerce","supports":{"html":false,"align":["wide","full"]},"attributes":{},"editorScript":"file:.\/index.js"}},"tagged_versions":["1.0.2","1.1.0","1.2.0","2.15.4","2.15.5","2.16.0","2.17.0","2.18.0","2.19.0","2.20.0","2.21.0","2.22.0","2.23.0","2.24.0","2.25.0","2.26.0","2.27.0","2.28.0","2.29.0","2.30.0","2.31.0","2.32.0","2.33.0","2.34.0","2.35.0","2.36.0","2.37.0","2.38.0","2.39.0","2.40.0","2.41.0","2.42.0","2.43.0","2.44.0","2.45.0","2.46.0","2.47.0","2.47.1","2.48.0","2.49.0","2.50.0","2.51.0","2.52.0","2.53.0","2.54.0","2.55.0","2.56.0","2.57.0","2.58.0","2.59.0","2.60.0","2.61.0","2.62.0","2.63.0","2.64.0","2.65.0","2.66.0","2.67.0","2.68.0","2.69.0","2.70.0","2.71.0","2.72.0","2.73.0","2.74.0","2.75.0","2.76.0","2.77.0","2.78.0","2.79.0","2.80.0","2.81.0","2.82.0","2.83.0","2.84.0","2.85.0","2.86.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3556797,"resolution":"1","location":"assets","locale":"","width":3840,"height":1138},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3556797,"resolution":"2","location":"assets","locale":"","width":1590,"height":1389},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3556797,"resolution":"3","location":"assets","locale":"","width":3601,"height":1786},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3556797,"resolution":"4","location":"assets","locale":"","width":3571,"height":2679}},"screenshots":{"1":"Customer view of the Withdrawal tab inside My Account \u2014 eligible orders with the 14-day deadline.","2":"Item-level partial withdrawal form \u2014 pick which items and how many units to return.","3":"Admin list of withdrawal statements with bulk actions and CSV export.","4":"Settings page \u2014 customer-facing labels, refund policy and eligibility rules."}},"plugin_section":[262246],"plugin_tags":[255182,266618,263226,245590,286],"plugin_category":[45],"plugin_contributors":[265339],"plugin_business_model":[],"class_list":["post-319606","plugin","type-plugin","status-publish","hentry","plugin_section-dashboard-widgets","plugin_tags-consumer-rights","plugin_tags-eu-compliance","plugin_tags-right-of-withdrawal","plugin_tags-withdrawal","plugin_tags-woocommerce","plugin_category-ecommerce","plugin_contributors-beziworld","plugin_committers-beziworld"],"banners":{"banner":"https:\/\/ps.w.org\/beziworld-withdrawal-for-woocommerce\/assets\/banner-772x250.png?rev=3556797","banner_2x":"https:\/\/ps.w.org\/beziworld-withdrawal-for-woocommerce\/assets\/banner-1544x500.png?rev=3556797","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/beziworld-withdrawal-for-woocommerce\/assets\/icon.svg?rev=3556797","icon":"https:\/\/ps.w.org\/beziworld-withdrawal-for-woocommerce\/assets\/icon.svg?rev=3556797","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/beziworld-withdrawal-for-woocommerce\/assets\/screenshot-1.png?rev=3556797","caption":"Customer view of the Withdrawal tab inside My Account \u2014 eligible orders with the 14-day deadline."},{"src":"https:\/\/ps.w.org\/beziworld-withdrawal-for-woocommerce\/assets\/screenshot-2.png?rev=3556797","caption":"Item-level partial withdrawal form \u2014 pick which items and how many units to return."},{"src":"https:\/\/ps.w.org\/beziworld-withdrawal-for-woocommerce\/assets\/screenshot-3.png?rev=3556797","caption":"Admin list of withdrawal statements with bulk actions and CSV export."},{"src":"https:\/\/ps.w.org\/beziworld-withdrawal-for-woocommerce\/assets\/screenshot-4.png?rev=3556797","caption":"Settings page \u2014 customer-facing labels, refund policy and eligibility rules."}],"raw_content":"<!--section=description-->\n<p>Add a compliant <strong>withdrawal button<\/strong> (\"right of withdrawal\" \/ \"Widerrufsbutton\" \/ \"odst\u0105pienie od umowy\") to your WooCommerce store. <strong>BeziWorld Withdrawal for WooCommerce<\/strong> is a free, GPL-licensed plugin that gives EU shops the dedicated, one-click withdrawal-from-contract function required by the EU Modernisation Directive (Directive (EU) 2023\/2673, amending the Consumer Rights Directive via Article 11a), <strong>in force since 19 June 2026<\/strong>.<\/p>\n\n<p>The directive requires online shops selling to EU consumers to provide a dedicated, one-click withdrawal function inside the shop interface \u2014 separate from any generic returns\/RMA page. This plugin delivers that function and the surrounding workflow: item-level partial withdrawals, a durable-medium acknowledgement, automatic refunds, and a tamper-evident audit trail.<\/p>\n\n<p><strong>This plugin is a technical tool; it does not provide legal advice and does not by itself guarantee legal compliance. Responsibility for meeting the applicable consumer-law obligations remains with the shop operator.<\/strong> How the directive applies depends on your country's transposition (for example, the dedicated withdrawal-function obligation is in force in Germany, France, Italy and the Netherlands, but had not been transposed in Poland at the time of writing). Consult a qualified lawyer for your jurisdiction.<\/p>\n\n<p><em>This plugin is an independent project. It is not affiliated with, endorsed by or sponsored by WooCommerce or Automattic Inc. \"WooCommerce\" is a trademark of its respective owner and is used here only to describe compatibility.<\/em><\/p>\n\n<h4>What this plugin gives you<\/h4>\n\n<ul>\n<li>A dedicated <strong>Withdrawal<\/strong> tab inside WooCommerce's My Account area<\/li>\n<li><strong>Item-level partial withdrawals<\/strong> with per-line quantity selection<\/li>\n<li><strong>Public withdrawal page<\/strong> auto-created on activation \u2014 guests enter order number + email to authenticate, no account required<\/li>\n<li>Single-use guest token automatically embedded in the order confirmation email<\/li>\n<li>Immediate confirmation email on a durable medium, as required by Article 11(3) CRD<\/li>\n<li>Configurable withdrawal period (14-60 days, default 14) \u2014 increase if you offer an extended return policy<\/li>\n<li>Deadline calculator that rolls weekends and public holidays forward to the next working day<\/li>\n<li>Polish public holidays preset for 2026-2028 (extensible to any locale through a filter)<\/li>\n<li>Refund calculation that respects Article 13(2) CRD: items plus the cheapest standard shipping option you offered<\/li>\n<li><strong>Automatic refunds<\/strong> through the original payment gateway when supported (Stripe, PayU, Przelewy24, Tpay, Mollie, etc.)<\/li>\n<li>Admin can override the calculated refund amount (restocking fee, partial damage)<\/li>\n<li>Configurable rule engine: exclude products, categories, user roles or payment gateways from withdrawal<\/li>\n<li>Storefront notices on <strong>product \/ cart \/ checkout \/ thank-you<\/strong> pages with WYSIWYG-editable text<\/li>\n<li>Predefined reason picker, configurable from settings<\/li>\n<li>Customer self-service cancellation while still pending<\/li>\n<li><strong>Five status emails<\/strong>: four to the customer (confirmation, received, refunded, rejected) plus a merchant notification when a new withdrawal is submitted \u2014 each with a <strong>visual (WYSIWYG) body editor<\/strong> and all overridable from your theme<\/li>\n<li><strong>Editable withdrawal-form wording<\/strong>: reword the form heading, labels and hints from the settings screen, with legally compliant defaults pre-filled<\/li>\n<li><strong>Withdrawal form field manager<\/strong>: choose which optional fields appear (reason, details, phone, IBAN), reorder them, and add your own custom fields \u2014 while the statutory item\/name\/email fields always stay required<\/li>\n<li>Optional automatic transition of the order status when a withdrawal is submitted<\/li>\n<li><strong>Full audit trail<\/strong>: IP, user-agent, server-side timestamps in UTC<\/li>\n<li>Trash \/ restore \/ delete for withdrawal records<\/li>\n<li>CSV export of all withdrawal statements<\/li>\n<li>WordPress privacy tools integration \u2014 exporter and eraser registered by default<\/li>\n<li>WP-CLI commands: <code>wp bzww list<\/code>, <code>wp bzww refund<\/code>, <code>wp bzww cancel<\/code>, <code>wp bzww received<\/code>, <code>wp bzww stats<\/code><\/li>\n<li>REST API endpoints under <code>\/wp-json\/bzww\/v1\/<\/code> for headless and mobile clients<\/li>\n<li>Gutenberg block and Elementor widget alternatives to the shortcode<\/li>\n<li>WooCommerce HPOS (custom order tables) compatible<\/li>\n<li>30+ filters and actions for deep customization (see HOOKS.md in the source repository)<\/li>\n<li><strong>Verifiable acknowledgement<\/strong>: each confirmation carries a SHA-256 receipt code recomputable from the stored declaration, so the durable-medium record is tamper-evident<\/li>\n<li><strong>Printable acknowledgement certificate<\/strong> the consumer can save as a PDF with the browser print function<\/li>\n<li><strong>Always-visible access<\/strong>: a site-wide footer link plus an optional dismissible sticky bar, so the withdrawal function is reachable from every page<\/li>\n<li><strong>Annex I generator<\/strong>: one-click withdrawal-information (Annex I.A) and model-withdrawal-form (Annex I.B) pages, generated from your store details, plus <code>[bzww_withdrawal_policy]<\/code> and <code>[bzww_model_form]<\/code> shortcodes<\/li>\n<li><strong>Optional two-step confirmation<\/strong> with a read-only review screen (off by default)<\/li>\n<li><strong>Optional IBAN field<\/strong> for consumers who request a refund to a specific account (never mandatory; validated with the IBAN checksum)<\/li>\n<li><strong>Compliance readiness panel<\/strong> in settings \u2014 an at-a-glance checklist of what is configured for the directive<\/li>\n<li><strong>Honeypot spam protection and per-IP rate limiting<\/strong> on the public lookup and guest submission<\/li>\n<li><strong>WCAG 2.1 AA<\/strong> accessibility on the customer-facing forms<\/li>\n<\/ul>\n\n<h4>Built-in features (no premium upgrade required)<\/h4>\n\n<ul>\n<li>Item-level partial withdrawals with quantity<\/li>\n<li>Guest withdrawal flow with email-based lookup<\/li>\n<li>Automatic refunds via payment gateways<\/li>\n<li>Weekend &amp; public-holiday aware deadline<\/li>\n<li>Audit trail with IP &amp; user-agent<\/li>\n<li>REST API<\/li>\n<li>WP-CLI<\/li>\n<li>CSV export<\/li>\n<li>GDPR exporter\/eraser<\/li>\n<li>Gutenberg block + Elementor widget<\/li>\n<\/ul>\n\n<h4>Theme overrides<\/h4>\n\n<p>Every customer-facing template can be overridden by your theme. Drop a copy of any file from <code>templates\/<\/code> into <code>your-theme\/beziworld-withdrawal-for-woocommerce\/&lt;same-path&gt;.php<\/code> and the plugin will use your version.<\/p>\n\n<h4>External services<\/h4>\n\n<p>This plugin performs <strong>no<\/strong> analytics, telemetry or remote downloads, and phones nothing home. Everything runs inside your WordPress installation.<\/p>\n\n<p>The single exception is entirely optional and off by default: if you enter a notification <strong>Webhook URL<\/strong> in the settings (for Slack, Discord or your own endpoint), the plugin sends a small JSON payload to that URL when a withdrawal is submitted and when it changes status (received, refunded, rejected). The payload contains the event name and the withdrawal and order identifiers (and the order number). No webhook is configured by default and nothing is sent unless you set a URL; the destination is the address you choose.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Activate WooCommerce 8.0 or newer if it is not already active.<\/li>\n<li>Upload the plugin via Plugins \u2192 Add New \u2192 Upload Plugin, or unzip into <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate the plugin through the Plugins screen.<\/li>\n<li>A <strong>Withdraw from contract<\/strong> page is created automatically \u2014 link it from your terms of sale.<\/li>\n<li>Go to <strong>WooCommerce \u2192 Withdrawal Settings<\/strong> to review the defaults (button labels, refund policy, eligibility rules, storefront notices).<\/li>\n<li>The plugin is now live. Logged-in customers see the <strong>Withdrawal<\/strong> tab inside My Account; guests can use the public page with the <code>[bzww_withdrawal_form]<\/code> shortcode.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"is%20this%20plugin%20enough%20to%20make%20my%20shop%20compliant%20with%20eu%202023%2F2673%3F\"><h3>Is this plugin enough to make my shop compliant with EU 2023\/2673?<\/h3><\/dt>\n<dd><p>The plugin covers the technical building blocks: a dedicated withdrawal function, a clearly labelled button, immediate confirmation on a durable medium, item-level selection, and a refund mechanism within 14 days. You still need to update your terms of sale, your privacy policy and the order summary copy. Whether \u2014 and exactly how \u2014 the dedicated withdrawal-function obligation applies depends on your country's transposition of Directive (EU) 2023\/2673: it is in force in Germany, France, Italy and the Netherlands, while in Poland it had not been transposed at the time of writing (so the function is voluntary there for now). <strong>The plugin does not provide legal advice and does not by itself guarantee compliance.<\/strong> Consult a lawyer for the specifics of your jurisdiction.<\/p><\/dd>\n<dt id=\"is%20a%20withdrawal%20button%20mandatory%3F%20%28ist%20der%20widerrufsbutton%20pflicht%3F%29\"><h3>Is a withdrawal button mandatory? (Ist der Widerrufsbutton Pflicht?)<\/h3><\/dt>\n<dd><p>It depends on your country's transposition of Directive (EU) 2023\/2673 (Article 11a). A dedicated withdrawal function is mandatory in Germany (\u00a7356a BGB, with an Abmahnung risk if missing), France, Italy and the Netherlands; in Poland the obligation had not been transposed at the time of writing, so it is voluntary there for now but still strengthens your consumer-law position. The plugin shows a jurisdiction-aware status and never makes a single global \"mandatory\" claim.<\/p><\/dd>\n<dt id=\"does%20the%2014-day%20withdrawal%20apply%20to%20a%20shop%20in%20poland%3F%20%28odst%C4%85pienie%2014%20dni%29\"><h3>Does the 14-day withdrawal apply to a shop in Poland? (odst\u0105pienie 14 dni)<\/h3><\/dt>\n<dd><p>Yes \u2014 the 14-day right of withdrawal for distance contracts applies to Polish consumers under existing consumer law, independently of whether the newer dedicated-button obligation has been transposed. The plugin calculates the 14-day deadline (rolling weekends and Polish public holidays forward) and lets the consumer withdraw from the conclusion of the contract; the deadline starts on delivery.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20the%20block%20%28store%20api%29%20checkout%20and%20block%20themes%3F\"><h3>Does it work with the block (Store API) checkout and block themes?<\/h3><\/dt>\n<dd><p>Yes. The statutory notices render on the block cart and block checkout, and the Article 16(m) digital-content consent is captured on the block checkout \u2014 not only the classic shortcode checkout. The customer-facing UI adapts to block themes, dark mode and high-contrast settings.<\/p><\/dd>\n<dt id=\"how%20do%20guests%20%28logged-out%20customers%29%20submit%20a%20withdrawal%3F\"><h3>How do guests (logged-out customers) submit a withdrawal?<\/h3><\/dt>\n<dd><p>The plugin auto-creates a public page on activation with the <code>[bzww_withdrawal_form]<\/code> shortcode. Guests visit that page, enter their order number and the email used at checkout. After verification, the plugin issues a single-use token and shows the same withdrawal form a logged-in customer would see. The link is also embedded in the order confirmation email for one-click access.<\/p><\/dd>\n<dt id=\"does%20it%20support%20multi-shipment%20orders%3F\"><h3>Does it support multi-shipment orders?<\/h3><\/dt>\n<dd><p>Yes. The 14-day clock starts after the last parcel is delivered. Because WooCommerce core does not track shipment-level delivery, the plugin uses the order completion timestamp by default and exposes a <code>bzww\/order\/delivered_at<\/code> filter so a shipping\/tracking plugin can override it.<\/p><\/dd>\n<dt id=\"how%20are%20digital%20products%20handled%3F\"><h3>How are digital products handled?<\/h3><\/dt>\n<dd><p>Per Article 16(m) CRD, sealed digital products and downloadable software are excluded by default. Products flagged as Virtual + Downloadable in WooCommerce are skipped automatically.<\/p><\/dd>\n<dt id=\"can%20a%20customer%20cancel%20a%20pending%20withdrawal%3F\"><h3>Can a customer cancel a pending withdrawal?<\/h3><\/dt>\n<dd><p>Yes. While a statement is in the <strong>pending<\/strong> state the customer sees a \"Cancel this withdrawal\" button on the success page in My Account.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20hpos%20%2F%20custom%20order%20tables%3F\"><h3>Does it work with HPOS \/ custom order tables?<\/h3><\/dt>\n<dd><p>Yes. The plugin declares full HPOS compatibility on activation.<\/p><\/dd>\n<dt id=\"where%20are%20records%20stored%3F\"><h3>Where are records stored?<\/h3><\/dt>\n<dd><p>In a private custom post type, <code>bzww_withdrawal<\/code>. Each statement is one post with meta fields holding order id, items, amount, IP and user-agent.<\/p><\/dd>\n<dt id=\"how%20do%20i%20add%20public%20holidays%20for%20a%20country%20other%20than%20poland%3F\"><h3>How do I add public holidays for a country other than Poland?<\/h3><\/dt>\n<dd><p>Use the <code>bzww\/eligibility\/holidays<\/code> filter to return an array of <code>Y-m-d<\/code> strings. The plugin will roll the 14-day deadline forward when it lands on one of those dates.<\/p><\/dd>\n<dt id=\"can%20i%20customise%20the%20withdrawal%20period%3F\"><h3>Can I customise the withdrawal period?<\/h3><\/dt>\n<dd><p>Yes. WooCommerce \u2192 Withdrawal Settings \u2192 <strong>Withdrawal period (days)<\/strong> \u2014 set anywhere between 14 and 60 days. The default is the 14 days mandated by EU law; the minimum cannot go below the statutory 14.<\/p><\/dd>\n<dt id=\"can%20the%20admin%20adjust%20the%20refund%20amount%20before%20issuing%3F\"><h3>Can the admin adjust the refund amount before issuing?<\/h3><\/dt>\n<dd><p>Yes. Each withdrawal detail page has an editable <strong>Refund amount<\/strong> input pre-filled with the calculated value. Override it to deduct a restocking fee or to account for the condition of returned goods.<\/p><\/dd>\n<dt id=\"where%20can%20i%20learn%20about%20the%20available%20hooks%3F\"><h3>Where can I learn about the available hooks?<\/h3><\/dt>\n<dd><p>The plugin is built to be extended. The main filters and actions are listed below; all pass the relevant order or withdrawal so you can tailor behaviour without touching plugin files.<\/p>\n\n<p><strong>Eligibility &amp; deadlines (filters)<\/strong><\/p>\n\n<ul>\n<li><code>bzww\/eligibility\/excluded_statuses<\/code> \u2014 order statuses excluded from withdrawal.<\/li>\n<li><code>bzww\/eligibility\/deadline<\/code> \u2014 the computed withdrawal deadline (DateTime).<\/li>\n<li><code>bzww\/eligibility\/holidays<\/code> \u2014 extra non-working days for weekend\/holiday roll-over.<\/li>\n<li><code>bzww\/order\/delivered_at<\/code> \u2014 override the delivery date the deadline is based on.<\/li>\n<li><code>bzww\/rules\/order<\/code>, <code>bzww\/rules\/item<\/code> \u2014 allow or deny a specific order or line item.<\/li>\n<li><code>bzww\/withdrawal\/deny_duplicate<\/code> \u2014 whether to block a second statement for the same order.<\/li>\n<\/ul>\n\n<p><strong>Refunds (filters)<\/strong><\/p>\n\n<ul>\n<li><code>bzww\/refund\/deadline_days<\/code> \u2014 statutory reimbursement deadline in days (default 14).<\/li>\n<li><code>bzww\/refund\/args<\/code> \u2014 arguments passed to the WooCommerce refund.<\/li>\n<li><code>bzww\/refund\/cheapest_shipping<\/code> \u2014 override the cheapest-delivery amount (Art. 13(2)).<\/li>\n<\/ul>\n\n<p><strong>Lifecycle (actions)<\/strong><\/p>\n\n<ul>\n<li><code>bzww\/withdrawal\/submitted<\/code> ( $withdrawal_id, $request, $order )<\/li>\n<li><code>bzww\/withdrawal\/cancelled<\/code> ( $withdrawal_id )<\/li>\n<li><code>bzww\/withdrawal\/status_changed<\/code> ( $withdrawal_id, $previous, $current )<\/li>\n<li><code>bzww\/withdrawal\/transition_to_{status}<\/code> ( $withdrawal_id, $previous )<\/li>\n<li><code>bzww\/refund\/before<\/code>, <code>bzww\/refund\/after<\/code>, <code>bzww\/refund\/failed<\/code><\/li>\n<li><code>bzww\/plugin\/booted<\/code> ( $plugin )<\/li>\n<\/ul>\n\n<p><strong>Security, presentation &amp; integration (filters)<\/strong><\/p>\n\n<ul>\n<li><code>bzww\/submit\/rate_limit<\/code>, <code>bzww\/submit\/rate_window<\/code>, <code>bzww\/lookup\/rate_limit<\/code>, <code>bzww\/lookup\/rate_window<\/code> \u2014 throttling.<\/li>\n<li><code>bzww\/request\/client_ip<\/code> \u2014 resolved client IP behind proxies.<\/li>\n<li><code>bzww\/lookup\/resolve_order<\/code> \u2014 custom guest order lookup.<\/li>\n<li><code>bzww\/csv\/columns<\/code>, <code>bzww\/csv\/row<\/code> \u2014 admin CSV export shape.<\/li>\n<li><code>bzww\/webhook\/payload<\/code> \u2014 outbound webhook body.<\/li>\n<li><code>bzww\/templates\/theme_directory<\/code>, <code>bzww\/templates\/located<\/code> \u2014 template overrides.<\/li>\n<li><code>bzww\/placement\/html<\/code>, <code>bzww\/placement\/tokens<\/code>, <code>bzww\/access\/label<\/code>, <code>bzww\/access\/url<\/code> \u2014 front-end placement.<\/li>\n<li><code>bzww\/checkout\/digital_consent_text<\/code>, <code>bzww\/assets\/should_enqueue<\/code>, <code>bzww\/model_form\/policy_html<\/code>, <code>bzww\/model_form\/model_form_html<\/code>.<\/li>\n<\/ul>\n\n<p>A REST endpoint <code>GET \/wp-json\/bzww\/v1\/stats<\/code> (capability <code>manage_woocommerce<\/code>) and the <code>wp bzww<\/code> CLI commands are also available for monitoring and automation.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>2.86.0<\/h4>\n\n<ul>\n<li>New (compliance, Article 8(7)): when a consumer gives the Article 16(m) digital-content consent at checkout, the confirmation of that consent (the wording and the time it was recorded) is now included in the WooCommerce order emails \u2014 a durable-medium confirmation of the prior express consent, delivered to the consumer, not only kept in the order notes.<\/li>\n<\/ul>\n\n<h4>2.85.0<\/h4>\n\n<ul>\n<li>Improved (internationalisation): the customer-facing styles now use CSS logical properties, so the withdrawal UI lays out correctly in right-to-left (RTL) languages. Left-to-right layouts are visually unchanged.<\/li>\n<\/ul>\n\n<h4>2.84.0<\/h4>\n\n<ul>\n<li>Improved (consumer): the post-submission success page now has a \"Print \/ Save this page\" button and a print stylesheet, so the consumer can keep a clean paper or PDF copy of their submitted statement (in addition to the emailed acknowledgement).<\/li>\n<\/ul>\n\n<h4>2.83.0<\/h4>\n\n<ul>\n<li>New (admin): a <strong>Withdrawal SLA<\/strong> report (WooCommerce menu) shows what percentage of refunds were issued within the statutory 14-day deadline (Article 13(3)), with aging buckets (0\u20133 \/ 4\u20137 \/ 8\u201314 \/ over the deadline) \u2014 useful for monitoring and evidencing timely reimbursement.<\/li>\n<\/ul>\n\n<h4>2.82.0<\/h4>\n\n<ul>\n<li>Improved (usability): on orders with several items, the withdrawal form now shows a \"Select all \/ none\" toggle and a live count of selected items, so choosing what to withdraw from a large order is quicker. It is a convenience layer only \u2014 the server still determines what is withdrawn and the refund amount \u2014 and the form works exactly as before without JavaScript.<\/li>\n<\/ul>\n\n<h4>2.81.0<\/h4>\n\n<ul>\n<li>Improved (integrations): the notification webhook now fires across the whole withdrawal lifecycle \u2014 not only on submission but also when a statement is received, refunded or rejected \u2014 each with a distinct <code>event<\/code> value (<code>withdrawal.received<\/code> \/ <code>withdrawal.refunded<\/code> \/ <code>withdrawal.rejected<\/code>). The last dispatch attempt is recorded for basic visibility. Still opt-in and off by default.<\/li>\n<\/ul>\n\n<h4>2.80.0<\/h4>\n\n<ul>\n<li>New (developers\/headless): a versioned REST API v2 under <code>\/wp-json\/bzww\/v2\/<\/code> adds <code>GET \/withdrawals\/{id}<\/code> (status lookup), <code>POST \/withdrawals\/{id}\/cancel<\/code> (cancel a pending withdrawal) and <code>GET \/schema<\/code> (resource introspection). Access uses the same owner-or-guest-token rule as the rest of the flow. The existing v1 endpoints are unchanged.<\/li>\n<\/ul>\n\n<h4>2.79.0<\/h4>\n\n<ul>\n<li>Improved (compliance, Article 9(2)(b)): for orders delivered in several parcels, the 14-day withdrawal window now runs from the <strong>last<\/strong> parcel delivered. A tracking\/fulfilment integration can supply the per-parcel delivery dates through the new <code>bzww\/order\/delivery_dates<\/code> filter; single-shipment orders are unaffected.<\/li>\n<\/ul>\n\n<h4>2.78.0<\/h4>\n\n<ul>\n<li>New (admin): the withdrawals list now has a search box (by order number, consumer name or email) and a submitted-date range filter, making it much easier to find a specific statement in a busy store. The filters combine with the existing status tabs.<\/li>\n<\/ul>\n\n<h4>2.77.0<\/h4>\n\n<ul>\n<li>New: a \"Resend acknowledgement\" button on each withdrawal's admin screen re-sends the durable-medium acknowledgement to the consumer (for example, if the original email was lost or went to spam). Each resend is recorded on the record for the audit trail.<\/li>\n<\/ul>\n\n<h4>2.76.0<\/h4>\n\n<ul>\n<li>New (admin): an <strong>Import \/ export<\/strong> tab lets you download all plugin settings as a JSON file and import them on another site \u2014 handy for moving a configuration from staging to production. Imported files are validated as a genuine export of this plugin and run through the normal settings sanitiser before saving.<\/li>\n<\/ul>\n\n<h4>2.75.0<\/h4>\n\n<ul>\n<li>New: a <code>wp bzww doctor<\/code> command runs a read-only health check of the plugin's configuration \u2014 WooCommerce active, the withdrawal page published, Action Scheduler available, the Polish translation present, the webhook signed, the withdrawal period at least the statutory 14 days \u2014 and reports pass\/warning\/failure per item, cutting support back-and-forth.<\/li>\n<\/ul>\n\n<h4>2.74.0<\/h4>\n\n<ul>\n<li>New (developers): the withdrawal form's custom-field types are now an extensible registry. A <code>bzww\/form\/field_types<\/code> filter lets a plugin or the Pro add-on register additional field types (they appear in the field-manager picker automatically), and a <code>bzww\/form\/render_custom_field<\/code> filter lets it render their markup \u2014 without forking the plugin. The built-in text\/paragraph\/checkbox\/dropdown types are unchanged.<\/li>\n<\/ul>\n\n<h4>2.73.0<\/h4>\n\n<ul>\n<li>Improved (compliance data): the Netherlands entry in the Jurisdiction panel now cites the specific transposition (Art. 6:230oa BW, the Dutch Implementation Act) instead of a generic reference, for a more precise, verifiable legal citation shown to merchants.<\/li>\n<\/ul>\n\n<h4>2.72.0<\/h4>\n\n<ul>\n<li>New: after an update, a single dismissible admin notice on the plugin's screens tells you the plugin was updated and links to what changed and to the settings. Shown once per version, gates nothing, and never nags.<\/li>\n<\/ul>\n\n<h4>2.71.0<\/h4>\n\n<ul>\n<li>Improved (discoverability): refreshed the plugin listing \u2014 searchable tags, a keyword-led description leading with \"withdrawal button\" \/ \"right of withdrawal\", present-tense framing now the directive is in force, and new FAQ entries answering the questions merchants actually search for (is the withdrawal button mandatory, does the 14-day right apply in Poland, does it work with the block checkout). No functional change.<\/li>\n<\/ul>\n\n<h4>2.70.0<\/h4>\n\n<ul>\n<li>New: a single, dismissible admin notice invites you to leave a WordPress.org review \u2014 shown only after you have processed a few refunds (real value), at most once, with no repeated nagging and nothing gated. The threshold is filterable and it never appears again once dismissed.<\/li>\n<\/ul>\n\n<h4>2.69.0<\/h4>\n\n<ul>\n<li>Security (hardening): the acknowledgement certificate\/PDF endpoint \u2014 an unauthenticated, code-authorised GET that serves personal data \u2014 is now rate-limited to blunt automated scanning. Guest submissions also gain a second, order-scoped rate limit so an attacker hammering one order's token from rotating IPs is stopped without risking a shared-IP lockout of legitimate consumers.<\/li>\n<\/ul>\n\n<h4>2.68.0<\/h4>\n\n<ul>\n<li>Security (hardening): the CSV export's formula-injection protection now also catches triggers hidden behind leading whitespace or a newline, and covers the DDE pipe character \u2014 closing known spreadsheet bypasses of a first-character-only check. The webhook signing secret is now shown as a masked password field instead of clear text.<\/li>\n<\/ul>\n\n<h4>2.67.0<\/h4>\n\n<ul>\n<li>Improved (Polish): consumer-facing wording is now gender-neutral (no masculine-only verb endings such as \"u\u017cy\u0142e\u015b\", \"zgubi\u0142e\u015b\", \"zapozna\u0142e\u015b\") and the customer email greetings were unified to one consistent, professional salutation instead of a mix of casual forms.<\/li>\n<\/ul>\n\n<h4>2.66.0<\/h4>\n\n<ul>\n<li>New: a one-click <strong>Evidence pack (ZIP)<\/strong> on each withdrawal's admin screen, bundling the canonical declaration (JSON), the durable-medium acknowledgement (HTML), the PDF certificate and the append-only audit chain with its integrity verdict \u2014 everything you would hand to a payment processor, ADR body or in a subject-access request, in a single download.<\/li>\n<\/ul>\n\n<h4>2.65.0<\/h4>\n\n<ul>\n<li>Security (hardening): the acknowledgement certificate response now sends stricter headers \u2014 X-Frame-Options, Referrer-Policy: no-referrer, X-Content-Type-Options and a minimal Content-Security-Policy \u2014 so the personal-data document cannot be framed and its code-bearing URL is not leaked via the referrer.<\/li>\n<li>Internal (quality): the withdrawal form-handler's authorization decision is now a small, pure, independently tested function, adding explicit coverage for the owner\/guest-token IDOR guard.<\/li>\n<\/ul>\n\n<h4>2.64.0<\/h4>\n\n<ul>\n<li>New (compliance): withdrawal is no longer offered on WooCommerce Subscriptions <strong>renewal<\/strong> orders. A renewal is a continuation of the original contract, so the right of withdrawal attaches to the initial subscription order, not to each renewal payment. Consumers who reach a renewal order see a clear explanation pointing them to cancel the subscription instead. A setting (off by default) can re-enable withdrawal on renewals if you need it.<\/li>\n<\/ul>\n\n<h4>2.63.0<\/h4>\n\n<ul>\n<li>Improved (admin UX): the withdrawal form field manager now uses keyboard-accessible move up \/ move down controls to set field order, instead of typing raw numbers into an \"Order\" column. It also prevents a field from being marked \"Required\" while it is not \"Shown\", matching the underlying rule. With JavaScript disabled the numeric order inputs remain as a fallback.<\/li>\n<\/ul>\n\n<h4>2.62.0<\/h4>\n\n<ul>\n<li>New (admin): each unmet item on the compliance-readiness panel now has a \"Fix this \u2192\" link that takes you straight to the relevant settings tab (or the WooCommerce email settings), so you can resolve it in one click.<\/li>\n<li>New (safety): bulk actions on the withdrawals list now ask for confirmation, showing how many records are selected, before issuing refunds, rejecting or permanently deleting \u2014 preventing accidental mass actions.<\/li>\n<\/ul>\n\n<h4>2.61.0<\/h4>\n\n<ul>\n<li>Improved (accessibility &amp; theming): the withdrawal UI now adapts to the visitor's colour-scheme and contrast preferences \u2014 a dark-mode palette (<code>prefers-color-scheme<\/code>), a higher-contrast variant (<code>prefers-contrast<\/code>) and Windows High Contrast \/ forced-colours support. The site-wide \"Withdraw from contract\" access button is now styled on every page (its stylesheet loads site-wide when the footer link or sticky bar is enabled), so it no longer degrades to a plain link off the withdrawal pages.<\/li>\n<\/ul>\n\n<h4>2.60.0<\/h4>\n\n<ul>\n<li>Improved (accessibility, WCAG 2.2): the consumer status timeline no longer relies on colour alone to show each step's state. Every step now carries a distinct symbol (\u2713 completed, \u25cf in progress, \u25cb upcoming, \u2717 not accepted) and a screen-reader label, so the progress is understandable to colour-blind and assistive-technology users.<\/li>\n<\/ul>\n\n<h4>2.59.0<\/h4>\n\n<ul>\n<li>Fixed (compliance, Article 9): consumers can now submit a withdrawal <strong>before the goods are delivered<\/strong>. The right of withdrawal exists from the conclusion of the contract, so an order that is paid but not yet delivered is no longer blocked with \"not delivered yet\" \u2014 it is accepted with an open window, and the 14-day deadline simply starts on delivery. A new \"Require delivery before withdrawal\" setting (off by default) lets shops keep the old behaviour if they specifically want it. Thanks to the merchant who reported this.<\/li>\n<\/ul>\n\n<h4>2.58.0<\/h4>\n\n<ul>\n<li>Improved: when a withdrawal is not available for an order, the consumer now sees a clearer, neutral explanation of why \u2014 with the relevant article reference and a note that the message is informational and does not remove any right \u2014 plus a \"Check another order\" link. The wording never suggests the statutory right itself is invalid.<\/li>\n<\/ul>\n\n<h4>2.57.0<\/h4>\n\n<ul>\n<li>Improved (Article 16(m)): on the block checkout, the digital-content consent checkbox now appears only when the cart actually contains a virtual, downloadable product, instead of showing on every checkout. When the cart contents cannot be determined the checkbox still appears (fail-open), and the consent record and enforcement remain governed server-side. A new <code>bzww\/checkout\/cart_has_digital<\/code> filter lets integrations override the determination.<\/li>\n<\/ul>\n\n<h4>2.56.0<\/h4>\n\n<ul>\n<li>New: the pre-contractual withdrawal notice now also renders on the <strong>block cart<\/strong> (not only the block checkout), so shops using block themes show the notice consistently across the cart and checkout. On classic themes nothing changes.<\/li>\n<\/ul>\n\n<h4>2.55.0<\/h4>\n\n<ul>\n<li>New (compliance, Article 6(1)(i)): a <strong>return address and return instructions<\/strong> you can configure (WooCommerce \u2192 Withdrawal Settings \u2192 Returns). They appear on the post-submission success page and are available in the editable emails through the <code>{return_address}<\/code> and <code>{return_instructions}<\/code> placeholders, so the consumer is told where to send goods being returned. The address falls back to your WooCommerce store address when left blank.<\/li>\n<\/ul>\n\n<h4>2.54.0<\/h4>\n\n<ul>\n<li>New: each editable email now has a \"Preview with sample data\" and a \"Send a test to me\" button, so you can see exactly how a message will look before customers receive it.<\/li>\n<li>New (safety): when you save an email whose body is missing a required placeholder (such as {amount} in the refund email) or contains a mistyped one, the settings screen now warns you, so legal or functional content is not silently dropped.<\/li>\n<\/ul>\n\n<h4>2.53.0<\/h4>\n\n<ul>\n<li>New (evidence): every withdrawal now keeps an append-only, tamper-evident audit chain. Each lifecycle event (submission and each status change) is linked by hash to the one before it, so altering or removing any past entry breaks the chain and is detected. The admin record shows an \"INTACT \/ BROKEN at entry N\" badge, and the new <code>wp bzww verify-chain &lt;id&gt;<\/code> command reports the chain status from the command line.<\/li>\n<\/ul>\n\n<h4>2.52.0<\/h4>\n\n<ul>\n<li>New: the acknowledgement certificate can now be downloaded as a real PDF file (not only printed from the browser), generated with no bundled library. A permanent, code-authorised download link is available on the certificate page.<\/li>\n<li>Improved (clarity): the raw SHA-256 code on the certificate is now tucked inside an expandable \"Unique fingerprint of your statement\" section with a plain-language explanation, instead of being shown as a bare technical string.<\/li>\n<\/ul>\n\n<h4>2.51.0<\/h4>\n\n<ul>\n<li>New (durable medium, Article 11a(4)): the confirmation email now includes a self-contained HTML acknowledgement file the consumer can save and reopen offline, independent of any live link. It contains the declaration details, the exact submission date, time and time zone, the SHA-256 verification code, and the clear \"receipt only, not a refund confirmation\" separation. All styling is inline with no remote fonts, scripts or images, so it renders anywhere and meets the plugin-directory content-security expectations. The attachment can be turned off with the <code>bzww\/email\/attach_acknowledgement<\/code> filter.<\/li>\n<\/ul>\n\n<h4>2.50.0<\/h4>\n\n<ul>\n<li>Improved (correctness): when the configured start date for the withdrawal clock is missing on an order (for example, an order that was delivered but never marked \"completed\"), the eligibility check now falls back through the other available dates (completed \u2192 paid \u2192 created) instead of refusing the withdrawal outright. The fallback favours the date closest to actual delivery and can only lengthen or leave the window unchanged, never shorten it. Shops that prefer the stricter behaviour can disable the chain with the new <code>bzww\/eligibility\/deadline_basis_fallback<\/code> filter.<\/li>\n<\/ul>\n\n<h4>2.49.0<\/h4>\n\n<ul>\n<li>New (compliance, Article 10): an optional \"Extend the window when uninformed\" setting. Where the consumer was not given the required pre-contractual information about the right of withdrawal, Article 10 of the Consumer Rights Directive extends the withdrawal period by 12 months. When enabled, the deadline calculation applies that extension \u2014 it only ever lengthens the window, never shortens it \u2014 closing a case where an otherwise-eligible consumer could have been wrongly refused. Per-order control is available through the new <code>bzww\/eligibility\/info_provided<\/code> filter.<\/li>\n<\/ul>\n\n<h4>2.48.0<\/h4>\n\n<ul>\n<li>Improved (Polish): unified the wording for \"plugin\" to the Polish \"wtyczka\" across every message that previously used the borrowed word inconsistently (activation, requirements, uninstall and settings text), for a more professional and consistent Polish interface.<\/li>\n<li>Internal (quality): added a Polish terminology glossary and an automated consistency validator, plus a per-locale translation-completeness gate (Polish must stay 100%; the French\/Italian starter bundles are reported as informational), so terminology drift is caught before release.<\/li>\n<\/ul>\n\n<h4>2.47.1<\/h4>\n\n<ul>\n<li>Fixed: a packaging error in 2.47.0 left a syntax error in the My Account withdrawal list template. This patch restores the page. Please update from 2.47.0.<\/li>\n<\/ul>\n\n<h4>2.47.0<\/h4>\n\n<ul>\n<li>Improved (consumer clarity): the withdrawal status a customer sees in the My Account list now uses the same wording as the progress timeline \u2014 \"In review\", \"Refund in progress\", \"Refund issued\", \"Not accepted\" \u2014 instead of a second, different set of labels. A single shared vocabulary means the list and the timeline never disagree, and the \"received\" state is no longer worded in a way that could be mistaken for mere receipt of the declaration.<\/li>\n<li>Fixed (Polish): the Article 16(m) digital-content consent recorded on block-checkout orders now reads \"przyj\u0105\u0142 do wiadomo\u015bci\" (acknowledged), matching the classic-checkout wording and the checkbox the customer actually ticks, instead of the divergent \"potwierdzi\u0142\".<\/li>\n<\/ul>\n\n<h4>2.46.0<\/h4>\n\n<ul>\n<li>Fixed (Polish interface): the form field-manager column that sets the display order of fields showed \"Zam\u00f3wienie\" (purchase order) instead of \"Kolejno\u015b\u0107\" (order\/sequence) \u2014 the two meanings shared one English word and collapsed onto one translation. The header now reads \"Kolejno\u015b\u0107\" while every purchase-order label keeps saying \"Zam\u00f3wienie\".<\/li>\n<li>Fixed (Polish interface): the two adjacent settings tabs \"Refunds\" and \"Returns\" both rendered as \"Zwroty\". They are now distinct \u2014 \"Zwroty \u015brodk\u00f3w\" (money refunds) and \"Zwroty towaru\" (goods returns) \u2014 so it is clear which tab does what.<\/li>\n<\/ul>\n\n<h4>2.45.0<\/h4>\n\n<ul>\n<li>Improved (translation quality, foundation): the Polish translation toolchain now resolves each string by its gettext context first (falling back to the bare text), so a single English word used in two different places \u2014 such as \"Order\" meaning a purchase order versus the display order of form fields \u2014 can finally be translated independently instead of collapsing onto one Polish word. This is the groundwork for the interface-wording corrections in the next releases.<\/li>\n<li>New (quality gate): an automated msgid-collision detector runs in the test suite and continuous integration, flagging any English string reused in disjoint interface roles without a context, so this class of mistranslation cannot silently reappear.<\/li>\n<\/ul>\n\n<h4>2.44.0<\/h4>\n\n<ul>\n<li>New: an <strong>accessibility-statement generator<\/strong> for the European Accessibility Act (EAA, in force 28 June 2025). One click creates a ready-made statement page from your shop details (conformance status, feedback contact, enforcement reference), or use the <code>[bzww_accessibility_statement]<\/code> shortcode. The compliance-readiness panel now includes an accessibility-statement row.<\/li>\n<\/ul>\n\n<h4>2.43.0<\/h4>\n\n<ul>\n<li>New (opt-in, transparency): on a product classified under an Article 16 withdrawal exemption (set in the product or category settings), the shop can show a short, neutral note explaining that the item may be excluded from the right of withdrawal \u2014 and why \u2014 reusing the existing exemption taxonomy. Off by default; enable it under Storefront notices.<\/li>\n<\/ul>\n\n<h4>2.42.0<\/h4>\n\n<ul>\n<li>New (opt-in): a <strong>return-handling layer<\/strong> with a stable extension point. The free plugin still records returns manually and contacts no carrier; enabling it (WooCommerce \u2192 Withdrawal Settings \u2192 Returns) exposes a documented <code>bzww\/returns\/registered<\/code> action and <code>bzww\/returns\/carrier_options<\/code> filter that a separate Pro add-on can hook for carrier integrations and return labels.<\/li>\n<li>New: a warning when a generic returns\/RMA plugin is active, reminding you that the statutory withdrawal function must keep its own dedicated, prominently-labelled button (Art. 11a) and must not be replaced by or hidden behind a generic returns page. Dismissible.<\/li>\n<\/ul>\n\n<h4>2.41.0<\/h4>\n\n<ul>\n<li>Improved (evidence): the tamper-evident acknowledgement receipt now uses a versioned hash (v2) that additionally binds the <strong>product names<\/strong> and the <strong>predefined-reason code<\/strong> into the SHA-256, with an explicit version marker. New acknowledgements use v2; acknowledgements issued by earlier versions keep verifying against the original (v1) hash byte-for-byte, so nothing already issued is invalidated. <code>wp bzww verify<\/code> and the admin integrity badge automatically check against the recorded version.<\/li>\n<\/ul>\n\n<h4>2.40.0<\/h4>\n\n<ul>\n<li>New: an <strong>approve\/reject decision workflow<\/strong> for withdrawal statements. Pending (and received) statements now have an <strong>Approve<\/strong> action alongside Reject, recorded with an audit trail (who decided and when). A new <strong>\"When to issue the refund\"<\/strong> setting lets you choose to refund manually (default), automatically when you approve, or automatically as soon as the statement is submitted. A statutory withdrawal remains effective from the moment it is submitted \u2014 this only controls operational handling and the refund timing, never the validity of the right.<\/li>\n<\/ul>\n\n<h4>Earlier versions<\/h4>\n\n<p>The changelog for versions 2.39.0 and earlier (back to 1.0.0) is available in the readme.txt of each tagged release under https:\/\/plugins.svn.wordpress.org\/beziworld-withdrawal-for-woocommerce\/tags\/ .<\/p>","raw_excerpt":"EU 2023\/2673 withdrawal-from-contract flow for WooCommerce. Per-item withdrawals, guest tokens, automatic gateway refunds, holiday-aware deadlines.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/319606","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=319606"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/beziworld"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=319606"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=319606"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=319606"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=319606"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=319606"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=319606"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}