Skip to content

Replacement Orders

Barberklingen\BasePlugin\Modules\ReplacementOrder\ReplacementOrderLoader

A replacement order is a free copy of an existing order — same items, same address, totals zeroed. It is typically created when a customer reports a problem with their shipment.

Activating the module

ReplacementOrderLoader::get_instance();

This registers the REST endpoint, admin UI filters, and Klaviyo extension.

Creating a replacement order

use Barberklingen\BasePlugin\Modules\ReplacementOrder\ReplaceOrder;

$replacementOrder = ReplaceOrder::from_order($originalOrder);

from_order():

  1. Creates a new WC order with status = processing, copying customer ID, note, and billing/shipping address.
  2. Copies all line items and shipping items (totals zeroed).
  3. Links the orders via the _replacement_for_order_id meta on the replacement and _subscription_renewal if a subscription exists.
  4. Fires replacement-order/created with ($replacementOrder, $originalOrder, $subscription|null).

Product substitutions

When creating the replacement, specific products can be swapped for alternatives (e.g. a "replacement blades" variant instead of the original product). Register substitutions via a filter:

add_filter('replacement-order/product-replacements', function (array $map): array {
    $map[ORIGINAL_PRODUCT_ID]   = REPLACEMENT_PRODUCT_ID;
    $map[ORIGINAL_VARIATION_ID] = REPLACEMENT_VARIATION_ID;
    return $map;
});

Skipping items

Individual items can be excluded from copying:

add_filter('replacement-order/skip-item', function (bool $skip, $item, $toOrder, $fromOrder): bool {
    return $item->get_product_id() === MY_EXCLUDED_PRODUCT_ID;
}, 10, 4);

REST endpoint

The module registers a WP REST route handled by ReplacementOrder\REST\RouteController. The endpoint accepts an order ID and returns the newly created replacement order.

Admin integration

  • Adds Replacement as a filterable order type in the WooCommerce orders list.
  • Exposes a single-order action via SingleOrderActions to trigger replacement creation from the order edit screen.
  • Updates the subscription's related orders panel to label replacement orders correctly.

Klaviyo extension

KlaviyoExtension hooks into replacement-order/created to push an event when a replacement is issued.

Meta keys

Key Location Description
_replacement_for_order_id Replacement order ID of the original order
_subscription_renewal Replacement order Related subscription ID (if any)

Excluded meta on copy

The loader maintains a hardcoded list of meta keys that are not copied to the replacement order (payment tokens, tracking numbers, invoice data, etc.). Extend it via:

// For order meta
add_filter('wc_subscriptions_copy_order_data', [ReplacementOrderLoader::class, 'exclude_meta_copy'], 100);

// For order item meta
add_filter('copy_order_item_meta_exclusions', fn($keys) => array_merge($keys, ['my_key']));