---
title: "Hooks and filters"
description: "The public extension contract the free plugin exposes — the same one Pro is built on."
url: "https://maksut.net/price-anchor/docs/hooks-and-filters/"
language: "en-US"
datePublished: "2026-08-02T00:35:16+00:00"
dateModified: "2026-10-10T08:40:01+00:00"
---

# Hooks and filters

Pro consumes only this contract. Anything you build against it is on the same footing as the commercial add-on, and a signature change here bumps Pro’s major version.

## Lifecycle

| Hook | Type | Purpose |
| --- | --- | --- |
| `panchor_loaded` | action | The free plugin’s services are constructed and ready. Boot your add-on here. |

## Rates

| Hook | Type | Purpose |
| --- | --- | --- |
| `panchor_rate_providers` | filter | Register an additional rate provider. |
| `panchor_pre_apply_rates` | filter | Inspect or hold a fetched rate table before it is stored. This is where Rate Guard lives. |
| `panchor_rates_updated` | action | A validated table was stored. Rate history, the audit log and sync triggers all listen here. |
| `panchor_fetch_failed` | action | A provider failed. Used for alerting. |
| `panchor_rate_stale` | action | The stored table is older than the configured warning threshold. |

## Pricing

| Hook | Type | Purpose |
| --- | --- | --- |
| `panchor_markup` | filter | Substitute the markup for this calculation. Pro’s per-product and per-category markup uses this. |
| `panchor_calculated_price` | filter | Adjust the calculated price before it is written. Pro’s margin floor uses this. |
| `panchor_rounding_strategies` | filter | Register rounding modes the enum cannot express. |
| `panchor_should_reprice` | filter | Veto a write for a specific product. Pro’s price freeze uses this. Fired by the price writer, with two parameters. |
| `panchor_price_written` | action | A native price field was written. The audit log listens here. |

## Currencies and sync

| Hook | Type | Purpose |
| --- | --- | --- |
| `panchor_supported_currencies` | filter | Widen the set of currency codes the plugin recognises. |
| `panchor_source_currencies` | filter | Extend the source currencies a product may use. Pro’s additional sources use this. |
| `panchor_sync_batch_size` | filter | Tune the repricing batch size for constrained hosting. |

## Admin and security

| Hook | Type | Purpose |
| --- | --- | --- |
| `panchor_settings_tabs` | filter | Add a capability-gated tab to the Price Anchor screen. |
| `panchor_security_event` | action | A boundary decision was recorded. Adapt to an external SIEM here. |
| `panchor_security_alert` | action | Correlated repeated failures crossed an alerting threshold. |
| `panchor_product_rest_meta_changed` | action | Source pricing meta was changed through the REST API. |
| `panchor_show_upgrade_prompts` | filter | Suppress the contextual Pro discovery prompts. Pro sets this to false while active. |
| `panchor_upgrade_url` | filter | Repoint the upgrade destination for distribution or white-label use. Only HTTPS destinations render. |
| `panchor_upgrade_catalog_threshold` | filter | Change the catalogue size at which the scale-based prompt appears. Default 50. |

## Rules for extending safely

- **Never write WooCommerce’s native price fields yourself.** One class owns that write. A second writer reintroduces every bug the architecture removes.
- **Do not filter `woocommerce_product_get_price`** to reconvert. There is nothing to reconvert; the stored price is already correct.
- **Return finite, non-negative numbers** from any pricing filter. A rounding strategy in particular is required to.
- **Keep the storefront clean.** Anything you hang off these hooks should be inert on a normal page view.
