Skip to main content

MageMe EU Withdrawal | Eligibility Rules

This page explains how the module decides whether a customer can withdraw from a given order: the 14-day clock (Art. 9(2)) and the Article 16 exclusion presets. Read this before enabling any of the four preset_* toggles in admin — misconfigured presets unlawfully deny valid withdrawals, which is a separate compliance violation.

For the regulatory context and merchant responsibilities, see Legal & Compliance. For digital content waivers (Art. 16(m)), see Digital Content Waiver.

The 14-day clock

14-day withdrawal period timeline

Article 9(2)(b) of Directive 2011/83/EU sets the standard withdrawal period at 14 calendar days from the day the consumer (or a third party other than the carrier indicated by the consumer) takes physical possession of the goods.

How the module anchors the period

The module reads Stores → Configuration → MageMe Extensions → EU Withdrawal → Withdrawal Window → Delivery Confirmation Statuses — a multi-select of Magento order statuses. The anchor is the moment the order first transitions into any of the configured statuses; the period counts from that anchor.

The Magento default workflow uses Complete for fully-shipped orders. Stores that distinguish shipped and delivered (e.g. a carrier-integration status update) should select the status that actually represents physical possession by the customer — not the moment the parcel leaves the warehouse.

warning

For orders with multiple shipments — for example, a backorder split across two boxes a week apart — the Directive specifies the last item delivered as the anchor (Art. 9(2)(b)(ii)). The module's current implementation uses the first transition into a configured delivery status, which matches the standard Magento Complete workflow but may be off for stores with custom per-shipment statuses. If you run split shipments with per-shipment status updates, configure only the final status (the one applied when the last shipment is delivered).

What "eligible" means in the UI

When a logged-in customer visits /withdraw-contract/, every order they own is evaluated:

StateWhat the customer sees
Anchor in the futureOrder not listed (delivery has not happened yet)
Within 14 days of anchorYou can return this order until <date> — order is selectable
Beyond 14 daysOutside the 14-day period — order is greyed out
Items already in an open withdrawalAlready requested per item — quantity available reduced
All items already approved or deniedFully processed — order is greyed out

The customer always sees why an order or item is ineligible. The same explanation is logged to the audit trail.

Extending the period beyond 14 days

You can configure a period longer than 14 days in Withdrawal Window → Withdrawal Period (Days) (range 14-3650). Common reasons: a customer-trust commitment (30 days, no questions asked), or a national variation that strengthens the floor. Anything shorter than 14 days is illegal under Art. 9(2) and the admin field rejects values below 14.

If you fail to disclose the right of withdrawal to the customer before contract conclusion, Art. 10 extends the period by up to 12 additional months. The free tier does not detect this automatically — Art. 10 detection is a Pro feature (mageme/module-eu-withdrawal-pro).

Article 16 exclusion presets

Article 16 lists categories of contract that the right of withdrawal does not apply to, with strict conditions. The module ships four preset toggles, each tied to a boolean product attribute. All four presets are off by default — the free tier ships permissive (everything is withdrawable) and the merchant opts items out by enabling the relevant preset and tagging the products that legitimately qualify.

PresetLegal basisRequired attributeApplies when
Custom-Made GoodsArt. 16(c)is_custom_made = 1Product is made to consumer specifications or clearly personalised (engraved jewellery, made-to-measure clothing, configured-to-order furniture).
Perishable GoodsArt. 16(d)is_perishable = 1Product can deteriorate or expire rapidly (fresh food, cut flowers, short-shelf-life pharmaceuticals).
Sealed Hygiene / HealthArt. 16(e)is_sealed_hygiene = 1Cosmetics, intimate apparel, sealed medical supplies — exclusion applies only if the seal has been broken after delivery.
Sealed A/V / SoftwareArt. 16(i)is_sealed_av = 1Sealed audio, video, or computer-software media — exclusion applies only if the seal has been broken after delivery. Does not cover streaming or digital downloads — use Art. 16(m).

Toggles live in Stores → Configuration → MageMe Extensions → EU Withdrawal → Eligibility Rules.

warning

Each preset is a denial of a fundamental consumer right. Enabling a preset for products that do not genuinely qualify is itself a violation of the Directive. National regulators (vzbv in DE, ACM in NL, DGCCRF in FR, KKV in FI) actively monitor for over-broad exclusion claims, and class-action exposure (France, action de groupe) follows. Have consumer-law counsel review your catalogue tagging before turning a preset on in production.

Seal-break semantics for Art. 16(e) and 16(i)

The Directive permits the exclusion only if the seal has been broken after delivery. A sealed, unopened return remains fully eligible for withdrawal.

The free tier flags products with the relevant attribute as excluded in the storefront UI — the customer sees an Excluded under Art. 16(e) reason inline. The merchant verifies the seal-break condition at the return-inspection stage, outside the module. The Pro tier adds a return-inspection workflow to record seal status explicitly per request.

Setting up product attributes

The required attributes are created automatically when the module is installed. The setup patch MageMe\EUWithdrawal\Setup\Patch\Data\AddWithdrawalProductAttributes adds five boolean attributes to all attribute sets, grouped under EU Withdrawal Compliance:

Attribute codeFrontend labelUsed by
is_custom_madeCustom-made / personalised (Art. 16(c))Custom-Made preset
is_perishablePerishable (Art. 16(d))Perishable preset
is_sealed_hygieneSealed hygiene / health (Art. 16(e))Sealed Hygiene preset
is_sealed_avSealed A/V / software (Art. 16(i))Sealed A/V preset
is_digital_contentDigital content (Art. 16(m))Digital Content Waiver

If the attributes are missing on an existing store, re-run setup:

php bin/magento setup:upgrade
php bin/magento cache:flush

Tagging products individually

  1. Open Catalog → Products → <product>.
  2. Scroll to the EU Withdrawal Compliance tab.
  3. Set the relevant attribute to Yes.
  4. Save.

Tagging products in bulk

For more than a handful of SKUs, use Magento's standard import:

  1. Export the products you want to tag: System → Data Transfer → Export with the Products entity. Choose CSV.

  2. In the resulting file, add a column for the attribute (e.g. is_perishable) and set the value to 1 for qualifying SKUs.

  3. Import the updated CSV: System → Data Transfer → Import → Products → Add/Update. Make sure Validation strategy is Stop on Error for the first run.

  4. Reindex and flush cache:

    php bin/magento indexer:reindex
    php bin/magento cache:flush

Filtering tagged products

To audit how many products are tagged with a given attribute, open Catalog → Products, click Filters, and add is_perishable = Yes (or similar). The grid shows the matching SKUs — review the list before enabling the preset in admin.

How the engine combines period and presets

When a customer attempts to withdraw, the eligibility engine (MageMe\EUWithdrawal\Model\EligibilityEngine) evaluates each order item independently. An item is eligible if:

  1. The order's delivery anchor exists and the current time is within the configured period.
  2. None of the enabled presets disqualify the item (Art. 16(c)/(d)/(e)/(i)).
  3. The item is not already part of a non-terminal withdrawal request.

The engine returns one of:

  • eligible — the item appears in the form with selectable quantity.
  • ineligible with a reason code (outside_period, excluded_custom_made, excluded_perishable, excluded_sealed_hygiene, excluded_sealed_av, already_requested, fully_processed).

The reason is shown to the customer inline and recorded in the eligibility snapshot stored with the request. The snapshot is what makes the decision auditable later: even if the merchant changes the preset toggles between submission and dispute, the record reflects the rule set that applied at the time of the customer's request.

→ For Article 16(m) digital content — a separate flow with checkout-time waiver and per-locale text — see Digital Content Waiver.