Dynamic Pricing Engine — Complete guide
Complete guide: install, 4 rule types, segments, competitor scraping, A/B testing, 3-level safeguards.
Welcome to the complete documentation for Dynamic Pricing Engine, the dynamic pricing engine for WooCommerce by DataFirefly. This guide covers installation, initial configuration, each rule type, customer segmentation, competitor scraping, A/B testing, logging, safeguards, and uninstallation.
Requirements: WordPress 6.0+, WooCommerce 8.0+, PHP 7.4+. HPOS and Checkout Blocks compatible.
Installation
Uploading the plugin
- From the WordPress back-office, go to Plugins → Add New → Upload Plugin.
- Select the
dfdynamicpricing.zipfile and click Install Now. - Once installation completes, click Activate Plugin.
What happens on activation
The plugin creates 6 custom tables (prefixed wp_dfdpe_):
wp_dfdpe_rules— pricing ruleswp_dfdpe_logs— adjustment logwp_dfdpe_segments— customer segments (3 seeded automatically)wp_dfdpe_competitors— competitor trackingwp_dfdpe_ab_tests— A/B testswp_dfdpe_ab_events— exposure, ATC, and conversion events
Two cron tasks are also scheduled: competitor scraping (hourly by default) and log purging (daily).
Admin menu
A new Dynamic Pricing menu appears in the sidebar with 7 sub-menus: Dashboard, Rules, Segments, Competitors, A/B Testing, Log, Settings. All actions require the WordPress capability manage_woocommerce.
Initial configuration (Settings)
Before creating your first rule, take a quick tour in Dynamic Pricing → Settings to adjust the global parameters.
Log
- Enable log: checked by default. Every adjustment is recorded with product, rule, customer, context.
- Retention (days): 60 days by default. Automatic purge runs daily.
The log is rate-limited to 1 entry per session, product, and hour to avoid flooding. You can disable it entirely if you don’t use it.
Global safeguards
- Floor price (% of original price): e.g., 70 = never go below 70% of the original price. 0 = disabled.
- Ceiling price (% of original price): e.g., 130 = never exceed 130%. 0 = disabled.
- Never sell below cost of goods: enable if you store the cost in a product meta.
- Cost meta key:
_costby default (compatible with WooCommerce Cost of Goods).
Competitor scraper
- Execution frequency: hourly, twice daily, or daily. The scraper processes 25 URLs per batch.
Front-office display
- Show original price crossed out: useful for a visible promo effect. Disable for confidential A/B tests.
Creating your first rule
Go to Dynamic Pricing → Rules → Add. Each rule has the same base fields, regardless of its type.
Common fields
- Name: internal label, useful in the log (e.g., “Happy hour 6pm-8pm”).
- Type: Time, Stock, Customer Segment, or Competitor.
- Status: Active or Inactive. An inactive rule is never evaluated.
- Priority: rules execute in ascending priority order. Each rule works on the result of the previous one.
- Scope: Global, Category, Tag, or Specific product.
- Adjustment: Percentage, Fixed amount, Set value, or Competitor match (only with Competitor type).
- Floor / Ceiling: optional per-rule safeguards.
- Date window: start and end dates to activate the rule only during a given period.
- A/B Test: optional link to an A/B test and variant (see A/B Testing section).
Prioritization tip: start with broad (global) rules at low priority, then refine with targeted rules at higher priority. The global safeguards configured in Settings always apply last.
Type 1 — Time rule
Adjusts the price based on the hour and day of the week. Ideal for happy hour, weekend promos, or night rates.
Available conditions
- Days of the week: select one or more days (Monday to Sunday, ISO format).
- Start hour / End hour: 24h format. Ranges that cross midnight are handled automatically (e.g., 10pm-2am).
- Timezone: site (default, uses the WordPress timezone) or a specific timezone (e.g.,
Europe/Paris).
Concrete examples
- Happy hour: −15%, Thursday-Friday, 6pm-8pm, Europe/Paris timezone.
- Weekend promo: −10%, Saturday-Sunday, 00h-23h59.
- Night pricing: +5%, every day, 10pm-6am (crosses midnight, handled automatically).
Type 2 — Stock rule
Adjusts the price based on the product stock level. Useful for quickly clearing overstocked products or premium-pricing scarce ones.
Available conditions
- Operator: <, <=, ==, >=, >.
- Threshold: integer.
- Mode: Absolute (number of units) or Percentage of initial stock (requires the
_initial_stockmeta on the product).
Concrete examples
- Clearance: stock >= 50 (overstock) → −20%.
- Scarcity: stock < 5 → +10%.
- Initial stock percentage: percentage mode, stock < 20% of initial stock → −5%.
To use Percentage mode, add an _initial_stock meta field to your products (via WP All Import, ACF, or a simple update_post_meta). Without this meta, percentage mode is ignored.
Type 3 — Customer segment rule
Applies an adjustment only to customers belonging to one or more defined segments.
Available conditions
- Segments: one or more existing segments (see Segments section).
- Match: Any (customer belongs to at least one segment) or All (belongs to all).
Concrete examples
- Loyalty: loyal-customers segment, −10% adjustment.
- Win-back: dormant segment (to create), −20% adjustment for 7 days.
- B2B: b2b segment (
wholesalerole), −25% adjustment.
Type 4 — Competitor price rule
Aligns your price with a competitor you have configured in the Competitors section. Three strategies available.
Strategies
- Match: your price becomes exactly the competitor’s price.
- Undercut: your price drops below the competitor’s, by percentage or fixed amount.
- Overprice: your price goes above the competitor’s (premium positioning).
Available conditions
- Mode: Percentage or Fixed amount.
- Amount: percentage (e.g., 5 for 5%) or amount in currency.
- Maximum data age (hours): beyond this, scraped data is considered too old and the rule switches to fallback behavior.
- Fallback: behavior when competitor data is unavailable (e.g., apply a neutral adjustment or skip the rule).
Concrete example
Undercut 3% of Competitor A, with a 6-hour max age. If Competitor A hasn’t been scraped in 6 hours, the rule is ignored and the price stays unchanged.
Customer segments
A segment is a combination of criteria defining a group of customers. Once created, a segment can be targeted by a rule of type Customer segment.
Segments seeded on activation
- new-customers: customers with 0 or 1 order.
- loyal-customers: customers with 5 or more orders.
- vip: customers who have spent at least €500.
Creating a segment
From Dynamic Pricing → Segments → Add, define:
- Name and Slug (auto-generated if empty).
- Description (optional, for your team).
- Criteria: add as many rows as needed. All criteria must be satisfied (AND logic).
- Status: active or inactive.
Available criteria fields
order_count— customer’s order count.total_spent— total spent (in the site currency).is_guest— 1 if visitor is not logged in, 0 otherwise.user_roles— customer’s WordPress roles (e.g.,customer,subscriber,wholesale).days_since_last_order— days since the last order.
Available operators
Ten operators: ==, !=, >, >=, <, <=, in, not_in, contains, not_contains.
For in and not_in, separate values by commas in the Value field (e.g., customer,subscriber).
Advanced example — “Win-back” segment: order_count >= 2 + days_since_last_order >= 60. Targets previous customers who haven’t ordered in 2 months.
Competitors (scraping)
The scraper automatically retrieves the price displayed on a competitor’s product page, at a configurable frequency. Scraped prices are then used by rules of type Competitor.
Adding a competitor
From Dynamic Pricing → Competitors → Add:
- WooCommerce product (ID): the local product ID to link the tracking to.
- Competitor name: free label (e.g., “Amazon”, “eBay”).
- URL: the competitor’s product page to scrape.
- Selector type: CSS, XPath, Regex, or JSON-LD.
- Selector: the selector pointing to the price (see examples below).
- Currency: defaults to the site’s WooCommerce currency.
- Status: active or paused tracking.
Selector types
- CSS: classic CSS selector. Examples:
.price .amount,#product-price,span[itemprop=price]. - XPath: XPath expression. Example:
//span[@class="price"]. - Regex: PHP regular expression. Example:
/€s*([d,.]+)/— the first captured group is used. - JSON-LD: Schema.org auto-detection. Searches for
price,offers.price,offers.lowPricein JSON-LD tags. Leave the Selector field empty.
Price parsing
The scraper handles European (1 299.90) and US (1,299.90) formats automatically. Currency symbols and spaces are cleaned up.
Manual execution
The Scrape now button next to each competitor forces an immediate AJAX update. Useful for testing a new selector.
Possible statuses
- pending — never scraped, waiting for next cron.
- ok — last run succeeded.
- error — last run failed (message stored in the last_error field).
Respect competitor T&Cs: the scraper performs a simple HTTP request with a short timeout, but it’s your responsibility to check that scraping is allowed by the target sites’ Terms of Service. Some jurisdictions regulate this practice.
A/B Testing
The built-in A/B module lets you compare multiple pricing strategies on the same product and measure their impact in real time (exposures, add-to-cart, conversions, RPV).
Creating a test
From Dynamic Pricing → A/B Testing → New test:
- Name and slug.
- Variants: list of labels separated by commas. Default
A,B. - Traffic split: relative weight per variant (auto-normalized). For example
50/50,70/30, or1/1/1for three even variants. - Status: Draft, Running, Paused, or Completed. Only Running tests assign visitors.
- Window: optional start and end dates.
Linking a rule to a variant
In the rule form, select the A/B test and the target variant. The rule will only apply to visitors assigned to that specific variant.
How assignment works
On first exposure, the plugin assigns the visitor to a variant according to configured weights, then stores this choice in a dfdpe_ab cookie. A separate session cookie dfdpe_sid tracks the same visitor throughout their session, logged in or not.
Tracked events
- exposure — first time the visitor sees a price affected by the test.
- atc — add to cart (
woocommerce_add_to_carthook). - conversion — finalized order (
woocommerce_thankyouhook). The order total is recorded.
Calculated metrics (Results page)
- Exposures and Unique sessions.
- ATC CR — add-to-cart rate (ATC / exposures).
- Conv. CR — conversion rate (conversions / exposures).
- Revenue — total conversions.
- RPV — revenue per visitor (revenue / exposures). This is the key decision metric: the variant with the highest RPV is highlighted automatically (Winner badge).
Best practice: let a test run for at least 2 weeks before concluding. A reliable A/B test requires several thousand exposures to reach statistical significance.
Adjustment log
Every price adjustment applied on the front-office can be logged. The log is accessible via Dynamic Pricing → Log.
Recorded information
- Date and time.
- Product and variation.
- Triggered rule (ID).
- Customer (ID) or anonymous session.
- Original price, final price, adjustment amount.
- A/B test and variant (if applicable).
- Context:
frontend,cart,checkout.
Available filters
You can filter by product ID, rule ID, or A/B test ID. Pagination shows 50 entries per page.
Rate-limiting
To avoid flooding, the plugin limits recording to 1 entry per session, product, and hour. A session viewing the same product page 100 times within an hour generates only one row.
Automatic purge
A daily cron task (dfdpe_cron_purge_logs) deletes entries older than the configured retention (60 days by default).
Safeguards: how they work
Three successive levels of protection prevent your final price from reaching a dangerous level.
Level 1 — Per-rule safeguards
Each rule can define its own floor and ceiling. They apply immediately after this rule’s adjustment. Useful for capping the effects of a specific rule (e.g., “happy hour can never drop below €30, regardless of original price”).
Level 2 — Global safeguards
Defined in Settings, as a percentage of the original price:
- Floor price: the final price cannot drop below this percentage.
- Ceiling price: the final price cannot exceed this percentage.
Example: 70% floor and 130% ceiling. A €100 product can never drop below €70 nor exceed €130, whatever rules are applied.
Level 3 — Cost-of-goods protection
If enabled in Settings, this protection prevents the final price from dropping below the value of the _cost meta (or the custom key you configure). This is the ultimate guarantee against selling at a loss.
The three levels are cumulative and apply in this order: rule → global → cost. The final price is always the most “protected” of the three results.
HPOS and cache compatibility
HPOS (High-Performance Order Storage)
The plugin declares compatibility with custom_order_tables and cart_checkout_blocks at initialization. No additional action is required if you have enabled HPOS in WooCommerce.
Variation price cache
WooCommerce caches the min and max prices of variable products via a hash. The plugin injects a dynamic seed (user + session + 5-minute bucket) into this hash via the woocommerce_get_variation_prices_hash filter, forcing WooCommerce to recalculate prices at the right moment without breaking the cache for other visitors.
FAQ
Can I combine multiple rules on the same product?
Yes. Rules execute in priority order, each working on the previous one’s result. You can chain “−10% VIP” then “cap at 130% of cost”.
Do rules apply to cart and checkout too?
Yes. A hook on woocommerce_before_calculate_totals recalculates cart line prices on every display.
Is the plugin compatible with server caches (Redis, Varnish)?
Yes, but if your cache is very aggressive at the full-page level, displayed prices may be cached ones. For reliable dynamic display, exclude product pages from full-page cache, or use ESI fragments.
Can I deactivate the plugin without losing my rules?
Yes. Deactivation does not delete any data. Only uninstalling via Plugins → Delete triggers the uninstall.php script.
How do I export my data?
All data is stored in the 6 wp_dfdpe_* tables. You can export them via phpMyAdmin, WP-CLI (wp db export), or any WordPress backup tool.
Uninstalling
To completely uninstall:
- Deactivate the plugin from Plugins.
- Click Delete.
The uninstall.php script then removes:
- The 6
wp_dfdpe_*tables. - The 9 WordPress options created.
- The scheduled cron tasks.
Uninstallation is definitive and non-reversible. Back up your rules, segments, and log first if you want to be able to roll back.
Support
Your license includes 12 months of support and updates. For any question, contact us via datafirefly.com/contact.