Skip to content
Developers

Hooks reference

WPReturns exposes WordPress actions and filters, all prefixed ddwcwr_, for every step of a return. Actions fire when a request is created, changes status, gets a message, is resolved, gets a label or is deleted. Filters change statuses, reasons, request numbers, return windows, risk flags, label carriers and the private upload folder.

Available in: Free and Pro. Hooks for rules, labels bought through a provider, fraud, automation and webhooks exist only in Pro. The tables mark them.

Add hook code to a small custom plugin or your child theme’s functions.php. Settings load on init at priority 5. Filters added when your plugin loads are in place before that.

ActionArgumentsWhen it firesAvailable in
ddwcwr_loadednoneOnce, when the plugin’s main class is first createdFree and Pro
ddwcwr_request_createdint $request_id, array $requestAfter a request and its items are saved, before auto-approve or auto-reject runsFree and Pro
ddwcwr_request_status_changedint $request_id, string $old_status, string $new_status, array $request, array $argsAfter any status change. $args holds note, author_id and notify.Free and Pro
ddwcwr_request_message_addedint $request_id, int $message_id, string $author_type, string $messageAfter a conversation message is added. Not for internal notes or log entries. $author_type is customer, staff or system.Free and Pro
ddwcwr_resolution_processedint $request_id, array $result, array $requestAfter a resolution is carried out, before the request moves to CompletedFree and Pro
ddwcwr_label_readyint $request_id, bool $is_reminderAfter a label is uploaded or bought (false). Again when the unused-label reminder runs (true, Pro).Free and Pro
ddwcwr_ship_reminderint $request_id, int $deadlineFires in the daily automation a set number of days before an unshipped request is closed. $deadline is a timestamp.Pro
ddwcwr_request_deletedint $request_idAfter a request, its items, messages and files are deletedFree and Pro
ddwcwr_webhook_request_updatedint $request_idAfter a status change or a resolution. It feeds the return_request.updated webhook topic.Pro

$result in ddwcwr_resolution_processed always has resolution and message. Depending on the resolution it also carries coupon, wallet, via_gateway, exchange_order_id, amount_due or pay_url.

WooCommerce emails listen to these actions through WooCommerce’s deferred _notification variants such as ddwcwr_request_created_notification.

Pro schedules two Action Scheduler actions in the ddwcwr group. You can see them under WooCommerce > Status > Scheduled Actions.

ActionArgumentsSchedule
ddwcwr_daily_maintenancenoneDaily at 03:00. Sends label and ship-by reminders and closes stale requests.
ddwcwr_auto_refundint $request_idOnce, the set number of hours after a request is marked received
FilterArgumentsWhat it changesAvailable in
ddwcwr_configurationarray $configurationAll settings (read once on init)Free and Pro
ddwcwr_order_adapterDDWCWR_Order_Adapter_Interface $adapterThe class every order call goes throughFree and Pro
ddwcwr_statusesarray $statusesStatuses keyed by slug with label, color, notify and coreFree and Pro
ddwcwr_final_statusesarray $slugsStatuses that close a request. Default completed, rejected and cancelled.Free and Pro
ddwcwr_reasonsarray $reasonsReasons keyed by slug with label, require_photo, merchant_fault and statusFree and Pro
ddwcwr_request_typesarray $typesRequest types and their labelsFree and Pro
ddwcwr_resolutionsarray $resolutionsResolutions and their labelsFree and Pro
ddwcwr_item_conditionsarray $conditionsItem conditions customers can pickFree and Pro
ddwcwr_request_numberstring $number, int $request_idThe visible number (RMA-01042 by default)Free and Pro
ddwcwr_find_order_id_by_numberint $order_id, string $order_numberMaps a typed order number to an order ID for sequential number pluginsFree and Pro
ddwcwr_withdrawal_eu_countriesarray $country_codesCountries in the default withdrawal scope (EU plus IS, LI, NO)Free and Pro
ddwcwr_withdrawal_item_excludedbool $excluded, array $itemWhether an item is exempt from withdrawalFree and Pro
ddwcwr_item_final_salebool $final_sale, array $itemWhether an item is final saleFree and Pro
ddwcwr_trader_addressarray $linesAddress lines on the model withdrawal formFree and Pro
ddwcwr_private_upload_dirstring $dirFolder for customer uploads and labelsFree and Pro
ddwcwr_requests_list_columnsarray $columns, string $fixed_typeColumns on the Requests and Withdrawals listsFree and Pro
ddwcwr_label_providersarray $providersLabel providers keyed by IDPro
ddwcwr_label_parcelarray $parcel, array $requestPackage length, width, height (in) and weight (oz) sent to the providerPro
ddwcwr_rule_matchesbool $matches, array $rule, array $contextWhether a rule applies, after the built-in conditions passedPro
ddwcwr_item_return_windowarray $window, array $contextdays and from (completed or created) for an itemPro
ddwcwr_request_risk_flagsarray $flags, array $argsRisk flags for a new requestPro
ddwcwr_risk_flag_definitionsarray $definitionsFlag labels and weights keyed by flag slugPro

$item holds the order line: id, product_id, variation_id, parent_id, name, sku, qty, unit_value and downloadable, among others.

The rule $context holds product_ids, category_ids, user_roles, order_total, item_value, country, request_type, reason and customer_flagged.

The risk $args holds customer_id, email, items, window_used, type and delivered.

Example: tell the warehouse when a parcel arrives

Section titled “Example: tell the warehouse when a parcel arrives”

This sends an email to the warehouse every time a request moves to Received.

<?php
add_action( 'ddwcwr_request_status_changed', 'myshop_notify_warehouse', 10, 4 );
function myshop_notify_warehouse( $request_id, $old_status, $new_status, $request ) {
if ( 'received' !== $new_status ) {
return;
}
wp_mail(
'warehouse@example.com',
sprintf( 'Return %s received', $request['number'] ),
sprintf( 'Order #%d. Check the items and restock.', $request['order_id'] )
);
}

Example: use your own request number prefix

Section titled “Example: use your own request number prefix”

This turns RMA-01042 into RET-01042. Search on the Requests list keeps working because it reads the digits.

<?php
add_filter( 'ddwcwr_request_number', 'myshop_request_number', 10, 2 );
function myshop_request_number( $number, $request_id ) {
return 'RET-' . str_pad( (string) absint( $request_id ), 5, '0', STR_PAD_LEFT );
}

This adds a “Freight forwarder” flag with a weight of 30 when the email domain is on your own list.

<?php
add_filter( 'ddwcwr_risk_flag_definitions', 'myshop_risk_flag_definitions' );
function myshop_risk_flag_definitions( $definitions ) {
$definitions['forwarder'] = array(
'label' => 'Freight forwarder',
'weight' => 30,
);
return $definitions;
}
add_filter( 'ddwcwr_request_risk_flags', 'myshop_risk_flags', 10, 2 );
function myshop_risk_flags( $flags, $args ) {
$domains = array( 'forwarder.example', 'parcelhub.example' );
$domain = strtolower( substr( strrchr( (string) $args['email'], '@' ), 1 ) );
if ( in_array( $domain, $domains, true ) ) {
$flags[] = 'forwarder';
}
return $flags;
}

The flag shows as a pill on the list and the request screen. It adds 30 to the risk score. Only serial_returner and manual_flag hold a request for review.

Every order call goes through one adapter. Return your own class from ddwcwr_order_adapter to change how orders are read, refunded or restocked. It must follow DDWCWR_Order_Adapter_Interface in helper/order/interface-order-adapter.php.

To add a label carrier, return an extra provider from ddwcwr_label_providers. The class follows DDWCWR_Label_Provider_Interface with get_id(), get_name(), is_configured() and create_label( $from, $to, $parcel ). create_label() returns url, tracking_number, carrier, cost and currency, or a WP_Error.