XC Tiered Pricing v1.0.0 · Documentation

XaniaCode · WooCommerce extension

XC Tiered Pricing

A complete rule engine for quantity discounts, B2B pricing tiers, and scheduled promotions in WooCommerce. This guide covers everything from server requirements through to developer hooks.

Version
1.0.0
Released
April 25, 2026
Audience
Store owners & developers

01 — SetupServer requirements

XC Tiered Pricing is a standard WordPress plugin and runs anywhere modern WooCommerce runs. The list below reflects the minimum tested versions. Newer versions are always recommended.

ComponentMinimumRecommended
WordPress6.0Latest stable
PHP8.18.2 or newer
WooCommerce8.0Latest stable
MySQL / MariaDBMySQL 5.7 / MariaDB 10.4MySQL 8 / MariaDB 10.6+
HTTPSRequired for license activationRequired for license activation
PHP memory_limit128 MB256 MB

Browser support

The admin interface targets evergreen browsers from mid-2023 onwards: Chrome 111+, Edge 111+, Firefox 113+, Safari 16.2+. Older browsers will still load the plugin but some visual refinements (such as color-mix() tinting on the frontend) fall back to neutral defaults.

Theme & builder compatibility

The plugin uses standard WordPress and WooCommerce hooks, so it is theme-independent and works alongside the major page builders.

  • Gutenberg block editor
  • Elementor (free & Pro)
  • Divi
  • Beaver Builder
  • Bricks

WooCommerce features

  • HPOS (High-Performance Order Storage) — declared compatible
  • Cart & Checkout Blocks — declared compatible
  • Variable products & variations — fully supported
  • Sale prices — excluded from tiered discounts by default; per-rule override available
  • Multi-currency — works with any extension that filters woocommerce_product_get_price
Note

WordPress Multisite is supported. Each network site needs its own license activation, since rules and settings are site-scoped.

02 — SetupInstallation

Install XC Tiered Pricing the same way you install any premium WordPress plugin. The whole process — including license activation — takes about three minutes.

Upload & activate

  1. Download the plugin ZIP After purchase, you receive an email with a download link. The same link is always available under My Account → Downloads on xaniacode.com. Keep the ZIP — you can re-download a fresh copy at any time.
  2. Upload via WordPress admin In WordPress, go to Plugins → Add New → Upload Plugin. Select the ZIP file (do not unzip it locally) and click Install Now. WordPress accepts ZIPs up to the value of upload_max_filesize, so a default 2 MB host is more than enough.
  3. Activate the plugin When the upload finishes, click Activate Plugin. The plugin creates two database tables (wp_xc_tp_rules and wp_xc_tp_logs) and adds a top-level Tiered Pricing menu in the WordPress admin sidebar.
  4. Confirm activation You should see a green admin notice and the Tiered Pricing menu on the left. The dashboard opens with empty stat cards — that is expected on a fresh install.
Tip

If you maintain multiple staging sites, install the same ZIP on each one. Staging and development sites that share a root domain are covered by a single license.

License activation

Until activated, the plugin runs in a limited mode and displays an admin notice asking for your key. Activation unlocks plugin updates and full functionality.

  1. Open the License screen Go to Tiered Pricing → License. The submenu appears under the main plugin menu.
  2. Paste your license key The key is a 32-character alphanumeric string sent to you by email after purchase. You can also find it under My Account → Licenses on xaniacode.com.
  3. Click Activate The plugin contacts the XaniaCode license server over HTTPS, validates the key, and binds it to your site URL. On success, the screen shows the activation date and remaining support window.
Warning

If the activation request fails, your server probably blocks outbound HTTPS to xaniacode.com. See License will not activate in Troubleshooting.

03 — Quick startBuild your first rule

This walkthrough creates a "buy 10, save 10%" rule on every product in the store. Total time: about ninety seconds.

  1. Open the rule editor Go to Tiered Pricing → Rules and click Add New. The rule editor opens with a blank form and an empty tier table.
  2. Name the rule and pick a discount type Type a name like Volume retail — 10%. Leave Discount type on Percentage off. Set Apply to to All products. Leave Quantity scope on Per product.
  3. Add the tier In the Tiers table, click + Add tier. Set Min qty to 10, leave Max qty at 0 (which means unbounded), and set Value to 10. With the discount type set to percentage, the value 10 is interpreted as 10%.
  4. Test in the live preview In the Live preview card, type a base price (for example 50) and a quantity (10). The preview shows the per-unit price, total savings, and percentage discount applied.
  5. Save the rule In the right sidebar, leave Status on Active and click Create rule. You return to the rules list with the new rule visible at the top.
  6. Verify on the storefront Open any product page on the frontend. A pricing table titled Volume discounts appears below the product summary, showing the discount applied at qty 10 and above. Add 10 of the product to the cart to see the savings notice.
Tip

That is the entire workflow. Every rule you create — from simple percentage tiers to role-restricted B2B pricing scheduled for a specific window — follows the same pattern.

04 — ReferenceSettings reference

Settings are grouped into four tabs, found under Tiered Pricing → Settings. Every option below is documented with its default value and effect.

Display tab

Controls where and how pricing tables and notices appear on the storefront.

SettingDefaultEffect
Show pricing table Enabled Renders the tiered pricing table on every product page where at least one rule applies.
Position After product summary Choose where the table appears: before summary, after summary, after add-to-cart button, or after the product tabs.
Style Modern One of four presets: Modern, Minimal, Bordered, Striped. All four inherit the theme's typography.
Show savings column Enabled Shows the per-unit saving and percentage in a third column. Disable for a compact two-column table.
Highlight active tier Enabled Highlights the row matching the current quantity input on the product page. Updates live as the customer changes quantity.
Show shop badge Disabled Adds a small Bulk discount badge next to the price on shop archive listings.
Show cart notice Enabled Displays a success notice in the cart when a customer's purchase qualifies for a tiered discount.
Show next-tier notice Enabled Encourages customers to add a few more units to unlock a bigger discount.
Primary color Empty (inherit theme) Optional brand colour used for the active tier highlight and the next-tier notice. Leave empty to inherit the theme's text colour.
Accent color Empty (inherit theme) Optional accent used for the savings figure and the cart success notice. Leave empty to inherit.

Labels tab

Customise every customer-facing string. All fields support the placeholders listed below.

FieldDefault
Pricing table titleVolume discounts
Quantity columnQuantity
Price columnPrice
Savings columnYou save
Cart notice templateYou saved {amount} thanks to your bulk discount!
Next-tier notice templateAdd {extra} more of {product} to unlock a bigger discount.
Discount label format-{value}

Available placeholders

  • {amount} — total savings for the order, formatted with the store currency
  • {extra} — number of extra units needed to reach the next tier
  • {product} — product name (next-tier notice only)
  • {value} — the raw discount value, used in the discount label

Behaviour tab

Controls how the engine evaluates rules at runtime.

SettingDefaultEffect
Apply to sale items Disabled By default, products with an active sale price are excluded from tiered discounts to prevent stacking. Enable to allow tiers to discount sale prices further.
Enable logging Enabled Records every rule application in wp_xc_tp_logs. Used by the dashboard for usage statistics. Older entries are trimmed automatically.

Advanced tab

Lifecycle and clean-up options.

SettingDefaultEffect
Remove data on uninstall Disabled When enabled and the plugin is deleted via Plugins → Delete, all rules, logs, and settings are wiped. Disabled by default for safety.
Warning

The Remove data on uninstall option is irreversible. Once activated and the plugin is deleted, there is no way to recover rules without a database backup.

05 — ReferenceBuilding rules

A rule is the unit of pricing logic. Every rule has a name, a discount type, a list of tiers, a target, optional restrictions, and a status. The sections below break down each piece.

Rule anatomy

Name
Internal label shown in the admin. Customers never see it.
Internal description
Notes for your team, shown only in the admin.
Discount type
How the discount is calculated — see Discount types.
Tiers
Quantity thresholds and the value applied at each — see Tiers.
Apply to
Which products the rule targets — see Targeting.
User roles
Optional list of WordPress roles that can use the rule. Empty means everyone.
Date range
Optional start and end timestamps for scheduled promotions.
Min subtotal
Optional cart subtotal threshold.
Combine with others
Whether this rule stacks with other matching rules or wins outright.
Priority
Lower number = higher priority. Used to break ties between competing rules.
Status
Active or inactive. Inactive rules are skipped by the pricing engine.

Discount types

Five discount types cover the common pricing models:

TypeTier value meansEffect
Percentage off
percentage
Percentage Subtracts the percentage from the per-unit price. 10 = 10% off.
Fixed amount off
fixed_discount
Currency amount Subtracts a fixed amount from each unit. 5 on a €50 item = €45 per unit.
Fixed price per unit
fixed_price
Currency amount Sets the unit price to this exact value. 40 = every unit costs €40.
Cart discount – percentage
cart_percentage
Percentage Applies a percentage discount to the matching items at the cart-total level. Useful for "10% off when you buy 50+ across the store" promotions.
Cart discount – fixed amount
cart_fixed
Currency amount Applies a fixed currency discount at the cart level once the tier qty is reached.

Worked example

Base price €100, customer buys 10 units:

  • Percentage 10% → €90 per unit, line total €900, savings €100
  • Fixed amount off €5 → €95 per unit, line total €950, savings €50
  • Fixed price €80 → €80 per unit, line total €800, savings €200
  • Cart percentage 10% → €100 per unit, line total €900 after cart discount
  • Cart fixed €100 → €100 per unit, line total €900 after €100 off the cart

Targeting

Each rule targets one of four product scopes:

Apply toWhat you selectWhen to use
All products Storewide volume promotions (Black Friday, B2B blanket pricing)
Specific products One or more products via the searchable picker Bestseller incentives, individual SKU promotions
Product categories One or more WooCommerce categories Section-wide pricing (Apparel −10%, Hardware −15%)
Product tags One or more product tags Cross-cutting groupings (everything tagged clearance)
Note

Variable products can be targeted as a whole or by individual variation. Selecting the parent product in the picker covers all its variations.

Restrictions

Three optional restrictions let you scope a rule down further. All three combine with AND logic — every restriction must pass for the rule to apply.

User roles

Pick one or more WordPress roles. Logged-out customers do not match a rule that has any role restriction. Leave empty to apply the rule to everyone, including guests.

Date range

Set an optional start timestamp, end timestamp, or both. Times use the WordPress timezone configured under Settings → General → Timezone. Internally they are stored in UTC, so daylight savings transitions are handled automatically.

Min subtotal

The cart subtotal must reach this threshold before the rule applies. Useful for "free volume discount on orders over €500" mechanics.

Tip

For B2B pricing, restrict by user role (Wholesale, Retailer, etc.) and turn off Combine with others so the wholesale tier is the only price these customers see.

Tiers & quantity scope

A tier is a row in the rule's tier table with three values: Min qty, Max qty, and Value.

  • Min qty — the smallest quantity that qualifies for this tier.
  • Max qty — the largest qualifying quantity. Use 0 for unbounded (always recommended on the highest tier).
  • Value — the discount amount (interpretation depends on the rule's discount type).

Tiers within one rule must not overlap. The plugin sorts tiers by Min qty on save and applies the matching tier to each line item or cart total, depending on quantity scope.

Quantity scope

ScopeQuantity counted fromTypical use
Per product (line item) The quantity of the matching line item in the cart Per-SKU bulk pricing — buy 10 of THIS shirt to get 10% off
Total cart quantity Sum of all matching line items in the cart Cross-product mix-and-match — buy any 10 shirts to get 10% off all of them

Combine vs exclusive rules

Two rules can target the same product. The Combine with others flag and the Priority field decide what happens.

Combine = on
The rule's discount stacks with other combinable rules. Each rule's discount is applied independently to the line item.
Combine = off
The rule is exclusive. If multiple exclusive rules match, the one with the lowest priority number wins. All others are skipped for that line item.
Combinable + exclusive together
The exclusive rule wins on its own; combinable rules still stack on top of the winning exclusive rule.
Note

Lower priority number = higher priority. A rule with priority 1 beats a rule with priority 10.

Live preview

The rule editor includes a Live preview card that calculates the discount in real time as you edit the tiers. It is the fastest way to validate a complicated tier table before saving.

The preview accepts two inputs:

  • Base unit price — any positive number representing the product's regular unit price.
  • Quantity — the quantity to test against the tier table.

It outputs:

  • After discount — the per-unit price after the rule applies.
  • You save — total savings for the line.
  • Discount — the percentage off, computed from base × quantity.
  • Status line — confirms which tier matched, or warns if no tier matches.

06 — FrontendCustomer experience

Customers interact with three frontend elements. All three inherit your theme's font, colours, and spacing by default.

Pricing table on product pages

When a product matches at least one active rule, a small table appears on its product page. Position is controlled by the Position setting under Display.

The table shows three columns by default — Quantity, Price, You save — with one row per tier. As the customer types into the quantity input, the matching tier highlights in real time. This works for the standard WooCommerce quantity field as well as themed +/− button widgets that update the underlying input.

Cart success notice

When a customer's cart contains items that qualify for one or more tiered discounts, the cart page shows a success notice with the total savings. The wording is set by the Cart notice template under Labels and supports the {amount} placeholder.

Next-tier upsell notice

If a customer is one or more units short of unlocking a bigger tier, the cart page shows an encouragement notice. Wording is set by Next-tier notice template and supports {qty}, {extra}, and {product}.

Example:

Add 3 more of "Premium T-Shirt" to unlock a bigger discount.

Shop archive badge (optional)

Enable Show shop badge in Display settings to add a small Bulk discount badge next to the price on shop archive listings. The badge is purely informational — clicking through to the product reveals the full tier table.

07 — MaintenanceTools

The Tools page (Tiered Pricing → Tools) groups four utilities for moving rules between sites and inspecting plugin health.

JSON export

Click Export rules to download a JSON file containing every rule on this site, with tiers, targets, and restrictions intact. Logs and usage counts are not included — exports are about pricing logic, not history.

JSON import

Use Import rules to upload a previously exported JSON file. Rules are added to the existing rule set; nothing is overwritten. The import handler enforces a 2 MB upload cap and validates the structure before inserting anything.

Tip

Pair this with a staging-to-production workflow: build and test rules on staging, export them, import on production. No copy-paste, no human error.

System status

A read-only table that confirms versions and configuration: plugin version, database schema version, total rule count, and active rule count. Useful when a support ticket asks "what version are you running?".

Uninstall behaviour

The Tools page also displays the current state of the Remove data on uninstall setting. Toggling it requires a trip to Advanced settings.

08 — DevelopersDeveloper reference

XC Tiered Pricing is autoloader-driven and exposes a small public API for extension. Every public class is namespaced under the XC_TP_ prefix; helper functions use xc_tp_.

Hooks

The plugin fires WordPress actions at the key lifecycle moments and exposes a single capability filter.

HookTypeArgumentsFires when
xc_tp_rule_saved Action (int $rule_id) A rule is created, updated, or duplicated.
xc_tp_rule_deleted Action (int $rule_id) A rule is permanently deleted.
xc_tp_admin_capability Filter (string $capability) Used to gate every plugin admin page and AJAX endpoint. Defaults to manage_woocommerce.
xc_tp_daily_maintenance Cron action Daily WordPress cron task that trims logs older than one year.

Example: log every rule change to a file

add_action( 'xc_tp_rule_saved', function ( $rule_id ) {
    error_log( "XC TP rule {$rule_id} was saved at " . current_time( 'mysql' ) );
} );

Example: open the admin to shop managers

add_filter( 'xc_tp_admin_capability', function ( $cap ) {
    return 'edit_others_shop_orders';
} );

Helper functions

A handful of helper functions are available for theme and plugin developers:

FunctionReturnsPurpose
xc_tp_rules()XC_TP_Rules_ManagerSingleton rules manager for queries and CRUD.
xc_tp_get_rule( $id )XC_TP_Rule|nullLoad a single rule by ID.
xc_tp_get_option( $key, $default )mixedRead a plugin setting with a fallback.
xc_tp_get_discount_types()array<string,string>Map of discount-type keys to translated labels.
xc_tp_get_target_types()array<string,string>Map of targeting modes to translated labels.
xc_tp_format_price( $amount )string (HTML)Format a number using WooCommerce currency settings.

Database tables

Two tables are created on activation:

  • {$wpdb->prefix}xc_tp_rules — one row per rule, including a JSON-encoded tiers column.
  • {$wpdb->prefix}xc_tp_logs — one row per discount application; trimmed daily.

Both tables follow WordPress naming conventions and respect the wp_ prefix configured in wp-config.php.

09 — SupportTroubleshooting

The most common issues, with proven fixes. If yours is not listed, open a ticket and include the System status output from the Tools page.

Pricing table does not show on product pages

Check the following in order:

  1. Is the rule Active? Inactive rules are skipped entirely.
  2. Does the rule's targeting include the product? An Apply to: Specific products rule needs the product explicitly selected.
  3. Is Show pricing table enabled under Display settings?
  4. Is the user logged in if the rule has a role restriction? Logged-out customers will not match.
  5. Is the product on sale? By default, sale-priced products are excluded — toggle Apply to sale items if needed.

Discounts not applied at checkout

If the pricing table is visible but the cart total is wrong:

  • Empty the cart and re-add the product. Cart totals are computed at add-to-cart and on quantity change — a stale cart from before the rule existed will not retroactively update.
  • Check whether another extension is overriding woocommerce_product_get_price. XC Tiered Pricing hooks into the standard pricing pipeline, so any extension that runs at a higher priority will win.
  • Confirm the customer's user role matches the rule's role restriction (if any).

Wholesale prices show to logged-out users

This means the rule has no role restriction. Edit the rule, expand User roles, and pick the role(s) that should see the discount. Logged-out customers never satisfy any role restriction.

Date scheduling doesn't activate the rule at the expected time

Two timezone realities collide here:

  • The plugin stores start and end timestamps in UTC.
  • The admin date input uses the WordPress timezone configured under Settings → General → Timezone.

If your site timezone is wrong, every rule schedule will be wrong. Verify the WordPress timezone first; the plugin reads it correctly afterwards.

License will not activate

Activation requires outbound HTTPS to xaniacode.com. Common blockers:

  • Strict server firewall blocking outbound traffic — ask the host to whitelist xaniacode.com on port 443.
  • WordPress WP_HTTP_BLOCK_EXTERNAL is true with no whitelist — add xaniacode.com to WP_ACCESSIBLE_HOSTS.
  • Server clock is off by more than 5 minutes — fix NTP.
  • License already activated on a different domain. One license = one production domain. Open a support ticket if you legitimately moved the site.

Settings not saving

Almost always a server-side write or nonce problem:

  • Browser session expired. Reload the page and try again.
  • An aggressive caching plugin is caching admin pages — exclude /wp-admin/ from the cache.
  • A web application firewall is rejecting the POST. Check the WAF logs for blocked requests.

Import file rejected

The import handler validates three things, in order: file size (max 2 MB), JSON parseability, and structural shape. The most common rejection is invalid JSON — open the file in any editor and verify it parses. Files exported from the plugin always pass.

Pricing table looks broken on my theme

The frontend inherits your theme's typography by default. If the table looks broken (collapsed columns, misaligned text), the most likely cause is an aggressive !important rule in the theme's stylesheet on table selectors. Override it by setting a primary and accent colour under Display settings, or contact support with the theme name.

Conflict with another tiered pricing plugin

Run only one quantity-discount plugin at a time. They all hook the same WooCommerce filters and the result of running two simultaneously is undefined — sometimes one wins, sometimes the discounts compound, sometimes they cancel. Disable the other plugin first.

10 — ReferenceTechnical FAQ

How are prices applied internally?

The pricing engine hooks into woocommerce_product_get_price and related variation pricing filters. For cart-level discount types, it also hooks woocommerce_cart_calculate_fees to register a discount fee. This is the WooCommerce-recommended pricing pipeline; nothing in the database is mutated to show a discounted price.

Does the plugin affect site performance?

Rules are loaded once per request and cached in memory for the duration of that request. The pricing engine evaluates each line item against in-memory rules — no extra database queries per item. On a store with 500 active rules, the typical overhead is under 5 ms per page load.

Which database tables are created?

Two: wp_xc_tp_rules (one row per rule) and wp_xc_tp_logs (one row per discount application). The prefix wp_ follows your wp-config.php.

Is there multi-currency support?

Yes, indirectly. The plugin uses WooCommerce's pricing pipeline, so any multi-currency extension that filters woocommerce_product_get_price sees the discounted value and can convert it. Tested with WooCommerce Multilingual / Multi-Currency and CURCY-style plugins.

Does it work with WordPress Multisite?

Yes. Each site in the network needs its own license activation. Rules and settings are stored per site.

Custom user roles?

Fully supported. The role picker lists every role registered with WordPress, including roles added by Members, User Role Editor, custom code, or other extensions.

WPML / Polylang compatibility?

Both work. Translations are picked up automatically because every customer-facing string runs through WordPress's gettext functions. Targeting by product applies to all language variants of the same product.

Subscription products?

Compatible with WooCommerce Subscriptions for the per-product discount types (percentage, fixed amount, fixed price). Cart-level discount types apply to the initial order; recurring renewals use the post-discount price as a baseline.

Variable products?

Fully supported. Selecting a variable product as a target applies the rule to every variation. Individual variations can also be selected directly.

Can I apply tiered pricing to bundles, composites, or grouped products?

The plugin works with WooCommerce Product Bundles and Composite Products at the line-item level — bundled children are discounted individually if they match a rule. Bundle-level pricing requires a small custom integration; contact support for guidance.

Are the assets loaded on every page?

No. Frontend CSS and JS load only on product, cart, and checkout pages. The admin assets load only on the plugin's own admin screens.

Does the plugin store any personal data?

The logs table stores the user ID (if logged in) and the cart line item that received a discount. No names, emails, or addresses. The data follows the same lifecycle as the rest of your WooCommerce data and respects WordPress data export and erasure requests.

11 — HelpSupport & updates

Direct developer support

Every license includes 6 months of direct support from the developer who built the plugin. Open a ticket from My Account → Support on xaniacode.com. Expect a response within one business day; most tickets are resolved on the first reply.

When opening a ticket, include:

  • The plugin version (visible on the dashboard)
  • The WordPress and WooCommerce versions
  • The output of the System status table
  • A clear description of expected vs actual behaviour
  • Screenshots, browser console output, or PHP error log entries when relevant

Support renewal

After 6 months, support can be renewed for a small fee. Updates remain free for the life of the plugin regardless of support status — your installation never stops receiving fixes and new features.

How updates are delivered

Updates appear inside WordPress admin under Plugins → Installed Plugins, just like any plugin from the WordPress.org repository. The license key activated on the site authorises the update channel; nothing else is required from you.

Privacy & data

The plugin contacts the XaniaCode server only for two purposes: license validation on activation, and update checks (twice daily, the WordPress default). No customer data, order data, or analytics are ever transmitted.

License terms recap

Pricing model
One-time payment, no subscription
Updates
Lifetime, delivered through WordPress admin
Support
6 months included, renewable thereafter
Domain scope
Single production domain; staging on the same root domain is included
Refund policy
Reviewed individually for products that do not function on a clean WordPress install — see the Refund Policy page on xaniacode.com