WP Manifestindependent plugin directory
manifest / privacy / trece-euwd-compliance

Withdrawal EU Law Compliance

Wordpress and Woocommerce EU Withdrawal Compliance, this plugin allow to adapt your web to your needs to comply the law.

★ 3stars
1.6.0latest · 3mo ago

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/trecenode/trece-euwd-compliance/archive/refs/heads/main.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Withdrawal EU Law Wordpress Plugin

Requires: PHP 7.4+ · WordPress 6.0+ · WooCommerce 7.0+ (optional)

Comprehensive WordPress plugin implementing EU consumer withdrawal rights under Directive 2011/83/EU (as amended by Directive (EU) 2019/2161) and upcoming June 2026 requirements. Provides a mandatory "withdraw from contract" button, two-step confirmation process, SHA-256 receipt hashing, Annex I.B model withdrawal form, checkout consent checkboxes for digital content (Art. 16(m)) and services (Art. 14(4)(a)), product exclusion notices under Art. 16, GDPR-compliant data handling, and a full admin management panel.


Table of Contents


Requirements

Dependency Minimum Version Notes
PHP 7.4+ 8.0+ recommended
WordPress 6.0+
WooCommerce 7.0+ Optional — required for checkout integration, order linking, and product exclusions

The plugin operates in two modes:

  • WooCommerce mode — Full integration with checkout consent checkboxes, order linking, product exclusion notices, My Account tab, and HPOS compatibility.
  • Standalone mode — Works without WooCommerce for simple sites that only need the withdrawal form and admin management.

Installation

  1. Upload the plugin folder trece-euwd-compliance to /wp-content/plugins/, or install via Plugins → Add New → Upload Plugin using the ZIP file.
  2. Activate the plugin through the Plugins menu in WordPress.
  3. Navigate to Withdrawals → Settings in the WordPress admin.
  4. Configure the required settings:
    • Set your trader information (company name, address, email).
    • Select or create a page for the withdrawal form.
    • Review the withdrawal deadline (default: 14 days).
    • Configure email notification recipients.
  5. Add the form to your chosen page using the [trece_withdrawal_form] shortcode.
  6. Add the withdrawal link to relevant locations using the [trece_withdrawal_link] shortcode or the automatic placement options in settings.

Configuration

All settings are available under Withdrawals → Settings in the WordPress admin panel.

General Settings

Setting Description Default
Withdrawal Deadline Number of days from delivery within which customers may exercise withdrawal rights. EU directive mandates a minimum of 14 days. 14
Deadline Basis Whether the advisory deadline is counted from the order date or the WooCommerce completion date. Order date
Grace Days Extra days added on top of the deadline before a request is flagged. 0
Deadline Enforcement Advisory flags late-looking requests for review but never blocks them; Strict blocks them. See below. Advisory
Form Introduction Optional plain text shown above the public form. empty
Consumer Self-Declaration Shows a required checkbox where the buyer declares they purchased as a consumer, stored with the request as proof. No
Consumer Self-Declaration Text Wording of that checkbox. Empty falls back to the bundled default. empty
Anti-Bot Check (ALTCHA) Adds a self-hosted ALTCHA proof-of-work checkbox to the public form. See below. No
Accept Unmatched Requests Register requests whose order/email pair matches no order as Unverified for manual review, instead of rejecting them upfront. No
Enable Standalone Mode Allow submissions without a WooCommerce order number. No

Why the deadline is advisory by default

The 14-day withdrawal period legally runs from delivery (or, for digital content, from the start of the download) — a date the shop cannot detect automatically. Rejecting a request based on the order or completion date would turn away customers who are still within their legal window, so Advisory mode registers the request and flags it in the request list, the detail screen, the admin notification email and the CSV export, leaving the decision to the merchant after checking the real delivery date.

Switch to Strict only when your start date is reliable: services and digital content (where the period runs from the contract date), shop pickup, or predictable carriers. In Strict mode the My Account button is hidden and new requests are blocked once the deadline plus grace days has passed.

Anti-bot check (ALTCHA)

The public form always ships a hidden honeypot field. When that is not enough — a withdrawal page that starts collecting scripted submissions — the Anti-Bot Check setting adds an ALTCHA checkbox above the submit button.

It is fully self-hosted:

  • The challenge is minted by the site and signed with an HMAC key generated on first use and stored in the trece_wdeu_altcha_key option. Nothing is sent to a third-party service, so the check adds no processor to your GDPR record and sets no cookie.
  • The widget is bundled with the plugin (assets/js/altcha.min.js), not fetched from a CDN, and served only on pages that render the form.
  • The browser solves a proof-of-work puzzle; the server re-derives the challenge from the answer and re-checks its own signature before accepting the request.
  • A solved challenge expires after 15 minutes and is accepted once, so a single solution cannot be replayed across a batch of submissions.

It is off by default and should stay off unless you have a spam problem: the widget requires JavaScript, and the public form works without it otherwise.

Use trece_wdeu_altcha_enabled to switch it on or off in code.

Permissions

Withdrawal requests store personal data (name, email, IP), so the request screens are gated by a dedicated manage_trece_withdrawals capability rather than manage_options.

Setting Description Default
Roles That Manage Requests Which roles, besides the administrator, may view and manage requests. none

The administrator always has access and cannot be unticked. Plugin configuration (the Settings screen itself) stays administrator-only. Sites upgrading from an earlier version keep Shop manager access so nothing breaks; new installs start administrator-only.

Email Notifications

Setting Description Default
Admin Notification Email Email address(es) that receive notifications on new withdrawal requests. Comma-separated. Site admin email
Send Customer Confirmation Whether to email the customer a confirmation with SHA-256 receipt hash upon successful submission. Yes
Email "From" Name Name used in the From header of outgoing emails. Site name
Email "From" Address Address used in the From header of outgoing emails. Site admin email
Accepted / Rejected / Completed Email Text Body text sent to the customer on each status transition. Empty falls back to the bundled default. empty

Form Page

Setting Description
Withdrawal Form Page Select the WordPress page where the [trece_withdrawal_form] shortcode is placed. Used for generating links automatically.

Order Number Requirement

Setting Description Default
Require Order Number When enabled, the withdrawal form requires a valid order number. Disable for standalone mode. Yes
Order Number Validation Validate that the submitted order number corresponds to an existing WooCommerce order. Yes

Privacy Policy

Setting Description
Privacy Policy Page Select the page containing your privacy policy. A link is displayed on the withdrawal form.
Consent Text Text displayed alongside the privacy policy checkbox on the form.

Trader Information

These fields populate the Annex I.B model withdrawal form as required by the directive.

Setting Description
Show Annex I.B Model Form Render the model form below the public form, with a printable view. On by default.
Company Name Legal name of the trader/business.
Address Full postal address of the trader.
Email Address Contact email address for withdrawal communications.
Phone Number Optional contact phone number.
Fax Number Optional fax number (still referenced in some EU member state implementations).

The printable view lives at the withdrawal page URL with ?print=annex. It renders outside the theme, answers only on that page, and sends noindex,nofollow plus no-cache headers — a standalone document is exactly the kind of thin page that should never reach an index.

Checkout Consents

These settings control the consent checkboxes displayed during WooCommerce checkout. They are only active when WooCommerce is installed and active.

Setting Description Default
Enable Digital Content Consent Display a checkbox for Art. 16(m) digital content consent (loss of right of withdrawal upon performance). Yes
Digital Content Consent Text The label text for the digital content consent checkbox. See plugin defaults
Enable Service Consent Display a checkbox for Art. 14(4)(a) service consent (acknowledgement that withdrawal right is lost after full performance). Yes
Service Consent Text The label text for the service consent checkbox. See plugin defaults
Require the Service Consent to Place the Order Makes the Art. 14(4)(a) checkbox mandatory. Off by default: asking for the service to start inside the withdrawal period is the customer's choice. Turn it on when the service always starts there (live sessions, bookings, dated appointments), where placing the order without that request makes no sense. No

A consent switched off is not rendered, not required and not persisted — on the block checkout it is not even registered in the Store API schema, so it cannot resurface as a stale field.

Where the checkboxes render, whether they apply to a given cart, and whether each one blocks the order are all filterable — see trece_wdeu_consent_hook, trece_wdeu_consent_applies and trece_wdeu_consent_is_required.

Both are validated on woocommerce_after_checkout_validation rather than the earlier woocommerce_checkout_process. Express gateways that render their own button (PayPal Payments and similar) run their pre-payment check on that hook only, so a missing consent blocks the payment window from opening instead of rejecting the order after the customer has already been through it.

Per-Product Withdrawal Status

Every WooCommerce product has a Withdrawal Status select on the General tab of the product edit screen (_trece_wdeu_withdrawal_status). It tells the plugin how that specific product is treated under the right of withdrawal — whether the customer keeps the full 14-day right, whether a checkout consent checkbox is required, and whether an exclusion notice is shown on the product page.

Option (value) Legal basis Effect in the store
Standard (14-day right of withdrawal) (standard) Default withdrawal right under Directive 2011/83/EU — the customer has 14 days to withdraw without giving any reason. No consent checkbox at checkout, no exclusion notice on the product page. The customer keeps the full right of withdrawal and can use [trece_withdrawal_form] / "Withdraw from contract" as normal.
Digital content (Art. 16(m)) (digital_content) Digital content not supplied on a physical medium loses its right of withdrawal once the customer explicitly consents to immediate performance before the order is placed (Art. 16(m)). A mandatory consent checkbox is shown at checkout ("I consent to the immediate supply of digital content and acknowledge that I will lose my right of withdrawal."). The order cannot be placed without checking it. The consent (with timestamp, IP, and user agent) is stored as evidence. If the customer accepts, the right of withdrawal is lost for that item; declining is not possible for this product type. No notice is shown on the product page — the checkout checkbox is the only place this is communicated.
Service started early (Art. 14(4)(a)) (service_early) A service the customer asks to start during the withdrawal period: once fully performed, the right of withdrawal is lost, and if withdrawn before completion the customer owes the proportionate cost of the service already provided (Art. 14(4)(a)). An optional consent checkbox is shown at checkout ("I request that the service begins during the withdrawal period and acknowledge that, should I withdraw, I will be liable for the proportionate cost of the service already provided."). It does not block placing the order. If accepted, the customer acknowledges the proportionate-cost liability and loses the right of withdrawal once the service is fully performed. If declined, the customer keeps the right of withdrawal for that item, and eligibility is recalculated accordingly in the My Account withdrawal tab.
Dated accommodation, transport, car rental, catering or leisure (Art. 16(l)) (dated_services) Services tied to a specific date or period of performance are excluded outright by Art. 16(l) — hotel nights, transport of goods, vehicle rental, catering, concert or event tickets. No consent checkbox is shown: the exclusion does not depend on anything the customer accepts. If Show Exclusion Notice on Product Page is enabled, the product page displays the Art. 16(l) notice. The item is always classified as excluded, on the form and in My Account.
Other Article 16 exception (other_article16) Catch-all for other exclusions under Art. 16 of the directive (e.g. sealed goods that cannot be returned for hygiene reasons once unsealed, custom or personalised goods, etc.). No consent checkbox is shown. If Show Exclusion Notice on Product Page is enabled (see Product Exclusions), the product page displays an exclusion notice ("No right of withdrawal" / configurable text). The withdrawal form/link is not offered for that item.

In short:

  • standard — always withdrawable within the deadline.
  • digital_content — withdrawable only until the mandatory consent is accepted at checkout; afterwards it is not.
  • service_early — withdrawable unless the optional consent was accepted and the service has been fully performed; if accepted, the customer may still owe the proportionate cost of work already done.
  • dated_services — never withdrawable (Art. 16(l)), no consent involved.
  • other_article16 — never withdrawable, regardless of consent.

The status is set on the product, but it is resolved more widely: a variation falls back to its parent product, a product with no status of its own inherits from its categories (walking up the hierarchy), and on a multilingual site a translation inherits from the original-language product or category. See Multilingual sites.

See Checkout Consents to customise the consent checkbox texts, and Product Exclusions to configure exclusions and notices at the category level.

Product Exclusions

Configure which products or product categories are excluded from withdrawal rights under Art. 16 of the directive.

Setting Description Default
Show Exclusion Notice on Product Page Master switch for the product-page notices below. Never applies to service_early: there the right is not lost, only pro-rated, and the checkout consent already says so. Yes
Other Exclusion Notice Title / Body Shown on other_article16 products. No right of withdrawal / see plugin defaults
Dated Services Notice Title / Body (Art. 16(l)) Shown on dated_services products. No right of withdrawal / see plugin defaults
Digital Content Notice Title / Body (Art. 16(m)) Shown on digital_content products. The right is not lost upfront — it ends once the customer consents at checkout and the content is supplied, which is what the default wording says. Leave both fields empty to show nothing. See plugin defaults

All six texts are exposed to WPML/Polylang String Translation through the bundled wpml-config.xml.


Multilingual sites (WPML / Polylang)

Compliance cannot depend on the language the customer happened to browse in, so both plugins are supported with nothing to configure.

  • Set the withdrawal status once, on the product or category in your original language, and it holds across every translation: exclusion notice, Art. 16(m) and Art. 14(4)(a) checkout consents, and the excluded items recorded on the order. A status set explicitly on a translation still wins, so per-language exceptions remain possible. The product editor states which status is in effect when the product inherits one.
  • Every link follows the visitor's language: withdrawal page, printable Annex I.B view, the button in WooCommerce emails, the excluded-notice link and the [trece_withdrawal_link] shortcode.
  • Your own texts stay translatable: wpml-config.xml exposes the notice titles and bodies, the form intro, the consent texts, the consumer self-declaration, the status-email bodies, the sender name and the trader address under String Translation, copies the withdrawal status to translations, and marks the request log as non-translatable.

Single-language sites are unaffected — the resolution short-circuits when neither plugin is active.


Shortcodes

[trece_withdrawal_form]

Renders the full two-step withdrawal form based on the Annex I.B model withdrawal form.

Attributes:

Attribute Type Description Default
consumer_check string yes to force the consumer self-declaration checkbox on this page regardless of the global setting. —

Usage: Place this shortcode on a dedicated WordPress page, then select that page in Withdrawals → Settings → Form Page.

[trece_withdrawal_form]

Behaviour:

  1. Step 1 — The customer fills in the form fields (name, address, order number if required, goods/services description, date of receipt, and optionally their email).
  2. Step 2 — A confirmation screen summarises the withdrawal request and requires explicit confirmation per Art. 11a(3) two-step process.
  3. Success — A confirmation page displays the SHA-256 receipt hash, withdrawal ID, and timestamp. If email confirmation is enabled, the customer also receives this by email.

[trece_withdrawal_link]

Renders the "Withdraw from contract here" button/link as required by the directive's mandatory withdrawal mechanism.

Attributes:

Attribute Type Description Default
order_id int Optional. Pre-fills the order number field when the form is loaded. —
class string Optional. Additional CSS class(es) for the link element. —

Usage:

<!-- Basic usage -->
[trece_withdrawal_link]

<!-- With order ID pre-filled -->
[trece_withdrawal_link order_id="12345"]

<!-- With custom CSS class -->
[trece_withdrawal_link class="my-custom-button"]

[trece_withdrawal_excluded_notice]

Renders the Article 16 exclusion notice for a product. Page builders (Divi, Elementor, Bricks, ShopLentor) render their own single-product template and never fire woocommerce_single_product_summary, where the notice is normally injected — drop this shortcode into the layout instead.

Attributes:

Attribute Type Description Default
id int Optional. Product to render the notice for. the current product
[trece_withdrawal_excluded_notice]
[trece_withdrawal_excluded_notice id="123"]

Nothing is printed when the product is not flagged as excluded, or when the Show Exclusion Notice on Product Page setting is off.


Hooks & Filters Reference

The plugin provides 20 filters and 5 actions for developers to customise behaviour.

Filters


trece_wdeu_withdrawal_deadline_days

Modify the withdrawal deadline in days. The EU directive mandates a minimum of 14 days, but member states or the trader may offer more.

Parameters:

Parameter Type Description
$days int The withdrawal deadline in days. Default: 14.

Returns: int — The modified deadline in days.

Example:

<?php
/**
 * Extend the withdrawal deadline to 30 days.
 */
add_filter( 'trece_wdeu_withdrawal_deadline_days', function ( int $days ): int {
    return 30;
} );

trece_wdeu_consent_digital_text

Modify the text displayed for the digital content consent checkbox at checkout (Art. 16(m)).

Parameters:

Parameter Type Description
$text string The default consent checkbox label text.

Returns: string — The modified text.

Example:

<?php
/**
 * Customise the digital content consent text.
 */
add_filter( 'trece_wdeu_consent_digital_text', function ( string $text ): string {
    return 'I expressly consent to the immediate provision of the digital content and acknowledge '
         . 'that I thereby lose my right of withdrawal.';
} );

trece_wdeu_consent_service_text

Modify the text displayed for the service consent checkbox at checkout (Art. 14(4)(a)).

Parameters:

Parameter Type Description
$text string The default consent checkbox label text.

Returns: string — The modified text.

Example:

<?php
/**
 * Customise the service consent text.
 */
add_filter( 'trece_wdeu_consent_service_text', function ( string $text ): string {
    return 'I acknowledge that once the service has been fully performed, '
         . 'I will no longer be entitled to withdraw from the contract.';
} );

trece_wdeu_excluded_notice_html

Modify the HTML output of the exclusion notice displayed on product pages for products excluded from withdrawal rights under Art. 16.

Parameters:

Parameter Type Description
$html string The default exclusion notice HTML.
$product WC_Product The WooCommerce product object.
$reason string The exclusion reason key (e.g., sealed_goods, personalised).

Returns: string — The modified HTML.

Example:

<?php
/**
 * Add a custom icon to the exclusion notice.
 */
add_filter( 'trece_wdeu_excluded_notice_html', function ( string $html, WC_Product $product, string $reason ): string {
    $icon = '<span class="dashicons dashicons-warning"></span> ';
    return '<div class="trece-wdeu-exclusion-notice trece-wdeu-exclusion-notice--custom">'
         . $icon . esc_html__( 'This product is excluded from the right of withdrawal.', 'trece-euwd-compliance' )
         . '</div>';
}, 10, 3 );

trece_wdeu_annex_trader_data

Modify the trader data string displayed in the Annex I.B model withdrawal form. Useful for multi-store setups or dynamic trader information.

Parameters:

Parameter Type Description
$trader_data string The formatted trader data (name, address, email, etc.).

Returns: string — The modified trader data string.

Example:

<?php
/**
 * Append a VAT number to the trader information.
 */
add_filter( 'trece_wdeu_annex_trader_data', function ( string $trader_data ): string {
    return $trader_data . "\n" . 'VAT: EU123456789';
} );

Order resolution

Out of the box the resolver matches the reference the customer typed against _order_number, _order_number_formatted, _alg_wc_full_custom_order_number and _alg_wc_custom_order_number — covering WooCommerce Sequential Order Numbers (free and Pro) and Custom Order Numbers for WooCommerce (Tyche and WPFactory). A literal order ID is accepted only when the order's displayed number matches what was typed, so internal IDs cannot be probed in a shop with custom numbering.

Three filters hook into that pipeline:

Filter Fires Return
trece_wdeu_pre_resolve_order Before the built-in strategies. WC_Order to accept, false to reject, null to fall through.
trece_wdeu_order_number_meta_keys While building the meta-key list. string[] of meta keys, in priority order.
trece_wdeu_resolve_order After resolution, for auditing or a last-chance override. WC_Order or null.
<?php
// Numbering computed on the fly, stored in no meta key.
add_filter( 'trece_wdeu_pre_resolve_order', function ( $pre, string $order_number ) {
    if ( ! str_starts_with( $order_number, 'ERP-' ) ) {
        return $pre; // null → fall through to the built-in strategies.
    }

    $order_id = my_erp_lookup( $order_number );

    return $order_id ? wc_get_order( $order_id ) : false;
}, 10, 2 );

// Or just add your numbering plugin's meta key.
add_filter( 'trece_wdeu_order_number_meta_keys', function ( array $keys ): array {
    $keys[] = '_my_plugin_order_number';
    return $keys;
} );

trece_wdeu_consent_hook

The classic-checkout action the consent checkboxes render on. Return an empty string to suppress the render entirely (for a theme that prints them itself).

add_filter( 'trece_wdeu_consent_hook', function ( string $hook ): string {
    return 'woocommerce_checkout_before_terms_and_conditions';
} );

Moving them into the order-review panel works, but that panel is re-rendered by AJAX on every address or shipping change, so anything the customer had ticked is redrawn unticked. woocommerce_review_order_before_submit (the default) is inside that panel too — it is the placement WooCommerce itself uses for the terms checkbox, and the field state is posted with the form either way.


trece_wdeu_consent_hook_priority

Priority the checkboxes are hooked with. Receives the hook name as the second argument.

add_filter( 'trece_wdeu_consent_hook_priority', fn( int $priority ): int => 20 );

trece_wdeu_consent_applies

Whether a consent is asked for on the current cart. Returning false drops it for that cart only: not rendered, not required, not persisted. For per-cart rules the product status alone cannot express.

add_filter( 'trece_wdeu_consent_applies', function ( bool $applies, string $type ): bool {
    // Never ask for the service consent on trade accounts.
    return ( 'service_early' === $type && my_shop_is_trade_customer() ) ? false : $applies;
}, 10, 2 );

trece_wdeu_consent_is_required

Whether a consent blocks the order when left unticked. Defaults to true for digital_content and to the Require the Service Consent setting for service_early.

add_filter( 'trece_wdeu_consent_is_required', function ( bool $required, string $type ): bool {
    return 'service_early' === $type ? true : $required;
}, 10, 2 );

trece_wdeu_eligible_statuses

The WooCommerce order statuses that make an order eligible for a withdrawal request. Receives the value from the Eligible Order Statuses setting and governs the My Account button, the order listing, the public form and the one-click link in order emails at once.

add_filter( 'trece_wdeu_eligible_statuses', function ( array $statuses ): array {
    $statuses[] = 'shipped'; // Custom status registered by another plugin.

    return $statuses;
} );

trece_wdeu_email_ids

The WooCommerce email IDs the withdrawal notice is injected into. Lets you add a custom transactional email (or drop a bundled one) without touching the eligible order statuses. Receives the WC_Order as the second argument.

add_filter( 'trece_wdeu_email_ids', function ( array $ids ): array {
    $ids[] = 'customer_shipped_order';

    return $ids;
}, 10, 2 );

trece_wdeu_grace_days

The grace days added on top of the withdrawal period, before trece_wdeu_withdrawal_deadline_days sees the total. Use it to extend your own margin (shipping lead time, holidays) without restating the statutory period. Receives the WC_Order as the second argument.

add_filter( 'trece_wdeu_grace_days', function ( int $days, $order ): int {
    return my_shop_is_peak_season() ? $days + 7 : $days;
}, 10, 2 );

trece_wdeu_accept_unmatched

Whether a request whose order/email pair cannot be matched is registered as Unverified for manual review instead of rejected. Receives the value from the Accept Unmatched Requests setting.

add_filter( 'trece_wdeu_accept_unmatched', '__return_true' );

trece_wdeu_show_consumer_check

Whether the "I purchased as a consumer" self-declaration checkbox is shown, for per-order logic (VIES validation, a customer-type field, and so on).

add_filter( 'trece_wdeu_show_consumer_check', function ( bool $show ): bool {
    return $show && ! my_shop_is_b2b_only();
} );

trece_wdeu_altcha_enabled

Whether the ALTCHA anti-bot check runs on the public form, overriding the setting. Evaluated on plugins_loaded, so keep the callback to things that are already known at that point — a constant, an environment flag — rather than the current user or the queried page.

add_filter( 'trece_wdeu_altcha_enabled', function ( bool $enabled ): bool {
    // Never make staging solve puzzles.
    return $enabled && 'production' === wp_get_environment_type();
} );

trece_wdeu_validation_errors

The array of validation errors collected in step 1, just before the request is allowed to proceed. Append a message to reject the submission, for example from a captcha integration. Receives the resolved WC_Order (or null) as the second argument.

add_filter( 'trece_wdeu_validation_errors', function ( array $errors, $order ): array {
    if ( ! my_captcha_passes() ) {
        $errors[] = __( 'Captcha verification failed.', 'my-textdomain' );
    }

    return $errors;
}, 10, 2 );

trece_wdeu_resolve_order_number

Legacy. Kept for back-compatibility with 1.x integrations; prefer trece_wdeu_pre_resolve_order above, which receives and returns a WC_Order rather than an ID. Implement custom logic to resolve an order number to a WC_Order object. Useful when using custom order number plugins (e.g., WooCommerce Sequential Order Numbers).

Parameters:

Parameter Type Description
$order WC_Order\|null The resolved order, or null if not yet resolved.
$order_number string The order number submitted by the customer.

Returns: WC_Order|null — The resolved order, or null if not found.

Example:

<?php
/**
 * Resolve order numbers from WooCommerce Sequential Order Numbers Pro.
 */
add_filter( 'trece_wdeu_resolve_order_number', function ( ?WC_Order $order, string $order_number ): ?WC_Order {
    if ( $order !== null ) {
        return $order;
    }

    // Query by custom order number meta.
    $orders = wc_get_orders( [
        'meta_key'   => '_order_number',
        'meta_value' => sanitize_text_field( $order_number ),
        'limit'      => 1,
    ] );

    return ! empty( $orders ) ? $orders[0] : null;
}, 10, 2 );

trece_wdeu_receipt_email_content

Modify the content of the confirmation email sent to the customer after a withdrawal request is successfully submitted.

Parameters:

Parameter Type Description
$content string The default email body content (HTML).
$withdrawal object The withdrawal data object containing all submission details.

Returns: string — The modified email content.

Example:

<?php
/**
 * Add a custom footer to the withdrawal confirmation email.
 */
add_filter( 'trece_wdeu_receipt_email_content', function ( string $content, object $withdrawal ): string {
    $footer = '<hr><p style="font-size: 12px; color: #666;">'
            . 'If you have any questions, please contact us at support@example.com.'
            . '</p>';

    return $content . $footer;
}, 10, 2 );

Actions


trece_wdeu_form_before_submit

Fires inside the public form (step 1), just before the submit button. Insertion point for a captcha widget or an extra declaration; pair it with trece_wdeu_validation_errors to enforce it.

Parameters: none.

add_action( 'trece_wdeu_form_before_submit', function (): void {
    echo do_shortcode( '[my_captcha]' );
} );

trece_wdeu_after_form

Fires after the public form, before the Annex I.B block.

Parameters: none.

add_action( 'trece_wdeu_after_form', function (): void {
    echo '<p class="my-shop-returns-note">' . esc_html__( 'Questions? Call us.', 'my-textdomain' ) . '</p>';
} );

trece_wdeu_withdrawal_created

Fired immediately after a new withdrawal request is created and stored in the database.

Parameters:

Parameter Type Description
$withdrawal_id int The ID of the newly created withdrawal record.
$data array Associative array of submission data (customer_name, customer_email, order_id, reason, hash, etc.)

This README is longer than the copy stored here. Read the rest on GitHub →

Releases

1 release.

Tag
Published
1.6.0 latest
Jul 23, 2026 3mo ago

These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.