The withdrawal button becomes mandatory on 19 June 2026 for every B2C online shop in Germany. EU Directive 2023/2673 (BMJV) requires a two-step digital withdrawal mechanism whose technical implementation goes far beyond simply adding a button to the footer. Violations can trigger fines of up to 4% of annual revenue (IT-Recht Kanzlei) — and 18% of online retailers already received a warning letter in 2024, up 50% year-over-year (Händlerbund Abmahnstudie 2025). This guide covers the concrete technical implementation in Shopware 6, the permitted label wording, the allowed data queries and the requirements for receipt confirmation.
What applies from 19 June 2026
EU Directive 2023/2673 was transposed into German law by the implementing act of 3 September 2025 (BMJV 47/2025). The transposition deadline for member states ended on 19 December 2025; for retailers the obligation starts six months later on 19 June 2026. From that date, every B2C shop must provide a functional withdrawal button that makes withdrawal considerably easier than filling a form or writing an e-mail. Further legal background is covered in our article on the Withdrawal Button Requirement 2026.
The German e-commerce market grew to 83.1 billion euros in 2025, up 3.2% year-over-year (BEVH); in Q3 2025 alone 17.96 billion euros were turned over — with marketplaces reaching a share of 54.4% (BEVH). The sheer size of the market means the new requirement affects tens of thousands of retailers. At the same time, surveys show that 93% of shoppers expect stronger marketplace control (vzbv) — introducing the withdrawal button is therefore also a trust signal for customers.
The withdrawal period of 14 days remains unchanged; for financial services it can extend to 12 months and 14 days (BMJV). Important: the button does not replace the obligation to provide the withdrawal instructions, it merely offers an additional, low-barrier way to exercise the right. Retailers must offer both channels in parallel — classical withdrawal by text and digital withdrawal by button.
The 2025 Abmahnstudie by Händlerbund shows: individual warning letters in September 2025 ranged from 300 to 3,441.60 euros. 43% of affected retailers paid up to 500 euros, 31% between 500 and 2,000 euros (Händlerbund). A missing or incorrectly implemented withdrawal button will, from the deadline onwards, become a comparable standard reason for warning letters.
Button anatomy: two-step flow
The legislator mandates a two-step process: step 1 is the actual button with the click, step 2 is a confirmation form in which identification data is entered and the withdrawal is submitted. Only this way can it be ensured that the customer triggers the withdrawal deliberately and that the retailer can clearly assign the order. A single-step implementation — a button that triggers the withdrawal directly without data collection — is inadmissible because no assignment would be possible.
Technically, the flow can be realized via a dedicated route (e.g. /withdrawal) with a Twig template that first shows the button and then redirects to the form step via POST request. Alternatively, a modal dialog can be opened via JavaScript, as long as the dialog also works as a fallback via a normal page when JS is disabled — accessibility is mandatory anyway under the BFSG.
Exact label wording
The button label is legally prescribed and leaves no room for creative variants. Permitted texts must unambiguously express the intent to withdraw — neutral phrases such as "Contact" or "Send message" are expressly inadmissible because they obscure the purpose.
| Element | Permitted | Inadmissible |
|---|---|---|
| Step 1 button | Withdraw contract | Contact us |
| Step 2 button | Confirm withdrawal | Send |
| Alternative step 1 | Declare withdrawal | Send message |
| Alternative step 2 | Trigger withdrawal now | Submit |
| Page title | Declare withdrawal | Return |
| Footer link text | Withdraw contract | Returns |
The wording "Withdraw contract" is the legally preferred default for the primary button. For the confirmation button, "Confirm withdrawal" is the recommended phrasing. Anyone who has already engaged a Shopware agency with the implementation should deposit these labels in the snippet set and translate them appropriately — for German shops as "Vertrag widerrufen" and "Widerruf bestätigen".
Placement in the shop
The button must be placed permanently, visibly and with high contrast. Burying it inside a nested help section does not suffice. Two placements are recommended: prominently in the footer on every page, plus in the customer account under "My orders". Particularly important: the button must also be reachable for non-logged-in visitors (guest orders) — placement exclusively behind the customer account login is inadmissible.
- Position in the footer of every page, above or next to imprint/terms
- Additionally in the header as a link or in meta navigation
- In the customer account linked directly to every withdrawable order
- Also reachable for guest orders via a separate page without login
- High contrast designed per WCAG 2.1 AA (min. 4.5:1 for body text)
- Fully usable on mobile, tap target at least 44x44 px
- Not hidden behind multiple clicks or accordions
- Functional even with JavaScript disabled
If you follow a clean checkout optimization approach, deliberately do NOT place the button inside the active order process. It belongs in the post-purchase phase (customer account, footer, order confirmation e-mail) — not in the phase where purchase decisions are still being made.
Data you are allowed to request
The law strictly limits data collection in the withdrawal form to the minimum needed for clear assignment. Querying withdrawal reasons, satisfaction scales or alternative return options during the withdrawal process is inadmissible and would put you at risk of warning letters.
Name
First and last name for identification of the contracting party - mandatory field
Order number
Unique reference to the order to be withdrawn - mandatory field
E-mail address
Address for the automatic receipt confirmation - mandatory field
These three fields are sufficient. Optionally you may offer a selection of the specific item to be withdrawn if partial withdrawal should be supported — for instance with multiple line items in one order. Under no circumstances may you request: reasons for withdrawal, a request for comment before withdrawal, questions about payment method or alternative offers such as vouchers. A return reason survey may be offered after the completed withdrawal on a voluntary basis — our guide on returns management shows how to collect that data without legal risk.
Technical integration in Shopware 6
Shopware has announced that it will deliver the withdrawal button implementation with version 6.7.9.0 in April 2026 (Shopware). If you need a solution earlier or cannot upgrade to 6.7.9, you can implement the feature as a custom plugin. The following minimal implementation shows the controller for the second step (form submission):
<?php declare(strict_types=1);
namespace Xictron\Withdrawal\Storefront\Controller;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Storefront\Controller\StorefrontController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* @RouteScope(scopes={"storefront"})
*/
class WithdrawalController extends StorefrontController
{
public function __construct(
private readonly EntityRepository $withdrawalRepository,
private readonly WithdrawalMailService $mailService
) {}
/**
* @Route("/withdrawal", name="frontend.withdrawal.form", methods={"GET"})
*/
public function form(Request $request): Response
{
return $this->renderStorefront('@XictronWithdrawal/storefront/page/withdrawal/index.html.twig');
}
/**
* @Route("/withdrawal/submit", name="frontend.withdrawal.submit", methods={"POST"})
*/
public function submit(Request $request, Context $context): Response
{
$name = trim((string) $request->request->get('name'));
$orderNumber = trim((string) $request->request->get('orderNumber'));
$email = filter_var($request->request->get('email'), FILTER_VALIDATE_EMAIL);
if (!$name || !$orderNumber || !$email) {
$this->addFlash('danger', 'Please fill in all mandatory fields.');
return $this->redirectToRoute('frontend.withdrawal.form');
}
$reference = 'WDR-' . date('Y') . '-' . strtoupper(substr(Uuid::randomHex(), 0, 5));
$this->withdrawalRepository->create([[
'id' => Uuid::randomHex(),
'reference' => $reference,
'customerName' => $name,
'orderNumber' => $orderNumber,
'email' => $email,
'receivedAt' => new \DateTimeImmutable(),
]], $context);
$this->mailService->sendConfirmation($email, $name, $orderNumber, $reference);
$this->mailService->notifyMerchant($name, $orderNumber, $reference);
return $this->redirectToRoute('frontend.withdrawal.success', ['ref' => $reference]);
}
}The database entity withdrawal stores the incoming data with a timestamp for evidence. Additionally, a trigger must be set up in the Shopware Flow Builder that initiates internal processes when a new withdrawal arrives — creating a return in the ERP, pausing pending shipping orders and informing the customer service team. For the form view itself, a slim Twig template with three input fields is enough. Shops running a custom frontend with Vue or Nuxt implement the flow as a separate SPA route with a REST endpoint.
Automating receipt confirmation
The retailer is obliged to confirm receipt of the withdrawal without undue delay on a durable medium. In practice that means: within a few minutes of form submission, an e-mail must go to the customer documenting the receipt. The confirmation must contain at least: the customer's name, order number, timestamp of receipt (date and time), a unique reference ID and brief information about the next steps.
Technically, a mail template in the Shopware mail system with placeholders {{ customerName }}, {{ orderNumber }}, {{ receivedAt|format_datetime }} and {{ reference }} is recommended. To avoid delays, sending should not happen synchronously in the request handler but asynchronously via the Shopware message queue in a worker process. This keeps the customer's response time below 500 ms even when the SMTP server is currently under load.
In parallel with the customer mail, an internal notification system should be set up: a message to the customer service team, optionally a ticket in the ticketing system or a push notification to logistics. The retailer's obligation of proof relates to the receipt confirmation — it must be verifiable when and how the withdrawal was received. A detailed log entry with IP address and user agent (without personal processing beyond order assignment) protects in case of dispute.
Exceptions: when the button is not needed
Not every shop needs a withdrawal button. The obligation only applies to contracts for which a statutory right of withdrawal exists. In the following constellations the button obligation is fully or partially waived:
- Pure B2B shops without end-customer sales — no right of withdrawal, no button needed
- Sale of personalized goods (e.g. engraving, individual configuration)
- Easily perishable food with limited shelf life
- Sealed media (CDs, DVDs, software) after the seal has been removed
- Digital content on a non-physical medium once execution has begun
- Financial services with their own withdrawal rules (extended deadlines)
- Goods that have been inseparably combined with other items
- Contracts concluded at public auctions
With mixed assortments (B2C + B2B in one shop, or standard items + personalized items), the button must generally be provided. In our guide on customer-specific assortments in B2B shops we show how customer groups can be cleanly separated so that the obligation only applies to actually affected B2C orders.
Warning letter risk and typical mistakes
The 2025 Abmahnstudie by Händlerbund shows: competition law accounts for 42% of all warning letters, followed by the Packaging Act with 40% (Händlerbund). 27% of retailers perceive an increase in warning letters, 79% feel growing competitive pressure (Händlerbund 2025). In total, Händlerbund has processed over 26,000 warning letters (Händlerbund). With the deadline of 19 June 2026, the pattern will extend to the withdrawal button — experience shows that warning letter waves start within days of such deadlines.
| Typical mistake | Correct implementation |
|---|---|
| Only a "Contact" link in the footer | Dedicated button "Withdraw contract" |
| Button only in customer account | Also in footer and for guests |
| Single-step process without form | Two-step: click + confirmation |
| Reason for withdrawal is requested | Only name, order number, e-mail |
| No receipt confirmation by mail | Automatic confirmation with reference |
| Button hidden behind login | Accessible without login as well |
| Color contrast too low | WCAG 2.1 AA, min. 4.5:1 |
| Mail sent only after 24h | Sent without undue delay via worker queue |
It is particularly expensive for smaller retailers: according to the University of Bamberg, return costs for small retailers average 17.70 euros per return, while large retailers bear only 5.18 euros per return (University of Bamberg). An additional burden from warning letters therefore hits smaller businesses disproportionately. Clean consulting at the initial implementation is always cheaper than a later fix after a warning letter has already been issued.
Project plan until 19 June 2026
- By 30 April 2026: Stocktaking — which order types exist, which customer groups, which exceptions apply, check Shopware version status
- By 15 May 2026: Technical draft — define route, template, controller, data model, mail templates, Flow Builder integration
- By 31 May 2026: Development and code review — develop plugin or schedule Shopware 6.7.9.0 update, adapt storefront template
- By 10 June 2026: End-to-end test in staging — form flow, confirmation mail, internal notification, Flow trigger, mobile, accessibility
- By 15 June 2026: Legal review by specialist lawyer, label check, privacy review, update of privacy policy
- By 18 June 2026: Deployment to production, cache warm-up, monitoring of error logs
- From 19 June 2026: Live monitoring — for the first 48 hours watch logs and mail queue closely, prepare support team for inquiries
Anyone starting now still has sufficient buffer. Depending on shop complexity, implementation typically takes 3 to 8 working days of pure development work — plus testing and legal review. Those relying on custom programming or running a headless frontend should plan 2-3 weeks, because the API interfaces must be designed along.
This article is based on data from: EU Directive 2023/2673 (European Union, transposition by 19 December 2025); BMJV press release 47/2025 (German Implementing Act of 3 September 2025, withdrawal deadlines); IT-Recht Kanzlei (fines up to 4% of annual revenue); Händlerbund Abmahnstudie 2025 (18% warning letter rate 2024, +50% YoY, individual letters 300 to 3,441.60 euros, 43% below 500 euros, 31% between 500 and 2,000 euros, competition law 42%, Packaging Act 40%, 27% perceive more warning letters, 79% competitive pressure, 26,000+ processed warning letters); vzbv (93% of shoppers expect marketplace control); University of Bamberg returns research (fashion return rate 26-50%, per-item 70-80%, alpha return rate fashion invoice purchase 55.65%, return costs 15.18 euros comprising 7.93 euros process cost and 7.25 euros value loss, small retailers 17.70 euros vs. large 5.18 euros per return, 286 million return packages per year at a 28.6% rate); Bitkom (16-29-year-olds return 15%, 65+ only 7%, top return reasons: size 67%, damage 56%, dislike 50%); BEVH (German e-commerce 2025 83.1 billion euros, +3.2%, Q3 2025 17.96 billion euros, marketplaces 54.4%); Shopware (release 6.7.9.0 with withdrawal button functionality in April 2026). The figures mentioned may vary over time.
From 19 June 2026, warning letters from competitors and consumer protection associations are to be expected. According to the Händlerbund Abmahnstudie 2025, individual warning letters in September 2025 ranged from 300 to 3,441.60 euros. In addition, fines of up to 4% of annual revenue are possible (IT-Recht Kanzlei). We recommend completing the implementation by early June 2026 to allow buffer for tests and legal review. Our Shopware agency supports on-time implementation.
The law limits the request to the minimum: name, order number and e-mail address. Asking for the withdrawal reason or alternative offers during the withdrawal process is inadmissible. Typically a form with exactly three input fields suffices. Optionally, selecting individual positions to be withdrawn can be added if partial withdrawal should be offered.
Yes. Placement exclusively behind the customer account login is inadmissible because guest buyers would be disadvantaged. The withdrawal button must be permanently publicly reachable — typically prominently in the footer on every page. In the form itself the customer then identifies themselves via name, order number and e-mail address.
The law mandates confirmation without undue delay on a durable medium. In practice: within a few minutes of form submission, an e-mail must arrive at the customer. Technically, sending should happen asynchronously via the Shopware message queue so the response time for the customer remains short. The confirmation must contain name, order number, time of receipt and a reference ID.
Shopware has announced delivery with version 6.7.9.0 in April 2026 (Shopware). Anyone not using this version or needing individual adjustments — for headless setups or specific customer group logic — must implement the feature as a custom plugin. Typically such an integration including tests can be realized in 3 to 8 working days. We recommend early consulting on the technical architecture.
Pure B2B shops without end-customer sales are not affected because no statutory right of withdrawal exists for them. With mixed assortments (B2C + B2B in parallel), however, the obligation applies because the shop enables B2C orders. In our article on customer-specific assortments in B2B shops we show how customer groups can be cleanly separated so the obligation applies specifically to the affected orders.