Docs
Filters Reference

Filters Reference

WordPress filters to modify SquareSync data and behavior.

Filters let you modify data before it's processed by SquareSync. Use these hooks to customize sync behavior, transform data, and integrate with other systems.

Order Filters

squarewoosync_prepare_order_data

Modify order data before sending to the Square API.

Location: includes/REST/OrdersController.php

ParameterTypeDescription
$order_dataarraySquare order data structure
$wc_orderWC_OrderWooCommerce order object
add_filter('squarewoosync_prepare_order_data', function($order_data, $wc_order) {
    $order_data['order']['metadata']['store_id'] = get_current_blog_id();
    $order_data['order']['metadata']['source'] = 'woocommerce';
    return $order_data;
}, 10, 2);

squarewoosync_order_location_id

Override the Square location for specific orders.

Location: includes/REST/OrdersController.php

ParameterTypeDescription
$location_idstringSquare location ID
$orderWC_OrderWooCommerce order
add_filter('squarewoosync_order_location_id', function($location_id, $order) {
    $shipping_zone = $order->get_shipping_state();
    if ($shipping_zone === 'CA') {
        return 'CALIFORNIA_LOCATION_ID';
    }
    return $location_id;
}, 10, 2);

squarewoosync_webhook_order_import_enabled

Control whether specific Square orders should be imported via webhook.

Location: includes/Jobs/WebhookProcessJob.php

ParameterTypeDescription
$should_importboolWhether to import this order
$orderIdstringSquare order ID
$orderLocationstringSquare location ID
$dataarrayWebhook payload data
add_filter('squarewoosync_webhook_order_import_enabled', function($should_import, $orderId, $orderLocation, $data) {
    // Skip orders from specific location
    if ($orderLocation === 'LOCATION_TO_SKIP') {
        return false;
    }
    return $should_import;
}, 10, 4);

squarewoosync_before_process_square_order

Modify Square order data before processing for import.

Location: includes/Woo/CreateOrder.php

ParameterTypeDescription
$squareOrderarraySquare order data
$orderIdstringSquare order ID
add_filter('squarewoosync_before_process_square_order', function($squareOrder, $orderId) {
    // Add custom processing logic
    return $squareOrder;
}, 10, 2);

sws_order_import_pushed_from_this_site

Decide whether a Square order about to be imported was created from a WooCommerce order on this site. The import skips such orders, since importing them would create a second WooCommerce order for the same sale. By default an order is recognised either from the marker the plugin sets the instant Square returns a new order it pushed, or from the order's woo_order_id metadata when that WooCommerce order exists here, is not itself a Square import, and either already links to this Square order or has no Square link yet and is less than two days old. Return 0 to import the order anyway.

Since 10.4.17.

Location: includes/Woo/CreateOrder.php

ParameterTypeDescription
$woo_order_idintWooCommerce order id the Square order was pushed from, or 0 if not recognised
$square_order_idstringSquare order ID
$square_orderarray/nullThe fetched Square order, when available (null on the pre-fetch marker check)
// Always import, even orders this site pushed to Square (not recommended).
add_filter('sws_order_import_pushed_from_this_site', function($woo_order_id, $square_order_id, $square_order) {
    return 0;
}, 10, 3);

squarewoosync_square_order_data

Modify Square order data before creating WooCommerce order.

Location: includes/Woo/CreateOrder.php

ParameterTypeDescription
$squareOrderarraySquare order data
$email_settingsarrayEmail notification settings
add_filter('squarewoosync_square_order_data', function($squareOrder, $email_settings) {
    // Modify order data before WooCommerce order creation
    return $squareOrder;
}, 10, 2);

squarewoosync_order_customer_id

Override customer ID assigned to imported orders.

Location: includes/Woo/CreateOrder.php

ParameterTypeDescription
$customerIdintWordPress customer ID
$squareOrderarraySquare order data
$orderWC_OrderWooCommerce order
add_filter('squarewoosync_order_customer_id', function($customerId, $squareOrder, $order) {
    // Assign specific customer based on Square data
    return $customerId;
}, 10, 3);

squarewoosync_order_line_items

Modify line items before adding to imported order.

Location: includes/Woo/CreateOrder.php

ParameterTypeDescription
$lineItemsarrayLine items array
$orderWC_OrderWooCommerce order
$squareOrderarraySquare order data
add_filter('squarewoosync_order_line_items', function($lineItems, $order, $squareOrder) {
    // Modify line items during import
    return $lineItems;
}, 10, 3);

squarewoosync_order_taxes

Modify tax data before applying to imported order.

Location: includes/Woo/CreateOrder.php

ParameterTypeDescription
$taxesarrayTax data array
$orderWC_OrderWooCommerce order
$squareOrderarraySquare order data
add_filter('squarewoosync_order_taxes', function($taxes, $order, $squareOrder) {
    // Modify taxes during import
    return $taxes;
}, 10, 3);

squarewoosync_order_discounts

Modify discount data before applying to imported order.

Location: includes/Woo/CreateOrder.php

ParameterTypeDescription
$discountsarrayDiscounts array
$orderWC_OrderWooCommerce order
$squareOrderarraySquare order data
add_filter('squarewoosync_order_discounts', function($discounts, $order, $squareOrder) {
    // Modify discounts during import
    return $discounts;
}, 10, 3);

squarewoosync_order_status_mapping

Custom status mapping for imported orders.

Location: includes/Woo/CreateOrder.php

ParameterTypeDescription
$newOrderStatusstringWooCommerce order status
$squareOrderStatestringSquare order state
$orderWC_OrderWooCommerce order
$squareOrderarraySquare order data
add_filter('squarewoosync_order_status_mapping', function($newOrderStatus, $squareOrderState, $order, $squareOrder) {
    // Custom status mapping
    if ($squareOrderState === 'OPEN') {
        return 'on-hold';
    }
    return $newOrderStatus;
}, 10, 4);

sws_fulfillment_shipping_note

Since 10.4.16. Change the note sent on a Square DELIVERY or SHIPMENT fulfillment (delivery_details.note / shipment_details.shipping_note), which Square prints on the order ticket. By default it is the WooCommerce shipping method name(s) the customer chose at checkout, e.g. "DHL Next Day Delivery". Return an empty string to send no note. Square caps the note at 500 characters. Nothing is sent in the shipment's shipping_type field (10.4.16 populated it and the Square Register / POS apps crashed opening the order; removed in 10.4.18).

Location: includes/REST/OrdersController.php

ParameterTypeDescription
$notestringThe note to send. Default: the shipping method name(s)
$orderWC_OrderWooCommerce order
$fulfillment_typestringDELIVERY or SHIPMENT
$method_namesstring[]Shipping line titles on the order
add_filter('sws_fulfillment_shipping_note', function($note, $order, $fulfillment_type, $method_names) {
    // Prefix the courier option and add the customer's checkout note
    $note = 'Ship via: ' . implode(', ', $method_names);
    if ($order->get_customer_note()) {
        $note .= ' | ' . $order->get_customer_note();
    }
    return $note;
}, 10, 4);

Product Import Filters (Square → WooCommerce)

These filters run while a Square catalog item is being turned into a WooCommerce product. They apply to every import path: manual imports, scheduled/cron syncs, and real-time webhook updates.

squarewoosync_category_mapping

Since 10.4.9. Override the Square → WooCommerce category mapping set under Settings → Products → Import. The mapping decides which WooCommerce category each Square category imports into, and takes precedence over SquareSync's name matching on every import path. Since 10.4.13 it is also honoured in reverse on export: a WooCommerce category that a Square category maps into exports as that Square category, so it is never recreated in Square under the WooCommerce name.

Location: includes/Common/Helpers.php

ParameterTypeDescription
$mappingarray['map' => [square_category_id => product_cat term ID], 'unmapped' => 'create'|'skip']. create finds or creates the category by name (the historical behaviour); skip leaves the product out of any Square category you have not mapped
// Send everything in one Square category to a WooCommerce category chosen in code,
// and never let an unmapped Square category create a new WooCommerce one.
add_filter('squarewoosync_category_mapping', function ($mapping) {
    $mapping['map']['A1B2C3SQUARECATEGORYID'] = 42; // WooCommerce product_cat term ID
    $mapping['unmapped'] = 'skip';
    return $mapping;
});

squarewoosync_wc_product_data

Since 9.8.5. Modify the fully mapped product data before the WooCommerce product is created or updated. This is the most powerful import hook — every field SquareSync writes to the product passes through it, so you can adjust the title, price, stock, categories, description, variations, images and more in one place.

Location: includes/Square/SquareImport.php

ParameterTypeDescription
$wc_product_dataarrayMapped WooCommerce product data (keys below)
$square_productarrayRaw Square catalog item — id, item_data (with name, description, variations, categories, reporting_category), custom_attribute_values, present_at_location_ids, etc.
$existing_productWC_Product|nullThe linked WooCommerce product, or null when the product doesn't exist yet (new import)
$update_onlybooltrue when the sync only updates existing products and won't create new ones

Keys available in $wc_product_data:

KeyTypeDescription
namestringProduct title. Must not be emptied — an empty name fails validation and the product is skipped
descriptionstringProduct description
typestringsimple or variable
pricefloat|nullPrice for simple products (variable products use per-variation prices)
stockint|nullStock quantity for simple products; null means "no inventory data — don't touch stock"
skustringSKU (simple products)
upcstringUPC/GTIN (simple products)
categoriesarraySquare categories, each ['id' => string, 'name' => string, 'parent_id' => string|false]
variationsarrayFor variable products. Each entry: name, sku, upc, price (float), currency, stock (int|null), variation_square_id, attributes (array of ['name' => ..., 'option' => ...]), images, track_inventory, location_overrides
imagesarraysquare_image_id => URL map, ordered — the first entry becomes the featured image
square_product_idstringThe Square catalog item ID
custom_attribute_valuesarraySquare custom attributes on the item
modifiersarraySquare modifier lists mapped for this product
is_taxable / tax_ids / resolved_tax_ratesbool / array / arraySquare tax data used for tax class mapping
locationsarraySquare location IDs the item is present at, or ['*'] for all locations
inventory_countsarrayPer-location stock map location_id => qty (only present when inventory was fetched)

Note: fields are still subject to your Data to Import settings — for example, a modified price is only written to the product when price importing is enabled for that sync.

// Prefix the title and zero out stock for items in a given Square category
add_filter('squarewoosync_wc_product_data', function ($data, $square_product, $existing, $update_only) {
    $category_names = array_map(fn($c) => $c['name'] ?? '', $data['categories'] ?? []);
 
    if (in_array('Events', $category_names, true)) {
        $data['name']  = '[Event] ' . $data['name'];
        $data['stock'] = 100; // fixed ticket allocation
 
        // Variable products: adjust each variation instead
        foreach ($data['variations'] as &$variation) {
            $variation['price'] = round($variation['price'] * 1.1, 2); // +10%
        }
        unset($variation);
    }
    return $data;
}, 10, 4);

squarewoosync_product_categories

Since 9.8.5. Adjust, add or remove the categories SquareSync is about to assign to a product. Runs just before Square categories are matched/created as WooCommerce product_cat terms. Return an empty array to remove all categories from the product.

Location: includes/Woo/CreateProduct.php

ParameterTypeDescription
$categoriesarrayCategories from Square (may be empty). Each entry: ['id' => string, 'name' => string, 'parent_id' => string|false]
$productWC_ProductThe WooCommerce product being created/updated
$wc_product_dataarrayFull mapped product data (see squarewoosync_wc_product_data)

Entries are matched or created by name; parent_id references another entry's id to build hierarchy. For categories you add yourself, any unique string works as id.

add_filter('squarewoosync_product_categories', function ($categories, $product, $data) {
    // Rename a Square category on the Woo side
    foreach ($categories as &$cat) {
        if (($cat['name'] ?? '') === 'Food & Drink') {
            $cat['name'] = 'Groceries';
        }
    }
    unset($cat);
 
    // Add an extra category to everything that comes from Square
    $categories[] = ['id' => 'custom-square-imports', 'name' => 'Square Imports', 'parent_id' => false];
 
    return $categories;
}, 10, 3);

squarewoosync_product_name

Filter the product title during import. Receives the raw Square item so the title can be adjusted conditionally. (For broader changes, prefer squarewoosync_wc_product_data.)

Location: includes/Square/SquareImport.php

ParameterTypeDescription
$namestringThe Square item name
$square_productarrayRaw Square catalog item
add_filter('squarewoosync_product_name', function ($name, $square_product) {
    return str_replace(' (POS)', '', $name);
}, 10, 2);

squarewoosync_import_html_description

Since 10.2.0. Control whether product descriptions are imported from Square's rich description_html field (bold text, lists and paragraphs preserved) or the deprecated plain-text description field. The default follows the Rich product descriptions toggle under Settings → Products → Import Settings (on unless the merchant turned it off); this filter overrides that setting. Runs on every Square → WooCommerce path — manual imports, scheduled sync and real-time webhook updates. When "Strip formatting on import" is enabled for the description field, stripping still runs afterwards and wins.

Location: includes/Common/Helpers.php

ParameterTypeDescription
$use_htmlboolWhether to prefer description_html
$item_dataarraySquare catalog item_data for the item
// Always import plain-text descriptions regardless of the setting.
add_filter('squarewoosync_import_html_description', '__return_false');

squarewoosync_import_clear_empty_fields

Since 10.4.13. Decide whether an empty value from Square may clear the matching WooCommerce field on import. By default it may not: a Square item with a blank description keeps the product's WooCommerce description, and a Square item with no categories keeps the product's WooCommerce categories. An empty field in Square is usually one nobody filled in there, not a deliberate clear. Return true to bring back the pre-10.4.13 behaviour, where empty Square values wiped the Woo field. Applies to every Square → WooCommerce path (manual import, scheduled sync, real-time webhooks), and only when that field is set to sync from Square.

Location: includes/Woo/CreateProduct.php

ParameterTypeDescription
$allowboolWhether the empty value clears the Woo field (default false)
$fieldstring'description' or 'categories'
$productWC_ProductThe product being updated
// Square is the master for descriptions: clearing one there clears it in WooCommerce.
add_filter('squarewoosync_import_clear_empty_fields', function ($allow, $field, $product) {
    return 'description' === $field ? true : $allow;
}, 10, 3);

squarewoosync_strip_formatting_value

Since 9.14.0. Post-process what the Strip formatting on import setting produced — extend the built-in cleanup, or ignore it and build your own value from the raw Square original. Runs once per enabled field per product, on every Square → WooCommerce path, but only for fields the merchant has ticked under Settings → Products → Import Settings. Returning a non-string leaves the field untouched, and the product name is never allowed to end up empty (an empty name fails import validation).

Location: includes/Common/Helpers.php

ParameterTypeDescription
$strippedstringThe plain-text value the built-in strip produced
$originalstringThe raw value from Square, untouched
$fieldstringField key: 'title' or 'description'
$wc_product_dataarrayFull mapped product data, for context
add_filter('squarewoosync_strip_formatting_value', function ($stripped, $original, $field) {
    if ($field === 'description') {
        $stripped = str_replace('™', '', $stripped); // extend the cleanup
    }
    if ($field === 'title') {
        return ucwords(strtolower($stripped));       // or replace it entirely
    }
    return $stripped;
}, 10, 3);

To transform fields regardless of the merchant setting, use squarewoosync_wc_product_data instead — it runs on every import whether stripping is enabled or not.

squarewoosync_strip_formatting_fields

Since 9.14.0. Register additional fields as eligible for formatting-stripping, or change how the built-in ones are treated. Each entry maps a field key to the mapped-product-data key it lives in and whether line breaks survive (multiline). Note there's no checkbox in the UI for custom fields — a field you register here is only stripped once its key is also enabled in the stored stripFormatting setting.

Location: includes/Common/Helpers.php

ParameterTypeDescription
$fieldsarrayfield key => ['data_key' => key in mapped product data, 'multiline' => bool] map
add_filter('squarewoosync_strip_formatting_fields', function ($fields) {
    // Treat descriptions like titles: collapse them to a single line
    $fields['description']['multiline'] = false;
    return $fields;
});

squarewoosync_import_product_action

Control what happens to each product during manual and scheduled imports: sync it, skip it, trash it, or restore it. Runs before the skip filter.

Location: includes/Square/SquareImport.php

ParameterTypeDescription
$actionstringAction to take: 'sync' (default), 'skip', 'trash', 'untrash'
$square_productarrayRaw Square catalog item
$woo_product_idint|nullLinked WooCommerce product ID, or null if not linked yet
add_filter('squarewoosync_import_product_action', function ($action, $square_product, $woo_product_id) {
    // Trash the Woo product when the Square item is archived
    if (!empty($square_product['item_data']['is_archived'])) {
        return 'trash';
    }
    return $action;
}, 10, 3);

squarewoosync_webhook_product_action

Same as squarewoosync_import_product_action, but for real-time webhook updates — kept separate so the two paths can be controlled independently. Also supports 'create' to force creation.

Location: includes/Jobs/WebhookProcessJob.php

ParameterTypeDescription
$actionstring'sync' (default), 'skip', 'trash', 'untrash', 'create'
$productarraySquare product data from the webhook
$woo_product_idint|nullLinked WooCommerce product ID, or null if not found
add_filter('squarewoosync_webhook_product_action', function ($action, $product, $woo_product_id) {
    // Never let webhooks touch manually curated products
    if ($woo_product_id && get_post_meta($woo_product_id, '_manually_curated', true)) {
        return 'skip';
    }
    return $action;
}, 10, 3);

squarewoosync_product_tax_class

Override the WooCommerce tax class determined from Square tax data.

Location: includes/Woo/CreateProduct.php

ParameterTypeDescription
$tax_classstringDetermined tax class ('' = standard, 'zero-rate', etc.)
$contextarrayis_taxable (bool), tax_ids (array), resolved_tax_rates (array of rates with name and percentage), product (WC_Product), square_data (full mapped product data)
add_filter('squarewoosync_product_tax_class', function ($tax_class, $context) {
    if (empty($context['tax_ids']) && $context['is_taxable']) {
        return ''; // keep standard rate when Square has no tax assigned
    }
    return $tax_class;
}, 10, 2);

squarewoosync_ignore_square_stock

Make specific products ignore inbound stock updates from Square — the inbound half of the product editor's Square stock sync setting (Ignore Square's updates and Paused both turn it on). WooCommerce can still send the item's stock to Square; to stop that too, see squarewoosync_block_stock_push.

Location: includes/Common/Helpers.php

ParameterTypeDescription
$lockedboolWhether the item currently ignores Square stock
$idintProduct/variation post ID
$product_or_idWC_Product|intThe product object or ID that was checked
add_filter('squarewoosync_ignore_square_stock', function ($locked, $id) {
    // Never let Square overwrite stock for pre-order products
    if (has_term('pre-order', 'product_cat', $id)) {
        return true;
    }
    return $locked;
}, 10, 2);

squarewoosync_combine_location_stock

Since 9.9.0. Control per product whether stock is summed across all Square locations or tracked from the primary location only (the per-product counterpart of the global Combine All Location Stock setting). Applies consistently everywhere stock moves: imports, real-time webhooks, order/refund stock pushes, scheduled syncs, and the Stock Checker. Not applied while order splitting by product location is enabled.

Location: includes/Common/Helpers.php

ParameterTypeDescription
$combineboolThe global Combine All Location Stock default
$parent_idintParent/simple product ID — variations are resolved to their parent so category checks just work; 0 when unknown (e.g. first import)
$item_idintThe originally-passed product/variation ID (0 when unknown)
$contextarrayExtra context when available: source, catalog_object_id, square_product
add_filter('squarewoosync_combine_location_stock', function ($combine, $parent_id) {
    // Only combine locations for products in the "Warehouse" category
    if ($parent_id && has_term('warehouse', 'product_cat', $parent_id)) {
        return true;
    }
    return false;
}, 10, 2);

squarewoosync_decimal_stock_supported

Since 10.4.0. Override whether the plugin believes WooCommerce can store fractional stock quantities.

The Decimal stock quantities setting only describes what you want; WooCommerce stores whole numbers unless a decimal-quantities plugin replaces its woocommerce_stock_amount filter. The plugin probes for that at runtime and, when it is missing, runs in whole-number mode rather than computing fractions WooCommerce would silently discard. Use this filter if your decimal-quantities integration works at the data-store layer and the probe cannot see it.

Returning true without real decimal support will cause fractional quantities to be truncated on save with no warning, so only override this when you know the store can hold them.

Location: includes/Common/Helpers.php

ParameterTypeDescription
$supportedboolResult of the wc_stock_amount() runtime probe
add_filter('squarewoosync_decimal_stock_supported', function ($supported) {
    // My decimal-quantities integration filters stock at the data store,
    // so the wc_stock_amount() probe cannot detect it.
    return true;
});

squarewoosync_skip_square_product_import

Skip importing specific products from Square.

Location: includes/Jobs/WebhookProcessJob.php, includes/Square/SquareImport.php

ParameterTypeDescription
$skipboolWhether to skip (default: false)
$productarraySquare product data
add_filter('squarewoosync_skip_square_product_import', function($skip, $product) {
    // Skip products with specific naming pattern
    if (strpos($product['item_data']['name'], '[INTERNAL]') !== false) {
        return true;
    }
    return $skip;
}, 10, 2);

squarewoosync_defer_thumbnail_generation

Control thumbnail generation during product import.

Location: includes/Woo/CreateProduct.php

ParameterTypeDescription
$deferboolWhether to defer (default: true)
add_filter('squarewoosync_defer_thumbnail_generation', function($defer) {
    return false; // Generate thumbnails immediately
});

squarewoosync_custom_attribute_wp_value

Since 10.1.0. Change the value read from a Square custom attribute before it is written to WooCommerce, or return an empty string to skip that attribute entirely. Selection values have already been resolved from UIDs to names by this point.

Location: includes/Woo/CreateProduct.php

ParameterTypeDescription
$valuestringResolved value
$wp_keystringTarget meta key (or pa_ taxonomy) from the mapping
$val_objarrayRaw Square custom attribute value object
$product_objWC_ProductProduct or variation being written
$definitionarraySquare custom attribute definition data
add_filter('squarewoosync_custom_attribute_wp_value', function($value, $wp_key) {
    // Store the "material" attribute lowercased
    if ($wp_key === 'material') {
        return strtolower($value);
    }
    return $value;
}, 10, 2);

squarewoosync_apply_custom_attribute_value

Since 10.1.0. Take over the write for one custom attribute. Return true once you have applied the value yourself and SquareSync will not also store it as post meta. Use this for WooCommerce fields that are not meta at all — the built-in weight binding uses the same mechanism internally.

The product object is saved by SquareSync after every filter has run, so setters are enough — do not call save() yourself.

Location: includes/Woo/CreateProduct.php

ParameterTypeDescription
$handledboolfalse by default
$valuestringResolved value
$wp_keystringTarget meta key from the mapping
$product_objWC_ProductProduct or variation being written
$val_objarrayRaw Square custom attribute value object
$definitionarraySquare custom attribute definition data
add_filter('squarewoosync_apply_custom_attribute_value', function($handled, $value, $wp_key, $product) {
    // Send a "length_cm" custom attribute to the WooCommerce length field
    if ($wp_key === 'length_cm' && is_numeric($value)) {
        $product->set_length((string) $value);
        return true;
    }
    return $handled;
}, 10, 4);

sws_orphan_variation_action

Since 10.4.4. Change what happens to a WooCommerce variation whose Square variation has been deleted.

Editing an item's option set in the Square dashboard deletes its variations and recreates them under new IDs. On the next live sync of that item, the plugin verifies each leftover WooCommerce variation against the Square catalog, and every variation Square explicitly confirms as deleted is acted on: set to draft by default (it can no longer be purchased, but its data and stock are kept), or moved to trash when Square → Woo auto product deletion is enabled. This filter overrides that per variation.

Only variations Square positively reports as deleted ever reach this filter. A variation whose ID is merely missing from Square's response (for example after connecting a different Square account) is never touched.

Location: includes/Woo/CreateProduct.php

ParameterTypeDescription
$actionstring'draft' or 'trash' (from the auto-delete setting); return 'none' to only log
$vidintWooCommerce variation ID
$sidstringThe deleted Square variation ID
$parent_idintParent WooCommerce product ID
add_filter('sws_orphan_variation_action', function ($action, $vid, $sid, $parent_id) {
    // Log the deletions but never modify the store automatically.
    return 'none';
}, 10, 4);

sws_orphan_variation_max_actions

Since 10.4.4. Cap how many deleted-in-Square variations one sync run may act on for a single product.

Past the cap the run stands down with a sync-log warning and leaves everything untouched, pointing at the human-reviewed Tools → Missing Square scan instead. Square items hold at most 250 variations, so a figure past the default cap of 50 usually means something structurally unexpected.

Location: includes/Woo/CreateProduct.php

ParameterTypeDescription
$maxintMaximum variations to act on per run (default: 50)
$parent_idintParent WooCommerce product ID
add_filter('sws_orphan_variation_max_actions', function ($max, $parent_id) {
    return 10;
}, 10, 2);

Product Export Filters (WooCommerce → Square)

squarewoosync_square_custom_attribute_values

Since 10.1.0. Modify the custom attribute values built for a product before they are sent to Square. Use it to export fields the mapping table cannot reach — anything that is not post meta.

Each entry needs a custom_attribute_definition_id that exists in Square plus exactly one of string_value, number_value, boolean_value or selection_uid_values. Entries whose definition ID is unknown to Square are dropped. Runs for the parent product and for each variation separately.

Location: includes/Woo/WooImport.php

ParameterTypeDescription
$entriesarrayBuilt value entries
$productWC_ProductProduct or variation being exported
$definitionsarraySquare definitions, indexed by definition ID
$mappingsarrayConfigured metafield mapping rows
add_filter('squarewoosync_square_custom_attribute_values', function($entries, $product) {
    $length = $product->get_length('edit');
    if ($length !== '') {
        $entries[] = [
            'custom_attribute_definition_id' => 'YOUR_DEFINITION_ID',
            'number_value' => (string) $length,
        ];
    }
    return $entries;
}, 10, 2);

squarewoosync_product_field_attributes

Since 10.1.0. Add a WooCommerce product field to the list offered under Settings → Metafields → WooCommerce Fields, where a merchant picks the Square custom field it syncs with. Weight is built in; this filter registers others.

Each entry needs a getter and setter that exist on WC_Product. With numeric set, values are formatted as decimals on the way out and non-numeric Square values are ignored on the way in.

Location: includes/Common/Helpers.php

ParameterTypeDescription
$fieldsarrayField key => ['label', 'getter', 'setter', 'numeric']
add_filter('squarewoosync_product_field_attributes', function($fields) {
    $fields['length'] = [
        'label'   => 'Length',
        'getter'  => 'get_length',
        'setter'  => 'set_length',
        'numeric' => true,
    ];
    return $fields;
});

squarewoosync_skip_variation_sync

Control whether specific variations should sync to Square.

Location: includes/Woo/SyncProduct.php

ParameterTypeDescription
$skipboolWhether to skip this variation
$variation_idintVariation product ID
$variationWC_ProductVariation object
add_filter('squarewoosync_skip_variation_sync', function($skip, $variation_id, $variation) {
    if ($variation && !$variation->is_in_stock()) {
        return true; // Skip this variation
    }
    return $skip;
}, 10, 3);

squarewoosync_export_html_description

Since 10.2.0. Control whether descriptions are written to Square's rich description_html field (default) or the deprecated plain-text description field, on both new-product exports and pushes to already-linked items. When the rich field is written on a linked-item push, any stale plain description on the Square object is removed so Square derives its own plaintext copy.

Location: includes/Common/Helpers.php

ParameterTypeDescription
$use_htmlboolWhether to write description_html
$productWC_Product|nullProduct being exported (null in rare contexts)
// Revert to the pre-10.2.0 behaviour (plain description field).
add_filter('squarewoosync_export_html_description', '__return_false');

squarewoosync_export_location_ids

Since 10.2.0. Filter the Square location IDs that exported products are scoped to. The default comes from the Export locations setting under Settings → Products → Sync Behavior; an empty array means exported items are made available at all Square locations (the pre-10.2.0 behaviour). Applies to the item and every variation on new-product exports and newly created variations.

Location: includes/Common/Helpers.php

ParameterTypeDescription
$idsstring[]Location IDs; empty = present at all locations
add_filter('squarewoosync_export_location_ids', function ($ids) {
    return ['L123ABC']; // only ever export to this location
});

squarewoosync_export_sold_out_override

Since 10.2.0. WooCommerce products that don't manage stock but are marked Out of stock have no inventory count to push, so exports mark them "sold out" at the export location(s) via a Square location override — otherwise they would stay purchasable in Square POS. Return false to disable that override.

Location: includes/Common/Helpers.php

ParameterTypeDescription
$enabledboolWhether to add the sold_out override
$productWC_ProductProduct or variation being exported
add_filter('squarewoosync_export_sold_out_override', '__return_false');

squarewoosync_block_stock_push

Stop specific products' stock being sent to Square. Since 10.4.22. The outbound half of the product editor's Square stock sync setting (Paused turns it on). A blocked item is skipped by every path that writes stock to Square: real-time pushes after a sale or stock edit, product syncs and exports, order and refund restocks, the delayed-capture correction, and Stock Checker fixes in the WooCommerce wins direction. Other fields (title, price, …) still sync. Pair it with squarewoosync_ignore_square_stock to keep an item's website stock entirely separate from Square.

Location: includes/Common/Helpers.php

ParameterTypeDescription
$blockedboolWhether the item's stock is currently withheld
$idintProduct/variation post ID
$product_or_idWC_Product|intThe product object or ID that was checked
add_filter('squarewoosync_block_stock_push', function ($blocked, $id) {
    // Website-only allocation for click-and-collect items: never send their stock to Square.
    if (has_term('web-allocation', 'product_cat', wp_get_post_parent_id($id) ?: $id)) {
        return true;
    }
    return $blocked;
}, 10, 2);

sws_stock_push_skip_log_window

Change how often the sync log repeats a "Stock change for X not pushed to Square" line. Since 10.4.20. When a WooCommerce stock change is not pushed to Square — real-time sync switched off, the product not linked to a Square item, a Square import or scheduled sync in progress, or the change having come from Square in the first place — the plugin writes one Product Sync log line naming the reason. To keep the log readable the line is repeated at most once per window: 10 minutes per product and reason by default, or 6 hours site-wide for the two settings-off reasons (stock_sync_off, stock_direction_off). Return a smaller number while diagnosing a store, or a larger one to quieten a store that deliberately syncs stock one way.

Location: includes/Woo/SyncProduct.php

ParameterTypeDescription
$windowintSeconds before the same line may be written again (600, or 21600 site-wide)
$reasonstringSkip reason: stock_sync_off, stock_direction_off, not_linked, from_square, square_origin_request, import_running, scheduler_running, push_blocked
$product_idintProduct id, or 0 for a site-wide (settings-off) record
// Log every skipped push while investigating a store.
add_filter('sws_stock_push_skip_log_window', function($window, $reason, $product_id) {
    return 1;
}, 10, 3);

Storefront & Checkout Filters

sws_loyalty_product_excluded

Since 10.4.1. Override whether a product is excluded from earning loyalty points. The plugin already excludes gift card products and anything your Square loyalty program's accrual rule excludes (excluded categories and item variations) — everywhere points are shown or awarded: the cart/checkout "You will earn…" estimates, product page badges, and the point calculation itself. Use this filter to exclude additional products (for example, products Square has no knowledge of) or to force a product back in.

Location: includes/Loyalty/LoyaltyEligibility.php

ParameterTypeDescription
$excludedboolWhether the product earns no points (after the plugin's own rules ran)
$product_idintWooCommerce product or variation ID
$exclusionsarrayThe program's resolved exclusions: item_ids, category_ids, category_names
// Stop a deposit/fee product from earning points:
add_filter('sws_loyalty_product_excluded', function ($excluded, $product_id) {
    if (in_array($product_id, [123, 456], true)) {
        return true;
    }
    return $excluded;
}, 10, 2);

sws_storefront_wording

Since 10.3.0. Override the customer-facing text used on the pickup/delivery date selectors (Blocks and classic checkout), the confirmation lines beneath them, and the "Pickup Information" / "Delivery Information" blocks shown on the thank-you page, in wp-admin and in order emails.

Most stores set this text under Settings → Orders → Storefront Wording — the filter runs after those overrides are merged in, so it is only needed for per-language, per-locale or per-condition rewrites that the UI cannot express. Return the modified map.

Location: includes/Storefront/StorefrontWording.php

ParameterTypeDescription
$resolvedarray<string,string>Full defaults ∪ settings overrides map, keyed by string id. Confirmation strings support {date} / {time}.
$overridesarray<string,string>Raw customer overrides only (before defaults are merged), useful for detecting which fields were customised.

String keys

  • pickup_heading, pickup_date_label, pickup_time_label, pickup_confirmation
  • pickup_info_title, pickup_date_display_label, pickup_time_display_label
  • delivery_heading, delivery_date_label, delivery_choose_label, delivery_confirmation
  • delivery_info_title, delivery_date_display_label
// Rewrite "Pickup" as "Collection" for a specific locale:
add_filter('sws_storefront_wording', function ($resolved, $overrides) {
    if (determine_locale() !== 'en_GB') {
        return $resolved;
    }
    $resolved['pickup_heading']      = 'Select a Collection Time';
    $resolved['pickup_date_label']   = 'Collection Date';
    $resolved['pickup_time_label']   = 'Collection Time';
    $resolved['pickup_confirmation'] = 'Your order will be ready for collection on {date} at {time}. Please bring your order confirmation to the store.';
    $resolved['pickup_info_title']   = 'Collection Information';
    return $resolved;
}, 10, 2);

sws_modifiers_heading

Since 9.10.1. Change or remove the heading shown above the modifier sets on the product page. The default value comes from Settings → Modifiers → Storefront Display (an empty string when the heading is switched off there), so this filter is only needed for conditional or code-managed setups. See the Modifiers guide for the settings-based approach.

Location: includes/Modifiers/ProductModifiers.php

ParameterTypeDescription
$headingstringHeading text (empty string = heading hidden)
$productWC_ProductThe product being viewed
// Different heading for a specific category:
add_filter('sws_modifiers_heading', function ($heading, $product) {
    if (has_term('drinks', 'product_cat', $product->get_id())) {
        return 'Customise your drink';
    }
    return $heading;
}, 10, 2);
 
// Or remove the heading everywhere:
add_filter('sws_modifiers_heading', '__return_empty_string');

squaresync_render_inline_wallets

Since 9.9.2. Control whether the Apple Pay / Google Pay / Afterpay wallet buttons render inside the credit-card payment box on the classic checkout. The plugin itself returns false here when an express-checkout area has already rendered earlier on the page, so wallets never appear twice.

Location: includes/Payments/WC_SquareSync_Gateway.php

ParameterTypeDescription
$renderboolWhether to render wallet buttons in the payment box (default: true)
add_filter('squaresync_render_inline_wallets', '__return_false');

sws_express_checkout_accept_terms

Since 9.9.2. Express wallet sheets (Apple Pay / Google Pay) have no terms-and-conditions checkbox, so by default the plugin treats completing the sheet as acceptance — mirroring other express-checkout gateways. Return false to stop the auto-acceptance; note that express orders will then fail WooCommerce's terms validation unless you handle it another way.

Location: includes/Payments/ExpressCheckout.php

ParameterTypeDescription
$acceptboolWhether completing the wallet sheet counts as accepting terms (default: true)
add_filter('sws_express_checkout_accept_terms', '__return_false');

sws_wallet_default_shipping_option

Since 9.10.8. Control which shipping method is pre-selected when an express wallet sheet (Apple Pay / Google Pay) or the checkout first loads. By default the plugin follows your shipping zone's method order — exactly like standard WooCommerce — with the optional Prefer Delivery Over Pickup setting moving delivery ahead of pickup. The returned value must be one of the available option IDs or it is ignored, and a shopper's own selection is never overridden by this filter.

Location: includes/Payments/WC_SquareSync_Gateway.php

ParameterTypeDescription
$selectedstringOption ID the plugin chose as the default
$option_idsstring[]Every available shipping option ID
$packagearrayThe WooCommerce shipping package
$package_indexintPackage index
// Always default to a specific method when it's available:
add_filter('sws_wallet_default_shipping_option', function ($selected, $option_ids) {
    return in_array('flat_rate:3', $option_ids, true) ? 'flat_rate:3' : $selected;
}, 10, 2);

sws_wallet_pickup_method_ids

Since 9.10.8. Declare which shipping method IDs count as "pickup" for wallet defaulting and the Prefer Delivery Over Pickup setting. Defaults to local_pickup and pickup_location; add your own if you use a custom pickup plugin whose method slug differs.

Location: includes/Payments/ShippingDefaults.php

ParameterTypeDescription
$pickup_method_idsstring[]Method slugs treated as pickup (default: local_pickup, pickup_location)
add_filter('sws_wallet_pickup_method_ids', function ($ids) {
    $ids[] = 'my_custom_pickup';
    return $ids;
});

sws_wallet_prices_include_tax

Since 10.4.17. Control whether the Apple Pay, Google Pay and Afterpay/Clearpay sheets show tax-inclusive amounts. By default the sheet follows WooCommerce → Settings → Tax → "Display prices during cart and checkout": when that is "Including tax", product lines and shipping options are shown with tax included and no separate tax line (what UK and EU shoppers expect — £7.50 delivery rather than £6.25 plus a VAT line); when it is "Excluding tax", lines and shipping are shown ex-tax with a single "Tax" line. The total charged is identical either way; only where the tax is displayed changes. A VAT-exempt customer always sees ex-tax figures.

Location: includes/Payments/WC_SquareSync_Gateway.php

ParameterTypeDescription
$includebooltrue to show tax-inclusive amounts (default: follows the WooCommerce display setting)
// Keep the wallet sheets ex-tax even though checkout displays prices including tax:
add_filter('sws_wallet_prices_include_tax', '__return_false');
 
// Or force tax-inclusive sheets on a store that displays ex-tax prices at checkout:
add_filter('sws_wallet_prices_include_tax', '__return_true');

sws_express_enforce_approved_total

Since 9.10.8. Express checkout orders are verified against what the buyer approved in the wallet sheet: if applying their real address pushes the total above the approved amount, the order is refused instead of being placed at a different price. Return false to disable that check and accept the order at the recalculated total. Refusals are logged under squarewoosync-express in WooCommerce → Status → Logs.

Location: includes/Payments/ExpressCheckout.php

ParameterTypeDescription
$enforceboolWhether to enforce the approved total (default: true)
add_filter('sws_express_enforce_approved_total', '__return_false');

sws_express_approved_total_tolerance

Since 9.10.8. How far above the wallet-approved total an express order may drift before it is refused (only consulted while the check above is enabled). The default 0.01 absorbs pure rounding differences; raise it if your tax setup legitimately produces small recalculation deltas.

Location: includes/Payments/ExpressCheckout.php

ParameterTypeDescription
$tolerancefloatAllowed overage in store currency (default: 0.01)
add_filter('sws_express_approved_total_tolerance', fn () => 0.50);

sws_express_shipping_rate_rematch

Since 10.4.1. Dynamic rate providers such as ShipStation Rates generate a new unique rate ID on every quote, so the shipping method approved in the wallet sheet no longer exists (by ID) once the buyer's full address re-quotes the cart at checkout. When that happens, express checkout re-matches the approved rate to the fresh rate carrying the same label and the same price — a price or label change still refuses the order, and the wallet-approved total is still enforced. Return false to disable re-matching and go back to strict ID matching only. Re-matches and refusals are logged under squarewoosync-express in WooCommerce → Status → Logs.

Location: includes/Payments/ExpressCheckout.php

ParameterTypeDescription
$rematchboolWhether to re-match regenerated rate IDs (default: true)
add_filter('sws_express_shipping_rate_rematch', '__return_false');

Gift Card Balance Filters

These shape the customer-facing gift card list — the [sws_gift_card_balance] shortcode, the Gift Cards tab in My Account, and the sws_get_customer_gift_cards() / sws_get_gift_card_balance() template helpers. See Gift Card Balances.

sws_customer_gift_cards

Since 10.3.5. The final list of gift cards resolved for one customer, after all three sources are merged. Add, remove or re-order entries.

Location: includes/GiftCards/GiftCardAccount.php

ParameterTypeDescription
$cardsarrayNormalised cards (see the doc page for the array shape)
$user_idintWordPress user ID
// Hide physical cards, which a customer cannot use online anyway:
add_filter('sws_customer_gift_cards', function ($cards, $user_id) {
    return array_values(array_filter($cards, function ($card) {
        return 'PHYSICAL' !== $card['type'];
    }));
}, 10, 2);

sws_gift_card_balance_html

Since 10.3.5. The markup [sws_gift_card_balance] is about to return. Wrap it, replace it, or append your own call to action.

Location: includes/GiftCards/GiftCardAccount.php

ParameterTypeDescription
$htmlstringRendered markup
$cardsarrayCards being rendered (empty for the "no cards" state)
$attsarrayResolved shortcode attributes
add_filter('sws_gift_card_balance_html', function ($html, $cards, $atts) {
    if (empty($cards)) {
        $html .= '<p><a href="/shop/gift-cards/">Buy a gift card</a></p>';
    }
    return $html;
}, 10, 3);

sws_gift_card_status_label

Since 10.3.5. The status shown against one card. An ACTIVE card with nothing left on it reads "No balance" rather than "Active"; everything else uses the Square state.

Location: includes/GiftCards/GiftCardAccount.php

ParameterTypeDescription
$labelstringResolved label
$cardarrayNormalised card
add_filter('sws_gift_card_status_label', function ($label, $card) {
    if ('ACTIVE' === $card['state'] && $card['balance_minor'] <= 0) {
        return 'Fully redeemed';
    }
    return $label;
}, 10, 2);

sws_gift_card_account_include_gifted

Since 10.3.5. Whether a card the customer bought and emailed to somebody else appears in their own list. Off by default — the recipient holds that number, and a gift card number can be spent by anyone who reads it.

Location: includes/GiftCards/GiftCardAccount.php

ParameterTypeDescription
$includeboolfalse by default
$user_idintWordPress user ID
// Let buyers see the cards they sent, e.g. to re-read a number to a recipient:
add_filter('sws_gift_card_account_include_gifted', '__return_true');

sws_gift_card_account_include_received

Since 10.3.5. Whether cards somebody else bought and emailed to this account's address appear. On by default. Turn it off if your store allows registration without confirming the email address.

Location: includes/GiftCards/GiftCardAccount.php

ParameterTypeDescription
$includebooltrue by default
$user_idintWordPress user ID
add_filter('sws_gift_card_account_include_received', '__return_false');

sws_gift_card_account_can_view

Since 10.3.5. Whether the current request may read one customer's cards. Allowed for the customer themselves, for shop managers and administrators, and for cron/WP-CLI with nobody logged in; refused otherwise, so a template that passes a user id from the query string cannot leak card numbers.

Location: includes/GiftCards/GiftCardAccount.php

ParameterTypeDescription
$allowedboolResolved from the rules above
$user_idintAccount being read
// Allow a support role to look up a customer's cards:
add_filter('sws_gift_card_account_can_view', function ($allowed, $user_id) {
    return $allowed || current_user_can('view_customer_gift_cards');
}, 10, 2);

sws_gift_card_account_cache_ttl

Since 10.3.5. Seconds a customer's resolved card list is cached. Default 300. Return 0 to disable caching — every page render then makes live Square requests.

Location: includes/GiftCards/GiftCardAccount.php

ParameterTypeDescription
$ttlintSeconds, default 300
$user_idintWordPress user ID
add_filter('sws_gift_card_account_cache_ttl', function ($ttl) {
    return 60;
});

sws_gift_card_account_order_limit

Since 10.3.5. How many of the customer's recent orders are scanned for gift cards. Default 50.

Location: includes/GiftCards/GiftCardAccount.php

ParameterTypeDescription
$limitintOrders, default 50
$user_idintWordPress user ID

sws_gift_card_account_max_lookups

Since 10.3.5. Cap on the number of individual Square balance lookups one render may make for order-sourced cards. Default 15. Raise it for customers who hold many cards, at the cost of a slower first render.

Location: includes/GiftCards/GiftCardAccount.php

ParameterTypeDescription
$maxintLookups, default 15
$user_idintWordPress user ID

sws_gift_card_account_retry_budget

Since 10.3.5. Seconds the Square lookups behind a page render may spend retrying before giving up. Default 5.0, so a Square outage returns an empty list instead of holding the page open through the full back-off ladder.

Location: includes/GiftCards/GiftCardAccount.php

ParameterTypeDescription
$secondsfloatBudget, default 5.0
$user_idintWordPress user ID

sws_gift_card_account_tab_shortcode

Since 10.3.5. The shortcode the My Account tab renders. Use it to print card numbers outright, or to show balances only.

Location: includes/GiftCards/GiftCardAccount.php

ParameterTypeDescription
$shortcodestringShortcode run for the tab body
add_filter('sws_gift_card_account_tab_shortcode', function ($shortcode) {
    return '[sws_gift_card_balance format="table" show_code="full"]';
});

sws_gift_card_account_enabled

Since 10.3.5. Whether customer-facing gift card balances are available at all. Resolved from Enable Square Gift Cards in the gateway settings.

Location: includes/GiftCards/GiftCardAccount.php

ParameterTypeDescription
$enabledboolResolved from the gateway settings
// Members only:
add_filter('sws_gift_card_account_enabled', function ($enabled) {
    return $enabled && current_user_can('read');
});

Automatic Discount Filters

These filters control automatic discount syncing — Square catalog discounts applied at cart and checkout. (Coupon-style codes are a separate feature; see the Discount Code filters below.)

sws_apply_square_discount

Since 9.10.7. Skip a synced Square discount entirely, for the whole cart or storefront. Runs on every path a discount is applied or displayed: cart-level fees, line-item pricing, and catalogue price display.

Location: includes/Discount/DiscountApplicator.php

ParameterTypeDescription
$applyboolWhether to apply this discount (default: true)
$discarrayThe Square discount object, including discount_data and pricing_rules
$cartWC_Cart|nullThe cart, or null on catalogue/display paths
// Only apply the "Happy Hour" discount between 3pm and 6pm site time
add_filter('sws_apply_square_discount', function ($apply, $disc, $cart) {
    if (($disc['discount_data']['name'] ?? '') === 'Happy Hour') {
        $hour = (int) current_time('G');
        return $hour >= 15 && $hour < 18;
    }
    return $apply;
}, 10, 3);

sws_product_matches_discount

Since 9.10.7. Exclude individual products or categories from a specific discount — or force-include them. Runs after the plugin's own matching (including any excluded items configured on the Square rule), so whatever you return is final. For whole-purchase percentage discounts, products excluded here are also left out of the cart subtotal the discount is calculated from.

Location: includes/Discount/DiscountApplicator.php

ParameterTypeDescription
$matchesboolWhether the product matched the discount's pricing rule
$productWC_ProductThe product or variation being priced
$discarrayThe Square discount object, including discount_data and pricing_rules
$cat_namesstring[]Lower-cased category names of the product (variation-safe)
add_filter('sws_product_matches_discount', function ($matches, $product, $disc, $cat_names) {
    // Never discount gift cards
    if (in_array('gift cards', $cat_names, true)) {
        return false;
    }
    // Exclude one specific product from the "Storewide Sale" discount only
    if (($disc['discount_data']['name'] ?? '') === 'Storewide Sale' && $product->get_id() === 123) {
        return false;
    }
    return $matches;
}, 10, 4);

sws_discount_priority

Set the priority for discount calculations.

Location: includes/Discount/DiscountApplicator.php

ParameterTypeDescription
$priorityintCalculation priority (default: 99)
add_filter('sws_discount_priority', function($priority) {
    return 50; // Run earlier in the calculation chain
});

Discount Code Filters

sws_discount_codes_square_version

Since 9.10.0. Override the Square-Version header sent to Square's Discount Codes (beta) endpoints, in case Square moves the beta to a newer API version before the plugin updates.

Location: includes/DiscountCodes/DiscountCodesClient.php

ParameterTypeDescription
$versionstringRFC date string, e.g. '2019-06-12'
add_filter('sws_discount_codes_square_version', function ($version) {
    return '2026-08-01';
});

Customer Filters

squarewoosync_create_square_customer_payload

Modify customer data before creating a Square customer.

Location: includes/Customer/Customers.php

ParameterTypeDescription
$payloadarrayCustomer data payload
$user_idintWordPress user ID
$settingsarrayPlugin settings
add_filter('squarewoosync_create_square_customer_payload', function($payload, $user_id) {
    $payload['note'] = 'VIP Customer';
    return $payload;
}, 10, 2);

squarewoosync_square_customer_payload

Modify customer payload during sync operations.

Location: includes/Customer/Customers.php

ParameterTypeDescription
$payloadarrayCustomer data payload
$customerWP_UserWordPress user object
$settingsarrayPlugin settings
add_filter('squarewoosync_square_customer_payload', function($payload, $customer, $settings) {
    // Add custom note during sync
    $payload['note'] = 'Synced from WooCommerce';
    return $payload;
}, 10, 3);

sws_customer_managed_roles

Control which WordPress roles Square group syncing is allowed to remove from a user.

Since 10.4.7.

Location: includes/Customer/Customers.php

By default this is every role that has a Square customer group mapped to it in Settings → Customers → Role Mapping. Roles outside the list are only ever added, never taken away — so a Shop Manager who is also a Customer keeps both roles through every sync, match and webhook. Narrow the list to protect a mapped role from ever being removed automatically.

ParameterTypeDescription
$managed_rolesarrayRole slugs the plugin may remove
$user_idintWordPress user ID being updated
$settingsarrayFull plugin settings array
// Never let a Square group change take the 'wholesale' role away,
// even though it is mapped to a group.
add_filter('sws_customer_managed_roles', function($roles) {
    return array_diff($roles, ['wholesale']);
});

sws_additional_roles_ui_enabled

Show or hide the plugin's own Additional Roles check-boxes on the WordPress user profile screen.

Since 10.4.7.

Location: includes/Admin/Helpers/LegacyAdminHelpers.php

The field stands down automatically when a dedicated role manager (User Role Editor, PublishPress Capabilities, Members) is active, because two multi-role editors on the same profile form fight: ours is drawn before the save, so a role ticked in the other plugin arrives unticked in ours. Use this filter to force the field on or off.

ParameterTypeDescription
$enabledboolWhether to render and save the field
// Keep SquareSync's Additional Roles field even with a role manager installed.
add_filter('sws_additional_roles_ui_enabled', '__return_true');

Queue & System Filters

sws_base_capability

Change the WordPress capability that gates access to the SquareSync dashboard, its REST API and its admin menu. Since 10.4.2. The default capability, manage_squaresync_for_woo, is granted once to administrators, shop managers and any role that could already reach the plugin; role managers such as User Role Editor can then grant or revoke it per role. While the capability is not present on any role, the legacy manage_woocommerce/manage_options check applies instead, so a site can never lock itself out entirely.

Location: includes/Permissions/BaseCapability.php

ParameterTypeDescription
$capabilitystringCapability name (default manage_squaresync_for_woo)
add_filter('sws_base_capability', function($capability) {
    return 'my_store_sync_access';
});

sws_api_controllers

Register custom REST API controllers.

Location: includes/REST/Api.php

ParameterTypeDescription
$controllersarrayArray of controller classes
add_filter('sws_api_controllers', function($controllers) {
    $controllers[] = 'My_Custom_Controller';
    return $controllers;
});

sws_redis_config

Configure Redis connection for queue processing.

Location: includes/Queue/QueueConnectionResolver.php

ParameterTypeDescription
$configarrayRedis configuration
add_filter('sws_redis_config', function($config) {
    $config['host'] = 'redis.example.com';
    $config['port'] = 6380;
    return $config;
});

sws_is_local_development

Override local development detection for queue configuration.

Location: includes/Queue/QueueConnectionResolver.php

ParameterTypeDescription
$is_localboolWhether environment is local
add_filter('sws_is_local_development', function($is_local) {
    return false; // Force production queue behavior
});

sws_allowed_job_classes

Restrict or extend allowed job classes for queue security.

Location: includes/Queue/QueueConnectionResolver.php

ParameterTypeDescription
$allowed_jobsarrayArray of allowed job class names
add_filter('sws_allowed_job_classes', function($allowed_jobs) {
    $allowed_jobs[] = 'My_Custom_Job';
    return $allowed_jobs;
});

Best Practices

Always Return Values

Filters must return the modified (or unmodified) data:

add_filter('squarewoosync_prepare_order_data', function($order_data, $wc_order) {
    // Make modifications
    $order_data['order']['metadata']['custom'] = 'value';
 
    // Must return the data!
    return $order_data;
}, 10, 2);

Validate Data

Always check data types before modifying:

add_filter('squarewoosync_prepare_order_data', function($order_data, $wc_order) {
    if (!$wc_order instanceof WC_Order) {
        return $order_data;
    }
    // Safe to proceed
    return $order_data;
}, 10, 2);

Handle Errors Gracefully

Wrap modifications in try-catch blocks:

add_filter('squarewoosync_prepare_order_data', function($order_data, $wc_order) {
    try {
        // Your modifications
    } catch (Exception $e) {
        error_log('SquareSync filter error: ' . $e->getMessage());
    }
    return $order_data;
}, 10, 2);