What is the EU withdrawal button?
The EU withdrawal button is a function on a website or app through which a consumer can declare withdrawal from a contract concluded online, as easily as they placed the order. It comes from Directive (EU) 2023/2673, which amended the Consumer Rights Directive; each member state writes it into national law, and Germany did so in § 356a BGB, applying since 19 June 2026.
Before this rule, a German customer could withdraw by letter, email, phone or the model withdrawal form, and many shops buried those options in the Widerrufsbelehrung. The new function does not replace those routes. It adds a mandatory digital one that must sit on the same interface where contracts are made.
Calling it a "button" undersells it. The law describes a short process: an entry point labelled "Vertrag widerrufen" or something equally clear, a form, a second confirmation button labelled "Widerruf bestätigen" or similar, and an acknowledgement of receipt sent at once on a durable medium. You can read the German statute on gesetze-im-internet.de, the federal government's law portal.
Who needs an EU withdrawal button in Germany?
Any business that lets consumers conclude distance contracts through an online interface needs one, wherever a statutory withdrawal right exists. That covers online shops, booking and subscription sites, and mobile apps where purchases are made. Pure B2B shops that only sell to businesses are outside the rule, because the withdrawal right is a consumer right.
Where the law excludes the withdrawal right for a particular contract, the function is not required for it. Typical exclusions in German law include goods made to the customer's specification and perishable goods, but whether an exclusion applies to your products is a question for your lawyer, not for a developer. Mixed shops, where some items carry a withdrawal right and some do not, usually still need the EU withdrawal button for the covered items.
Being small is not an exemption. A two-person shop on Shopify has the same duty as a large retailer, which is why the platforms moved quickly to offer apps and native features. For sellers that serve both trade and private buyers, the button should appear to consumers; if you also run a trade portal, see our separate guide to B2B portal development, where this duty does not apply to the logged-in business customers.
What must the EU withdrawal button do? The five requirements
§ 356a BGB can be read as five technical requirements. Each one maps to something testable in your shop, which is how we turn the statute into a build ticket.
- Entry point: a function labelled “Vertrag widerrufen” or an equally clear phrase, readable, prominently placed and easy to reach for the whole withdrawal period
- Form: lets the consumer give their name, details that identify the contract or the part of it they want to withdraw from, and the electronic channel for the receipt
- Confirmation: a second function labelled “Widerruf bestätigen” or equivalent, which actually sends the declaration
- Receipt: an acknowledgement sent to the consumer without delay on a durable medium once they confirm
- Timeliness: a withdrawal sent through the function before the deadline counts as received in time
The fifth point matters for your returns team. A declaration confirmed at 23:58 on the last day is on time even if your email server delivers it to the inbox after midnight, so your system must store the moment the consumer confirmed, not the moment someone read it.
Which fields should the withdrawal form contain?
The statute lists three pieces of information the function must allow the consumer to provide: their name, information identifying the contract or part of the contract, and details of the electronic channel where the receipt should go. In practice that means name, order number (or another identifier) and an email address.
Everything else deserves scrutiny. Asking for a reason, a bank account or photos adds friction to a process the law wants to keep simple, and because the statute names only three items, anything you make mandatory beyond them is a point your lawyer should weigh before launch. Optional fields for a return reason can help your analytics, but keep them clearly optional and consider asking them later in the returns flow instead. Your lawyer should approve the final field list.
Partial withdrawal needs thought. The law speaks of withdrawing from the contract "or a part of it", so if a customer ordered three items and wants to return one, the form should let them say which. The cleanest pattern shows the order lines after the order is identified, with a checkbox per line; the fallback is a free-text field for the items concerned.
Required by the statute
Consumer name; contract identification such as order number; electronic contact channel for the receipt.
Useful but optional
Selection of individual order lines; an optional reason; a preferred refund method where your process allows a choice.
Best left out
Mandatory reasons, mandatory photos, login walls for guest orders, or CAPTCHAs that block assistive technology.
The receipt: what goes into the confirmation, and how to prove it was sent
Once the consumer clicks the confirmation button, they must receive an acknowledgement of receipt without delay on a durable medium. In practice that is an email, and legal commentary on the German law says it should include the content of the withdrawal declaration and the date and time it was received.
We build the receipt as its own message, not as a line in your normal order emails. It repeats the name, order number and selected items, states the timestamp in German time, and carries a unique reference for the withdrawal. The same data is written to your database or order notes, so customer service sees exactly what the customer saw.
Proving it was sent matters if a dispute ever arises. Your system should log the confirmation event, the email hand-off to your mail provider, and any bounce. Use a transactional email service with delivery logs rather than a plain server mail function, and keep the records for as long as your lawyer recommends. A page that only says "thank you" on screen, without a durable copy, does not meet the rule.
Where should the EU withdrawal button appear on the site?
Put it where a customer who wants to withdraw would look, and keep it there. The statute asks for the function to be prominently placed, easy to reach and available throughout the withdrawal period, so hiding it three clicks deep in a help centre is risky.
The common pattern is a clearly labelled link or button in the footer of every page, plus entry points in the customer account's order view and in the order confirmation and shipping emails. The footer entry covers guest customers; the account entry lets logged-in customers start with the order already filled in. On mobile, check the footer entry is not swallowed by a collapsed accordion that nobody opens.
Styling should make the entry look like something you can press, with adequate contrast and a readable size. Accessibility testing belongs in the job: keyboard navigation, focus order, labels a screen reader announces properly. That overlaps with duties many consumer shops now carry under the BFSG, explained on our BFSG requirements page.
Guest checkout vs logged-in customers: how do you identify the order?
Do not force a login. Guest buyers never created an account, so the EU withdrawal button must work from the footer with nothing more than the three statutory data items. Logged-in customers can get a faster route, but the guest path has to exist.
For guests the usual approach is to accept the name, order number and email as entered, then try to match them to an order in the background. If they match, the receipt can list the order lines. If they do not match, perhaps because of a typo in the order number, the declaration must still be accepted, receipted and routed to a person, because rejecting it at the form could block a valid withdrawal.
For logged-in customers, the account's order list shows a "Vertrag widerrufen" action next to each order still within its period. The form opens pre-filled, the customer picks lines and confirms. Keep the public footer route live for logged-in customers too, because someone who forgot a password must still be able to withdraw; the account shortcut is a convenience, never the only door.
EU withdrawal button vs the cancellation button under § 312k BGB
They solve different problems and many shops need both. The withdrawal button ends a new contract during the statutory withdrawal period; the cancellation button, in force in Germany since July 2022 under § 312k BGB, ends an ongoing paid contract such as a subscription.
The cancellation button has its own labels, "Verträge hier kündigen" followed by "jetzt kündigen", and a confirmation page that asks for more data, including the desired end date. A coffee subscription shop therefore needs a cancellation flow for the subscription and an EU withdrawal button for the first order during its withdrawal window. Mixing the two into one ambiguous "manage subscription" screen confuses customers and invites complaints.
Technically they share building blocks: a public form, a confirmation step, a timestamped receipt and a log. We usually build one service with two clearly separated flows, so labels and fields stay exactly as each rule demands. The comparison table further down puts the differences side by side.
How to add an EU withdrawal button to a Shopify store
On Shopify, most merchants use an app from the Shopify App Store, several of which appeared ahead of the deadline, some of them free. An app is a sensible start; the work is choosing one that handles guest orders, partial withdrawals and a proper receipt, and then testing it in your theme.
Things we check on Shopify: the footer entry renders on every template, including custom landing pages; the form works without customer login; the receipt email uses your sender domain and approved German text; the withdrawal is written back to the order as a tag, note or return request; and the app does not load heavy scripts that slow your pages.
When an app clashes with your returns tool or your headless storefront, a theme app extension or a small custom app using Shopify's APIs gives full control. For wider store work, including German checkout settings and legal pages, see our Shopify developer for Germany guide.
How to add the withdrawal button to WooCommerce
WooCommerce shops in Germany usually already run Germanized or German Market for legal features, and both now ship a withdrawal function: vendidero includes it in the free Germanized plugin from version 4.0, and MarketPress added it to German Market in version 3.58, released before 19 June 2026. Start by updating that plugin and switching the feature on; custom code is only needed where your checkout or account pages have been rebuilt.
After activation, test with the theme you actually use. Block-based checkouts, page builders and caching plugins are the usual troublemakers: a cached form can show an expired security token, and an aggressive optimisation plugin can defer the script the form needs. Exclude the withdrawal page from full-page cache and test from a private window.
Where neither plugin fits, a lean custom plugin can register a shortcode or block for the form, store declarations in a custom table with timestamps, send the receipt through your transactional mail service, and add a note to the matching order. Plugin sprawl is a known WordPress risk; our WordPress developer page covers how we keep German shops lean.
How does the EU withdrawal button work in Shopware 6 and Shopware 5?
Shopware added a native withdrawal function in release 6.7.9.0 and, according to Shopware's own announcement, backported it to the 6.6 line, available in the Community Edition and higher plans without extra licence cost. For most Shopware 6 merchants the job is updating to a release with the feature, placing the footer entry and configuring the form page.
The native form covers the standard case: the statutory fields, the two-step confirmation and an automatic receipt, with a notification to the shop operator. What Shopware cannot do for you is decide how your team handles the declaration afterwards, and custom storefronts must place and style the entry point themselves. We connect the notification to order states, flows and your returns process.
Shopware 5 is different. It lost security support in 2024 and gets no native function, so you would rely on a third-party extension or custom code on an unsupported platform. Many merchants are using the deadline as the push to move; our guide to Shopware 5 to 6 migration explains that path.
Building an EU withdrawal button into a custom or headless shop
In a custom shop nothing comes pre-built, so treat it as a small feature with its own data model, API and tests. It is not hard, but it touches the frontend, backend, email and order handling at once, which is where shortcuts cause trouble.
Our usual design: a public page with the two-step form; an API endpoint that validates input, stores the declaration with a server-side timestamp in UTC and an idempotency key, so a double click does not create two withdrawals; a job that sends the receipt through the mail provider and records delivery; and an event that the order system consumes to open a returns case. The timestamp stored is the moment of confirmation, which is what the timeliness rule relies on.
- Store: declaration ID, consumer name, order reference, selected lines, contact channel, confirmation time, IP only if your lawyer wants it
- Never delete a declaration because the order match failed; flag it for review
- Rate-limit the endpoint instead of adding a CAPTCHA that blocks assistive technology
- Show the receipt reference on screen and in the email so customer service can find the record
For storefronts running as apps, the same endpoint serves the mobile client. Custom web apps with us start at US$900.
Do mobile apps need an EU withdrawal button too?
Yes, if consumers conclude contracts in the app. The rule attaches to the online interface through which the contract is concluded, and guidance on Directive (EU) 2023/2673 treats a website and a mobile app alike as such an interface, so a shopping app needs the same two-step flow inside the app, not only on the website.
Build it as a native screen calling the shop's withdrawal API rather than a web view pointing at the footer page. A native screen can pre-fill the order from the logged-in session, show order lines with checkboxes and display the receipt reference, while still letting a user who ordered as a guest on the web enter details by hand.
Place the entry in the order history and in the app's settings or help menu so it is always reachable during the withdrawal period. Test on small screens and with the system font size increased, since a cramped confirmation button is easy to miss. Apps we build in Flutter or React Native start at US$600 and ship through Play Console and App Store Connect in your own developer accounts.
Connecting withdrawals to returns, refunds and customer service
The button is only the front door. What makes the EU withdrawal button useful for your business is what happens after a declaration arrives: the right order is flagged, the returns label goes out, and the refund is issued within the time German law allows.
§ 357 BGB generally requires payments received to be returned within 14 days, so the clock starts with the withdrawal, not when a clerk opens the inbox. We route each confirmed declaration into your existing tools: a tag or status on the order in Shopify, WooCommerce or Shopware, a ticket in your help desk, a returns case in your returns app, or a document in your ERP. Customer service gets one notification with everything needed to act.
A small dashboard showing open withdrawals by age helps a team spot anything stuck. If you already automate customer messages, the withdrawal status can also feed a WhatsApp or email update; see our guide on WhatsApp Business API and GDPR before messaging customers there.
Plugin, app or custom build: which route fits your shop?
Use the platform's native feature or a well-maintained app when your shop runs a standard theme and returns are handled manually. Build custom when your storefront is headless, your returns run through an ERP, or you sell through a mobile app. Most shops land in the first group, and saying so is part of an honest quote.
Native or plugin is enough when
You are on a current Shopware 6 release, WooCommerce with Germanized or German Market, or Shopify with a standard theme, and you can process withdrawals from an email notification.
Add custom integration when
Withdrawals must create returns cases, credit notes or ERP documents automatically, or you need reporting across channels.
Build fully custom when
Your shop is headless or bespoke, you sell in an app, or several brands and storefronts share one backend.
Whichever route you choose, the testing checklist below applies. A plugin that is installed but never tested with a guest order gives false comfort.
What is the risk of getting the EU withdrawal button wrong?
The main practical risk in Germany is a cease-and-desist letter (Abmahnung) from a competitor or an association, which can bring legal costs and a demand to sign a declaration with a contractual penalty. Consumer-law rules that are easy to check from outside, like a missing or broken button, tend to attract such letters.
There is also a customer-relations risk. A declaration lost in a broken form still counts if the customer can show they sent it, and a refund paid late because nobody saw the notification damages trust and reviews. Visible, tested flows reduce both risks.
We build and test; we do not decide what your legal texts say or whether an exclusion applies. Your Widerrufsbelehrung should mention the new function in the wording your lawyer or legal-text provider recommends, and your lawyer should sign off on labels and fields. Nothing on this page is legal advice.
EU withdrawal button QA checklist before you call it done
Run these checks on the live shop, on a phone and a desktop, with at least one real guest order and one account order. Keep screenshots and the receipt emails as evidence of the test.
- Entry labelled “Vertrag widerrufen” (or agreed equivalent) is visible on every page type, including checkout success and mobile footer
- Form opens without login and asks for name, order identification and email
- Second step is labelled “Widerruf bestätigen” (or agreed equivalent) and sends the declaration
- Receipt email arrives within minutes, with content, date and time, and a reference
- Wrong order number: declaration still accepted, receipted and flagged for review
- Partial withdrawal: selected lines appear in the receipt and on the order
- Double click creates one withdrawal, not two
- Keyboard-only and screen-reader run completes the flow
- Notification reaches the right team and the refund deadline is visible
Worked example: a hypothetical Leipzig sneaker shop with an app
This scenario is made up to show the steps, not a client project. Imagine a sneaker retailer in Leipzig selling through WooCommerce with Germanized, plus a small Flutter app for loyal customers. Most orders are guest checkouts; returns are processed in a returns tool connected to the warehouse.
Week one would start with an audit of the current state: which Germanized version runs, whether the feature is active, how the footer behaves on mobile, and whether the caching plugin interferes. We would then enable the native function, adjust the footer and account entries, and route the notification into the returns tool through its API, creating a returns case with the selected lines.
In the app, a native withdrawal screen would call a small endpoint added to the shop, reusing the same storage and receipt email so there is one source of truth. Testing covers guest orders, typo'd order numbers, partial returns and a screen-reader run. The owner's lawyer approves the German labels and receipt text before the release goes live.
Hiring a remote team in India for this from Germany: how it works
A withdrawal-button job is small enough to judge a new developer by, which makes it a sensible first project with a remote team. Here is how it runs with us from a German shop's point of view.
You send the shop URL and platform on WhatsApp or email. We run a quick outside check and reply with questions; after a short video call in your morning, which is our early afternoon since India is three and a half hours ahead of German summer time, you get an itemised quote in about two working days. Once you approve it in writing, you add us as staff users or collaborators on your own shop, repository and email provider, so nothing lives in our accounts.
Work happens on a staging copy where possible, then goes live at a time you choose, usually outside your busiest hours. The team works in English and Hindi, so German labels and receipt wording come from you or your legal-text provider. Payment is in USD or EUR by Wise or bank wire, invoiced from India. Contract details are in our terms or your written quote.