{"id":319524,"date":"2026-06-02T11:34:42","date_gmt":"2026-06-02T11:34:42","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/right-of-withdrawal-online-form-refunds\/"},"modified":"2026-07-06T10:05:16","modified_gmt":"2026-07-06T10:05:16","slug":"bitron-right-of-withdrawal","status":"publish","type":"plugin","link":"https:\/\/ta.wordpress.org\/plugins\/bitron-right-of-withdrawal\/","author":13379012,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.7.1","stable_tag":"1.7.1","tested":"7.0.1","requires":"6.4","requires_php":"8.0","requires_plugins":null,"header_name":"Bitron Right of Withdrawal","header_author":"BitronDev Kft.","header_description":"Akad\u00e1lymentes el\u00e1ll\u00e1si \u0171rlap webshopoknak. A 2026-06-19-i CRD\/45-2014 megfelel\u0151s\u00e9ghez.","assets_banners_color":"","last_updated":"2026-07-06 10:05:16","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"","rating":5,"author_block_rating":0,"active_installs":300,"downloads":1507,"num_ratings":4,"support_threads":4,"support_threads_resolved":4,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.4.1":{"tag":"1.4.1","author":"oaron","date":"2026-06-16 18:21:20"},"1.5":{"tag":"1.5","author":"oaron","date":"2026-06-19 09:50:53"},"1.6":{"tag":"1.6","author":"oaron","date":"2026-06-23 11:38:12"},"1.7":{"tag":"1.7","author":"oaron","date":"2026-06-28 08:35:46"},"1.7.1":{"tag":"1.7.1","author":"oaron","date":"2026-07-06 10:05:16"}},"upgrade_notice":[],"ratings":{"1":0,"2":0,"3":0,"4":0,"5":4},"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":{"right-of-withdrawal\/form":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"right-of-withdrawal\/form","version":"0.4.0","title":"Withdrawal Form","category":"widgets","icon":"undo","description":"Accessible withdrawal form for consumer orders. Same output as the [bitrow_form] shortcode.","keywords":["withdrawal","refund","form","consumer"],"textdomain":"bitron-right-of-withdrawal","attributes":{"primaryColor":{"type":"string","default":""},"primaryTextColor":{"type":"string","default":""},"secondaryColor":{"type":"string","default":""},"textColor":{"type":"string","default":""},"backgroundColor":{"type":"string","default":""},"borderColor":{"type":"string","default":""},"errorTextColor":{"type":"string","default":""},"errorBackgroundColor":{"type":"string","default":""},"errorBorderColor":{"type":"string","default":""},"introText":{"type":"string","default":""}},"supports":{"html":false,"multiple":false,"reusable":true,"align":["wide","full"]},"editorScript":"file:.\/index.js"}},"tagged_versions":["1.4.1","1.5","1.6","1.7","1.7.1"],"block_files":[],"assets_screenshots":{"screenshot-1.jpg":{"filename":"screenshot-1.jpg","revision":3557967,"resolution":"1","location":"assets","locale":"","width":694,"height":824},"screenshot-2.jpg":{"filename":"screenshot-2.jpg","revision":3557967,"resolution":"2","location":"assets","locale":"","width":1778,"height":688},"screenshot-3.jpg":{"filename":"screenshot-3.jpg","revision":3557967,"resolution":"3","location":"assets","locale":"","width":1450,"height":822},"screenshot-4.jpg":{"filename":"screenshot-4.jpg","revision":3557967,"resolution":"4","location":"assets","locale":"","width":1437,"height":806}},"screenshots":{"1":"The customer-facing withdrawal form \u2014 accessible by default, with programmatic labels and live status announcements. Logged-in or email-verified customers get a two-step order-matching flow; unverified guests file a free-text declaration instead.","2":"The Withdrawals admin list collects every incoming declaration with its unique <code>BITROW-XXXXXX<\/code> reference, the linked order, and the customer's refund preference.","3":"Settings \u2192 General \u2014 withdrawal window length, admin notification, and opt-in record deletion at uninstall.","4":"Settings \u2192 Form \u2014 optional intro paragraph and brand colors for the submit button, with a live WCAG contrast meter so a custom brand color cannot quietly drop below AA."}},"plugin_section":[],"plugin_tags":[1953,255182,131785,9682,245590],"plugin_category":[34],"plugin_contributors":[93346],"plugin_business_model":[],"class_list":["post-319524","plugin","type-plugin","status-publish","hentry","plugin_tags-accessibility","plugin_tags-consumer-rights","plugin_tags-gdpr","plugin_tags-refund","plugin_tags-withdrawal","plugin_category-accessibility","plugin_contributors-oaron","plugin_committers-oaron"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/bitron-right-of-withdrawal.svg","icon_2x":false,"generated":true},"screenshots":[{"src":"https:\/\/ps.w.org\/bitron-right-of-withdrawal\/assets\/screenshot-1.jpg?rev=3557967","caption":"The customer-facing withdrawal form \u2014 accessible by default, with programmatic labels and live status announcements. Logged-in or email-verified customers get a two-step order-matching flow; unverified guests file a free-text declaration instead."},{"src":"https:\/\/ps.w.org\/bitron-right-of-withdrawal\/assets\/screenshot-2.jpg?rev=3557967","caption":"The Withdrawals admin list collects every incoming declaration with its unique <code>BITROW-XXXXXX<\/code> reference, the linked order, and the customer's refund preference."},{"src":"https:\/\/ps.w.org\/bitron-right-of-withdrawal\/assets\/screenshot-3.jpg?rev=3557967","caption":"Settings \u2192 General \u2014 withdrawal window length, admin notification, and opt-in record deletion at uninstall."},{"src":"https:\/\/ps.w.org\/bitron-right-of-withdrawal\/assets\/screenshot-4.jpg?rev=3557967","caption":"Settings \u2192 Form \u2014 optional intro paragraph and brand colors for the submit button, with a live WCAG contrast meter so a custom brand color cannot quietly drop below AA."}],"raw_content":"<!--section=description-->\n<p>From 19 June 2026, EU member states require every consumer-facing online shop to provide an <strong>online withdrawal function<\/strong> \u2014 not just static information, but a continuously available electronic interface where the consumer can declare intent to withdraw, and from which the shop sends an automatic confirmation on a durable medium. In Hungary the same rule applies through the amendment of Government Decree 45\/2014.<\/p>\n\n<p>Bitron Right of Withdrawal delivers exactly that, accessibly.<\/p>\n\n<p><strong>What the plugin does<\/strong><\/p>\n\n<ul>\n<li>A continuously available, accessible withdrawal form \u2014 embeddable via the <code>[bitrow_form]<\/code> shortcode or the <em>Withdrawal Form<\/em> Gutenberg block, so it drops into any classic-editor page, a block-built layout, or a page builder that handles either.<\/li>\n<li>Tight WooCommerce integration: the form is surfaced to logged-in customers as a <em>Withdrawal<\/em> item in their <em>My Account<\/em> menu, but only while they have at least one order still inside the window \u2014 so a customer with nothing eligible doesn't see a dead link.<\/li>\n<li>A withdrawal link is automatically attached to WooCommerce's customer order emails (processing, completed, invoice) while the window is open \u2014 a discreet text link (not a prominent button) to avoid accidental clicks. Its position in the email (top, after the order details, or bottom \u2014 bottom by default) and both the surrounding message text and the link label are configurable under <em>Settings \u2192 Email<\/em>. HTML and plain-text variants, with a filter to extend the list of carrier emails.<\/li>\n<li>Guest and logged-in customer paths. A logged-in customer sees a select of their own in-window orders. For guests, optional <strong>email verification<\/strong>: with the free <a href=\"https:\/\/wordpress.org\/plugins\/onecode-login\/\">OneCode Login<\/a> plugin active, the guest proves they own their email with a one-time code, and the form then loads that email's orders just like for a logged-in customer \u2014 closing the gap where anyone who knew an order number and the billing email could file on someone else's behalf. When email verification is not in force, an unverified guest is never shown any order data: instead of looking up an order, they file a free-text withdrawal declaration (no order is matched server-side, no line items or totals are disclosed), which is recorded flagged as unverified for the shop to match by hand. Order data is therefore only ever shown to logged-in or email-verified customers.<\/li>\n<li>Item-level partial withdrawal. After the customer picks an order, they tick exactly which line items (and quantities) they want to withdraw from \u2014 the form is not all-or-nothing.<\/li>\n<li>Bank-account capture for non-card payments. When the original gateway can't refund automatically (e.g. cash on delivery, bank transfer), the customer enters a Hungarian IBAN or domestic GIRO account number \u2014 validated client- and server-side with MOD-97 \/ CDV checks \u2014 so the shop has everything to wire the refund manually.<\/li>\n<li>Customizable form copy and brand colors. An optional intro paragraph above the form and the submit-button colors (background + text) are configurable from <em>Settings \u2192 Form<\/em>, with a live WCAG contrast meter that announces the ratio as you type so a custom brand color cannot quietly drop below AA. An \"advanced\" panel additionally exposes the form body text, wrapper background, and input\/fieldset border colors for themes that need the form to blend in \u2014 these three are not contrast-checked and carry an explicit \"you own the contrast\" warning. The same values can be overridden per-instance through <code>[bitrow_form]<\/code> shortcode attributes or the block's <em>Inspector<\/em> panel.<\/li>\n<li>Automatic confirmation email to the customer (durable medium) and notification to the shop admin, with editable subject and body templates for both \u2014 empty fields fall back to safe i18n defaults so the plugin is functional out of the box. The admin notification recipient is a configurable email address (defaults to the site administration email); leave it empty to switch admin notifications off.<\/li>\n<li>Optional business-customer exclusion: because the right of withdrawal is a consumer right, shops that also sell to VAT-registered businesses can switch the online form off for orders carrying a business marker (e.g. a VAT-number checkout field). Business buyers are shown a contact pointer instead; consumer orders are unaffected. It's a technical filter, not legal advice.<\/li>\n<li>Per-product and per-category withdrawal exemptions for the CRD \u00a716 \/ 45-2014 \u00a729 carve-outs (perishables, custom-made, sealed digital downloads, etc.). The withdrawal form still shows exempted items inside an eligible order so the customer sees what they bought, but the quantity input is locked at zero with a visible \"Not eligible for withdrawal\" badge; orders that consist entirely of exempt items are blocked at step 1 with a contact pointer. A separate <em>Settings \u2192 Exclusions<\/em> tab manages the lists with searchable autocompletes.<\/li>\n<li>Exclusion type split \u2014 excluded by law vs waivable. The exclusion settings separate two legally distinct cases: \"excluded by law\" items (perishables, custom-made, opened sealed goods) where the right never applies and no customer action is involved, and \"waivable\" items where the right exists but the customer can expressly give it up. Each case has its own product and category pickers; existing exclusions keep behaving as \"by law\".<\/li>\n<li>Checkout withdrawal waiver. For waivable goods (typically digital content), the shop can show a consent checkbox at checkout through which the customer expressly waives the right of withdrawal for the affected items. It appears only when the cart actually contains a waivable item, works on both the classic shortcode checkout and the block-based (Store API) checkout, can be optional or mandatory, and records the consent on the order as evidence (timestamp, IP, a fingerprint of the statement text, the covered products and the mode). Off by default; enable and word it under <em>Settings \u2192 Exclusions<\/em>.<\/li>\n<li>\"Withdrawals\" hub in the customer's <em>My Account<\/em> area \u2014 a single durable, log-in-gated landing page for everything withdrawal-related: a one-click button to start a new declaration (when the form page is configured), plus the full list of past declarations submitted from the account (reference number, date, order link, items, refund preference, status). The menu item appears only when the customer has at least one past record OR an order still inside the withdrawal window; the list itself is privacy-scoped to the customer's own account email and never reveals records filed under a different email.<\/li>\n<li>Minimal record-keeping with unique <code>BITROW-XXXXXX<\/code> references for evidentiary value, plus a per-record detail page in the admin.<\/li>\n<li>Admin can mark a record as <em>closed<\/em> (and reopen it) once the case is resolved, with timestamp and the closing user recorded \u2014 keeps the working list focused on what's still pending.<\/li>\n<li>Withdrawal status on the order screen. When an order has an associated withdrawal, the WooCommerce order-edit screen shows a \"Right of withdrawal\" panel with the withdrawal's status and a direct link to its record.<\/li>\n<li>Optional withdrawal column on the orders list. A <em>Settings \u2192 General<\/em> switch (off by default) adds a column to the WooCommerce orders list flagging which orders have a withdrawal and its status (a dash when none). HPOS- and legacy-orders compatible.<\/li>\n<li>WCAG 2.1 AA accessibility throughout \u2014 programmatic labels, focus management, live regions, sufficient contrast.<\/li>\n<li>GDPR integration with WordPress' personal data export and erase tools, plus a suggested paragraph for the Privacy Policy Guide.<\/li>\n<\/ul>\n\n<p><strong>Compatibility<\/strong><\/p>\n\n<p>The plugin integrates with WooCommerce orders. It declares HPOS (High-Performance Order Storage) compatibility and uses the WooCommerce CRUD API throughout. WooCommerce is referenced for compatibility only \u2014 the trademark is not used in the plugin name or slug.<\/p>\n\n<p><strong>Important \u2014 what this plugin does NOT do<\/strong><\/p>\n\n<p>This is a technical tool, not legal advice, and does not by itself guarantee legal compliance. The plugin does not generate Terms of Service text, privacy-policy text, or other legal content \u2014 those must be prepared by your own lawyer. The confirmation email contains only a factual acknowledgement (received, when, with which ID, what content); any \"what happens next\" wording is the shop operator's own policy and must come from you.<\/p>\n\n<p>The plugin records each withdrawal and notifies you, but it does not issue refunds automatically. Refunds remain a deliberate admin action through WooCommerce's standard refund interface.<\/p>\n\n<p><strong>Privacy<\/strong><\/p>\n\n<p>The plugin stores only what is necessary to acknowledge and document the withdrawal: name, email, order reference, optional note, timestamps and a unique identifier. No IP address is stored in plain text. On plugin removal the stored records are kept by default (so an accidental deactivation cannot destroy evidence); a setting lets you opt in to deletion at uninstall.<\/p>\n\n<h3>Pro version<\/h3>\n\n<p>The free plugin covers the full legal compliance core on its own. <strong>Bitron Right of Withdrawal Pro<\/strong> adds a convenience and automation layer on top, for shops that process withdrawals regularly:<\/p>\n\n<ul>\n<li><strong>One-click WooCommerce refund<\/strong> \u2014 issue the refund straight from the withdrawal record, instead of re-entering it by hand in WooCommerce.<\/li>\n<li><strong>Status management and history<\/strong> \u2014 a richer status workflow (received, in progress, goods returned, refunded, rejected) with a full audit trail of who changed what and when.<\/li>\n<li><strong>Automation rules<\/strong> \u2014 define rules that act on incoming withdrawals automatically (status transitions, notifications), so routine cases handle themselves.<\/li>\n<li><strong>Custom form fields<\/strong> \u2014 add your own fields to the withdrawal form and store them on the record.<\/li>\n<li><strong>Searchable admin + CSV export<\/strong> \u2014 find any declaration fast and export the list for accounting or reporting.<\/li>\n<li><strong>Webhooks<\/strong> \u2014 push withdrawal events to your CRM, ERP or any external system in real time.<\/li>\n<li><strong>REST API<\/strong> \u2014 read and manage withdrawal records programmatically from your own integrations.<\/li>\n<\/ul>\n\n<p>The Pro plugin is standalone: it contains the full compliance core plus the convenience layer, so you install it instead of the free plugin, not alongside it. Pro adds convenience, not extra compliance \u2014 the free plugin already makes you compliant.<\/p>\n\n<p><a href=\"https:\/\/bitron.hu\/woocommerce-elallas\">Learn more and see pricing<\/a><\/p>\n\n<!--section=installation-->\n<ol>\n<li>Install the plugin through the <em>Plugins \u2192 Add New<\/em> screen, or upload the plugin folder to <code>\/wp-content\/plugins\/bitron-right-of-withdrawal\/<\/code>.<\/li>\n<li>Activate the plugin through the <em>Plugins<\/em> screen in WordPress.<\/li>\n<li>Create the page that should host the form (for example, \"Withdrawal declaration\") and either:\n\n<ul>\n<li>add the shortcode <code>[bitrow_form]<\/code> to the page content, or<\/li>\n<li>insert the <em>Withdrawal Form<\/em> block in the block editor.<\/li>\n<\/ul><\/li>\n<li>Go to <em>Withdrawals \u2192 Settings<\/em> in the WordPress admin and select that page in the <em>Form page<\/em> setting. This is what enables the contextual link in WooCommerce's \"My Account\" area and in the order confirmation emails.<\/li>\n<li>Review the other settings on the same screen (withdrawal window length, admin notification, email subject and body) and save.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20i%20still%20need%20to%20put%20withdrawal%20information%20in%20my%20terms%20of%20service%3F\"><h3>Do I still need to put withdrawal information in my Terms of Service?<\/h3><\/dt>\n<dd><p>Yes. The plugin provides the technical function; your Terms of Service must still explain the right of withdrawal, exceptions, and refund handling under your shop's policy. Your legal advisor drafts that text \u2014 the plugin does not.<\/p><\/dd>\n<dt id=\"what%20about%20the%20privacy%20policy%3F\"><h3>What about the privacy policy?<\/h3><\/dt>\n<dd><p>The plugin registers a suggested paragraph in the WordPress Privacy Policy Guide describing what data it processes. Your lawyer should integrate that into the shop's full privacy policy.<\/p><\/dd>\n<dt id=\"can%20guests%20verify%20their%20identity%20before%20filing%20a%20withdrawal%3F\"><h3>Can guests verify their identity before filing a withdrawal?<\/h3><\/dt>\n<dd><p>Yes, optionally. Install the free OneCode Login plugin and a guest can prove they own their email with a one-time code; the form then loads the orders for that email. When enabled, this is required for guests (it replaces matching a typed email against the order). Without OneCode Login, guests identify an order by entering its number together with the billing email, as before.<\/p><\/dd>\n<dt id=\"does%20it%20automatically%20refund%20the%20customer%3F\"><h3>Does it automatically refund the customer?<\/h3><\/dt>\n<dd><p>No. The plugin records the withdrawal and notifies you; refunds remain a deliberate admin action through WooCommerce's standard refund interface.<\/p><\/dd>\n<dt id=\"is%20it%20accessible%3F\"><h3>Is it accessible?<\/h3><\/dt>\n<dd><p>Accessibility is the product's main differentiator. The form is WCAG 2.1 AA \u2014 programmatic labels, keyboard operability, visible focus, live regions for status messages, sufficient contrast. The admin list follows the same standard.<\/p><\/dd>\n<dt id=\"where%20can%20my%20customers%20see%20the%20withdrawal%20declarations%20they%27ve%20submitted%3F\"><h3>Where can my customers see the withdrawal declarations they've submitted?<\/h3><\/dt>\n<dd><p>Under <em>My Account \u2192 Withdrawals<\/em>. The page is a single hub: when you've set the withdrawal form page in <em>Settings \u2192 Form<\/em>, it shows a \"Submit a new withdrawal declaration\" button at the top; below it (or alone if the form page isn't set) it lists every declaration the logged-in customer has filed under their account email, with the reference number, date, the affected order, the items, the refund preference and the current status. The menu item appears only when the customer has at least one past record OR an order still inside the withdrawal window \u2014 accounts that never use the feature don't see a dead menu link. Records filed under a different email (e.g. with the customer logged out) are not surfaced here for privacy reasons; the customer can still find those via the confirmation email they received at submission time.<\/p><\/dd>\n<dt id=\"can%20i%20exclude%20certain%20products%20or%20categories%20from%20the%20withdrawal%20form%3F\"><h3>Can I exclude certain products or categories from the withdrawal form?<\/h3><\/dt>\n<dd><p>Yes. Under <em>Settings \u2192 Exclusions<\/em> there are two pickers \u2014 one for individual products, one for product categories \u2014 backed by searchable autocompletes. The CRD \u00a716 (transposed in Hungary as 45\/2014. Korm. r. \u00a729) lists categories of goods where the right of withdrawal does not apply at all: perishables, custom-made items, sealed digital downloads, items inseparably mixed with others, etc. Use the exclusions to mirror that list for your shop.<\/p>\n\n<p>Excluded items still appear on the withdrawal form so customers see exactly what they bought, but their quantity input is locked at zero and the row is marked with a \"Not eligible for withdrawal\" badge. If the customer picks an order whose every line item is excluded, the form blocks at step 1 with a \"please contact us\" pointer rather than presenting a step 2 where everything is greyed out. The server enforces the same rule on submit \u2014 a crafted POST that tries to set a positive quantity on an excluded item is rejected with a clear error.<\/p><\/dd>\n<dt id=\"can%20i%20switch%20the%20withdrawal%20form%20off%20for%20business%20%28b2b%29%20customers%3F\"><h3>Can I switch the withdrawal form off for business (B2B) customers?<\/h3><\/dt>\n<dd><p>Yes. The right of withdrawal is a consumer right, so under <em>Settings \u2192 Exclusions<\/em> you can enable \"Switch the online form off for business purchases\" and choose the checkout field whose presence on an order marks it as a business purchase \u2014 typically a VAT-number field. The list of available fields is read live from your checkout, so it reflects whatever fields your theme or other plugins add. Orders that carry a value in that field are blocked at step 1 with a message pointing the buyer to your contact channel; orders without it behave exactly as before. This is a technical filter to match your own policy \u2014 it is not legal advice, and you decide which field marks a business buyer.<\/p><\/dd>\n<dt id=\"can%20i%20customize%20the%20form%20text%2C%20background%2C%20and%20border%20colors%3F\"><h3>Can I customize the form text, background, and border colors?<\/h3><\/dt>\n<dd><p>Yes. <em>Settings \u2192 Form<\/em> has a \"Form colours (advanced)\" card with three colour pickers (form text, form background, input + fieldset border), and the same three are also available as <code>text<\/code>, <code>background<\/code>, <code>border<\/code> attributes on the <code>[bitrow_form]<\/code> shortcode and as inspector controls on the <em>Withdrawal Form<\/em> block.<\/p>\n\n<p>These three colours are <strong>not<\/strong> contrast-checked \u2014 there is no single adjacent surface to validate the body text against, so we cannot give you a meaningful ratio in the admin UI. WCAG 2.1 AA requires at least 4.5:1 for normal text and 3:1 for UI borders; verify any combination you change with an external checker (e.g. WebAIM Contrast Checker). The submit-button pair above is still contrast-checked live as before.<\/p><\/dd>\n<dt id=\"can%20a%20guest%20customer%20use%20it%2C%20or%20only%20logged-in%20users%3F\"><h3>Can a guest customer use it, or only logged-in users?<\/h3><\/dt>\n<dd><p>Both, but what a guest is shown depends on whether they can prove their identity. A logged-in customer sees a select of their own in-window orders. A guest with email verification active (the free <a href=\"https:\/\/wordpress.org\/plugins\/onecode-login\/\">OneCode Login<\/a> plugin) proves they own their email with a one-time code and then sees that email's orders the same way. An unverified guest \u2014 when email verification is not in force \u2014 does <strong>not<\/strong> get the two-step order-matching form and is never shown any order data: instead they file a free-text withdrawal declaration in their own words (no order is looked up or matched server-side, no line items or totals are disclosed), recorded flagged \"unverified\" for the shop to match by hand. The form is never gated behind login.<\/p><\/dd>\n<dt id=\"can%20i%20change%20the%2014-day%20withdrawal%20window%3F\"><h3>Can I change the 14-day withdrawal window?<\/h3><\/dt>\n<dd><p>Yes. <em>Settings \u2192 Bitron Right of Withdrawal<\/em> exposes the window length in days. The default is 14 (the EU minimum); some jurisdictions require longer.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20hpos%20%28high-performance%20order%20storage%29%3F\"><h3>Does it work with HPOS (High-Performance Order Storage)?<\/h3><\/dt>\n<dd><p>Yes. The plugin declares HPOS compatibility and uses the WooCommerce CRUD API rather than direct post-meta access.<\/p><\/dd>\n<dt id=\"where%20can%20i%20find%20the%20recorded%20withdrawals%3F\"><h3>Where can I find the recorded withdrawals?<\/h3><\/dt>\n<dd><p>Under <em>Withdrawals<\/em> in the WordPress admin sidebar. Each entry has a unique reference (e.g. <code>BITROW-XXXXXX<\/code>) and a timestamp; the list is a simple, paginated view.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.7.1<\/h4>\n\n<ul>\n<li>Fix \u2014 on the order-edit screen, the \"Mark as closed\" \/ \"Reopen\" control in the withdrawal meta box rendered its form nested inside the WooCommerce order form. Browsers drop nested forms but keep their hidden fields, so the meta box's hidden action field leaked into the order form and hijacked the order \"Update\" button: on orders that had a withdrawal record, saving the order silently failed and the status change was lost. The control now renders its form outside the WooCommerce order form (via the HTML5 form= attribute), so the order update works normally and the close\/reopen action still works.<\/li>\n<\/ul>\n\n<h4>1.7<\/h4>\n\n<ul>\n<li>New \u2014 the guest email-verification (OTP) texts are now editable in the admin under Settings \u2192 Form: the verification prompt shown to unverified guests, the \"send verification email\" and \"confirm code\" button labels, and the verification-code help text. Previously these were fixed built-in strings. Leaving a field empty keeps the built-in default.<\/li>\n<li>New \u2014 the guest email-verification step is now visually highlighted as a clear call to action: the prompt sits in an accented callout and its verify\/confirm button is a solid, filled button so an unverified guest notices the action they must take. The emphasis never relies on colour alone (left-border surface plus the prompt text and accessible button names), and the button keeps AAA contrast.<\/li>\n<li>New \u2014 the above verification texts are multilingual: they can be translated per language through WPML String Translation or Polylang's strings screen, like the other admin-entered texts. On single-language sites nothing changes.<\/li>\n<\/ul>\n\n<h4>1.6<\/h4>\n\n<ul>\n<li>New \u2014 multilingual support (WPML and Polylang): all admin-entered texts (form intro and disclaimer, the submission success message, the notification email subjects and bodies, the order-email withdrawal link label and text) can now be translated per language through WPML String Translation or Polylang's strings screen, and the form-page link follows the current language. On single-language sites nothing changes.<\/li>\n<li>New \u2014 the submission success message shown after the form is sent can now be edited in the admin under Settings \u2192 Form, including a {uid} placeholder for the record's reference id. Previously it was a fixed built-in text.<\/li>\n<li>Fix \u2014 secondary button hover: the secondary button's text colour is now pinned on hover, so it no longer turns unreadable (e.g. white-on-white) under themes that restyle button hover states.<\/li>\n<li>Fix \u2014 notification emails are now sent as HTML, so line breaks survive on sites where an SMTP or email-template plugin renders mail as HTML. Previously the text could arrive as one run-on block.<\/li>\n<li>Fix \u2014 the withdrawal form now recognises custom order numbers. When a plugin overrides WooCommerce's default order number (for example MD0574), the form accepts the displayed number, not only the original numeric ID.<\/li>\n<\/ul>\n\n<h4>1.5<\/h4>\n\n<ul>\n<li>Hardening (security) \u2014 this change was made to satisfy the WordPress.org plugin security review. Unverified guests now file a free-text withdrawal declaration without any order data being looked up or shown. Order data is disclosed only to logged-in or email-verified customers; a visitor who cannot prove their identity describes their order in their own words, and the resulting declaration is flagged \"unverified\" in the admin for manual matching before any refund.<\/li>\n<li>New \u2014 checkout withdrawal waiver: for goods where the right of withdrawal can be waived (typically digital content), the shop can now show a consent checkbox at checkout through which the customer expressly waives that right for the affected items. The checkbox appears only when the cart actually contains a waivable item, and works on both the classic shortcode checkout and the block-based (Store API) checkout. It can be set globally to optional or mandatory \u2014 mandatory blocks placing the order until the box is ticked. The consent is recorded on the order as evidence (timestamp, IP address, a fingerprint of the exact statement text, the covered products and the mode) and shown in a \"Withdrawal waiver\" panel on the order-edit screen. Off by default; enable and word it under <em>Settings \u2192 Exclusions<\/em>. For the block-based Checkout, add the \"Withdrawal waiver\" block to your Checkout page once where you want it to appear.<\/li>\n<li>New \u2014 exclusion type split (excluded by law vs waivable): the withdrawal-exclusion settings now separate two legally distinct cases. \"Excluded by law\" items (perishables, custom-made goods, opened hygiene\/sealed products) are never withdrawable \u2014 the right does not apply, no customer action is involved and no checkbox is shown. \"Waivable\" items are those where the right exists but the customer can give it up with the checkout consent: only these drive the consent checkbox, and such an item stays excluded only when the customer actually consents \u2014 without consent the right of withdrawal is retained. Existing exclusions keep behaving as \"by law\", so nothing changes for orders that predate this. Each case has its own product and category pickers under <em>Settings \u2192 Exclusions<\/em>.<\/li>\n<li>New \u2014 withdrawal status on the order screen: when an order has an associated withdrawal, the WooCommerce order-edit screen now shows a \"Right of withdrawal\" panel with the withdrawal's status and a link straight to its record.<\/li>\n<li>New \u2014 optional withdrawal column on the orders list: a new <em>Settings \u2192 General<\/em> switch (\"Show a withdrawal column in the orders table\", off by default) adds a column to the WooCommerce orders list flagging which orders have a withdrawal and its status (a dash when none). HPOS- and legacy-orders compatible.<\/li>\n<li>Fix \u2014 bank account entry: a Hungarian IBAN (starting \"HU\") could not be typed into the field \u2014 the letters were stripped as you went, so the prefix never took. Typing an IBAN now works character by character (pasting one already worked).<\/li>\n<li>Improvement \u2014 domestic (GIRO) bank account validation is no longer over-strict: it still checks the account format and the bank + branch check digit, but no longer rejects on the account-holder block's check digit, which is bank-dependent and not present at every bank. Valid accounts issued by some banks (e.g. Raiffeisen, Budapest Bank) that were previously refused are now accepted.<\/li>\n<li>New \u2014 the withdrawal link added to WooCommerce order emails is now a discreet text link instead of a prominent box, to avoid accidental clicks. Its position in the email is configurable (top, after the order details, or bottom \u2014 bottom by default), and both the surrounding message text and the link label can be customised under <em>Settings \u2192 Email<\/em>.<\/li>\n<li>Improvement \u2014 withdrawal form, step 2: item quantities now start at 0 and the customer increases them, instead of pre-filling the full purchased quantity. The per-item maximum still applies, and at least one item must be selected to submit.<\/li>\n<\/ul>\n\n<h4>1.4.1<\/h4>\n\n<ul>\n<li>Fix \u2014 the \"order not found\" validation message now displays correctly in Hungarian (the message was rewritten in 1.4 and its translation was missing from the shipped language pack, so it fell back to English).<\/li>\n<\/ul>\n\n<h4>1.4<\/h4>\n\n<ul>\n<li>Fix \u2014 guest (not-logged-in) form completion: the withdrawal form now fills in and submits reliably for visitors who are not logged in, including on shops running a login-hardening layer (rename wp-login.php, hide-wp-admin, a firewall) that could previously break the guest two-step submission. Where 1.3.2 only diagnosed an intercepted submit, the guest path now completes.<\/li>\n<li>New \u2014 Pro version visibility: administrators can clearly see that a Pro version exists and, when the Pro plugin is installed, which Pro version is active. The free-only upsell never appears once Pro is present.<\/li>\n<li>Fix \u2014 double-submission guard: a duplicated or retried submission (double click, network retry) can no longer create two withdrawal records or send two confirmation emails for the same declaration. The legitimate partial \/ repeat-withdrawal flow is unaffected.<\/li>\n<li>Fix \u2014 GDPR personal-data export now labels the \"by later arrangement\" refund preference correctly, instead of showing it as \"Original payment method\".<\/li>\n<li>Fix \u2014 the admin \"notification could not be sent\" notice now escapes its output correctly.<\/li>\n<li>Hardening \u2014 the guest email-verification code requests now carry their own rate limit, independent of whether the OneCode Login plugin enforces one, to prevent code-request flooding.<\/li>\n<li>Maintenance \u2014 uninstall now removes every option the plugin can create (customer-service contact, diagnostics toggle, error colours); plus minor robustness fixes in stored-record decoding and query handling.<\/li>\n<\/ul>\n\n<h4>1.3.2<\/h4>\n\n<ul>\n<li>Fix \u2014 when submitting the form fails because a caching or security layer (firewall, \"hide wp-admin\" rule, full-page cache) intercepts the request \u2014 most often for visitors who are not logged in \u2014 the form no longer does nothing silently. It now shows an accessible diagnostic with the server response status and a short excerpt of what came back, so the shop owner can identify and whitelist the layer that is blocking the submission.<\/li>\n<li>New \u2014 these intercepted submissions are also recorded in the WooCommerce logs (WooCommerce \u2192 Status \u2192 Logs, source \"bitron-right-of-withdrawal\"), including the response status, the page, and whether the visitor was logged in, so the shop owner has a server-side trail even if no one reports the problem. Stale-nonce failures (a cached form) are logged too. Logging is rate-limited, stores no plain-text IP addresses, and can be turned off with the bitrow_diagnostics_enabled filter.<\/li>\n<\/ul>\n\n<h4>1.3.1<\/h4>\n\n<ul>\n<li>Fix \u2014 email notifications: the order total no longer leaks raw HTML entities into the plain-text message (e.g. \"12&nbsp;990&nbsp;Ft\" \/ \"&#070;&#116;\") \u2014 the amount is now stripped and entity-decoded to clean text such as \"12 990 Ft\".<\/li>\n<li>New \u2014 a dismissible admin banner introduces the Pro version (one-click refunds, status management, automation, custom fields, CSV export, webhooks, REST API) with a link to learn more. Shown only in the free plugin and only to administrators, can be dismissed per-user, and never appears when the Pro plugin is present.<\/li>\n<\/ul>\n\n<h4>1.3<\/h4>\n\n<ul>\n<li>Fix \u2014 the bank account number is no longer mandatory: when the original payment method cannot auto-refund, the customer can choose \"by later arrangement\" and submit the declaration without entering an account number; the shop arranges the refund details afterwards.<\/li>\n<li>Fix \u2014 corrected a bank account number handling bug.<\/li>\n<li>Fix \u2014 resolved a block editor (Gutenberg) issue with the Withdrawal Form block.<\/li>\n<li>Fix \u2014 Hungarian translation: customer-facing strings switched to the formal register (mag\u00e1z\u00e1s) for a consistent tone across the form, emails and account pages.<\/li>\n<li>Improvement \u2014 the bank account field now formats the number as you type (IBAN in groups of four, domestic accounts as 8-8-8) and shows a \"saved as\" preview of the exact value the shop will receive, cutting down copy-paste and typing mistakes. When you finish typing it checks the IBAN\/GIRO and announces the result (valid or not) to screen readers, instead of only failing on submit. Fully keyboard- and screen-reader-accessible; pasting a number with spaces or hyphens still works.<\/li>\n<li>New \u2014 repeat-withdrawal guard: once a customer has already declared withdrawal for every eligible item in an order, re-selecting that order is blocked at step 1 with a clear message. If only some items \u2014 or some quantities \u2014 are still eligible, the form lets them through but limits each item to the remaining amount and marks the already-withdrawn ones. Enforced server-side, so it cannot be bypassed from the browser.<\/li>\n<li>New \u2014 customisable error colours: the validation error summary and the blocked-order notice (the red box above the form) now take their text, background, and left-accent-border colours from <em>Settings \u2192 Form \u2192 \"Error message colours\"<\/em>, the <code>[bitrow_form]<\/code> <code>error_text<\/code> \/ <code>error_background<\/code> \/ <code>error_border<\/code> attributes, or the block's inspector \u2014 matching the existing form-colour customisation. Defaults are unchanged (and stay WCAG-AA); like the other advanced colours these are not contrast-checked, so you own the contrast on any override.<\/li>\n<li>New \u2014 customer-service contact: a dedicated <em>Settings \u2192 General \u2192 \"Customer service contact\"<\/em> section lets you enter a support email and phone number. These are shown on every step-1 message that stops a customer from proceeding \u2014 the repeat-withdrawal block, the \u00a716-exempt and business-purchase blocks, and orders with nothing withdrawable \u2014 so they always know how to reach you instead of hitting a dead end. Both fields are optional \u2014 the email falls back to your WordPress administration email when left empty, and the phone is offered only when set.<\/li>\n<\/ul>\n\n<h4>1.2<\/h4>\n\n<ul>\n<li>New \u2014 business-customer exclusion: the right of withdrawal is a consumer right, so shops that also sell to VAT-registered businesses can now switch the online withdrawal form off for business orders. Under <em>Settings \u2192 Exclusions<\/em> enable \"Switch the online form off for business purchases\" and pick the checkout field whose presence on an order marks it as a business purchase (for example a VAT-number field). The available fields are read live from your checkout (<code>woocommerce_checkout_fields<\/code>), grouped by Billing \/ Shipping \/ Account \/ Order. Orders that carry a value in that field are blocked at step 1 with a message pointing the buyer to your contact channel; orders without it are treated as consumer purchases and work exactly as before. This is a technical filter, not legal advice \u2014 you decide which field marks a business buyer.<\/li>\n<li>New \u2014 the admin notification setting is now a free-form email field instead of an on\/off toggle: send each new declaration to any address, not just the site administration email. It defaults to your WordPress administration email (filled in automatically on update), you can point it elsewhere, and leaving it empty turns admin notifications off. An invalid address is rejected with a clear, screen-reader-announced error instead of silently disabling notifications.<\/li>\n<li>Improvement \u2014 the <em>Form page<\/em> selector is now a searchable, fully keyboard- and screen-reader-accessible combobox (the same accessible search already used by the product\/category exclusion pickers), so picking the form page no longer means scrolling a huge dropdown on shops with many pages.<\/li>\n<li>Maintenance \u2014 resolved all Plugin Check findings (translator comments, escaping, prepared-statement annotations) and hardened the test suite (deterministic colour-setting isolation). No behaviour change for the customer-facing form.<\/li>\n<\/ul>\n\n<h4>1.1<\/h4>\n\n<ul>\n<li>New \u2014 guest email verification: with the free <a href=\"https:\/\/wordpress.org\/plugins\/onecode-login\/\">OneCode Login<\/a> plugin active, a not-logged-in customer can prove they own their email with a one-time code before filing. The form emails a code; once entered, it loads the orders for that email just like for a logged-in customer. This replaces the previous \"order number + typed email\" guest path (which anyone who knew both could use), closing that gap. Controlled by <em>Settings \u2192 Form \u2192 Guest email verification<\/em> (on by default when OneCode Login is available). When OneCode Login isn't active the setting is shown disabled with a one-click \"Install &amp; activate OneCode Login\" button (for admins who can install plugins) plus a manual-install link; the classic guest path keeps working so the plugin remains fully standalone. Keyboard- and screen-reader-accessible; the verification step requires JavaScript.<\/li>\n<li>New \u2014 product and category withdrawal exemptions: exclude individual products and whole product categories from the right of withdrawal, for the CRD \u00a716 \/ 45-2014 \u00a729 carve-outs (perishables, custom-made goods, sealed digital downloads, etc.). Managed from a dedicated <em>Settings \u2192 Exclusions<\/em> tab with searchable, fully keyboard- and screen-reader-accessible autocompletes. Exempt items still appear inside an eligible order (with a visible \"Not eligible for withdrawal\" badge and the quantity locked at zero) so the customer sees what they bought; an order made up entirely of exempt items is blocked at step 1 with a contact pointer.<\/li>\n<li>New \u2014 text and colour customization: match the form to your shop's look. The submit-button background and text colours come with a live WCAG contrast meter that announces the ratio as you type, and an advanced panel adds the form text, background, and input\/fieldset border colours. There's also an optional intro paragraph and the editable disclaimer below the form. Set everything from <em>Settings \u2192 Form<\/em>, or override per-instance through <code>[bitrow_form]<\/code> shortcode attributes and the <em>Withdrawal Form<\/em> block's Inspector panel.<\/li>\n<li>New \u2014 customer \"Withdrawals\" hub in <em>My Account<\/em>: a single, logged-in landing page combining a \"Submit a new withdrawal declaration\" button (when the form page is configured) with the customer's own record of every declaration filed from their account \u2014 reference number, date, affected order, items, refund preference and status. The menu item appears only when there's something to show, and the list is privacy-scoped to the account email.<\/li>\n<li>Improvement \u2014 for logged-in customers the step-1 name field prefills from the WooCommerce billing record (family name + given name) instead of the WordPress display name, so the declaration carries the real name used at checkout; email prefills from the account.<\/li>\n<\/ul>\n\n<h4>1.0<\/h4>\n\n<ul>\n<li>Initial release<\/li>\n<\/ul>","raw_excerpt":"Accessible online withdrawal form. Built for the EU Consumer Rights Directive update effective 19 June 2026.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ta.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/319524","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ta.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/ta.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/ta.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=319524"}],"author":[{"embeddable":true,"href":"https:\/\/ta.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/oaron"}],"wp:attachment":[{"href":"https:\/\/ta.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=319524"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/ta.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=319524"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/ta.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=319524"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/ta.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=319524"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/ta.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=319524"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/ta.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=319524"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}