Skip to content

Product Page Pricing

When a discount applies to a product, Dino shows the discounted price (and supporting messaging) on the product page itself — before the shopper adds it to their cart. The display is controlled by the Product page block in the Messaging section of the rule editor.

Depending on the discount type and configuration, customers see one or more of:

  • Crossed-out original price with the discounted price alongside
  • Savings badge — "Save 15%" or "Save £5"
  • Tier table — for tiered or volume discounts, the full table of quantity / spend tiers and their prices
  • Bundle prompt — "Buy 3 for £25" callout on qualifying products

The display updates whenever the rule changes — raise a tier from 10% to 15% and the savings badge follows.

Scroll to the Messaging section at the bottom of the rule editor. The Product page sub-block has two controls:

  • Display mode — a segmented control with three options: Tier Table, Custom Message, or Hidden.
  • Position — a dropdown that picks where the display renders on the product page. The five options each target a different WooCommerce / page-builder hook:
    • Above Add to Cart (Standard) — above the Add-to-Cart form. Works with standard WooCommerce templates and most page builders.
    • Above Add to Cart Button (Elementor-compatible) — inside the form, just before the button. Works with Elementor's Add to Cart widget.
    • Below Price (Standard WC template) — immediately after the price in the product summary. Standard WooCommerce only.
    • Below Price (JetWooBuilder / Elementor) — after the price widget using the JetWooBuilder hook. Use this when your product page is built with Elementor + JetWooBuilder.
    • In a Product Tab (Standard WC template) — adds a "Bulk Pricing" tab alongside Description and Reviews. Standard WooCommerce only.

When Display mode is Custom Message, a third input appears for the message copy.

Rule editor scrolled to the Messaging section, with the Product page block visible. Display-mode segmented control, position dropdown, and (when Custom message is selected) the message input.

The Plain English summary green box above the Rewards section reflects the product-page display in the rule's sentence — so you can see at a glance whether the display matches the rest of the rule.

The Product page block is gated — it only lights up when the rule has product-specific targeting (a product / category / SKU / tag / attribute condition in the Eligible Items sub-block of What triggers it?). On a cart-wide rule with no product targeting, the block collapses to a heading: "Add a product, category, SKU, tag, or product-attribute condition to enable Product page messaging." The notice points at the section that owns the gating field.

Inside the unlocked block, Tier Table mode has its own gate: it requires the rule to carry at least one tier with a threshold above zero. On a flat-discount rule, the Tier-Table tile is disabled (with a tooltip explaining why); Custom Message and Hidden remain available.

This is the Messaging section's locked-state pattern everywhere — gating fields stay in view, with a one-line explanation of what to change to unlock them.

Different discount types produce different storefront elements, even when the Product page block is set to Tier table:

| Discount type | Storefront element | |---------------|--------------------| | Tiered (% off / Spend & Save) | Crossed-out price + savings badge at each tier; tier table if enabled | | Volume (bulk pricing) | Quantity tier table — every threshold and its per-unit price | | Buy X Get Y (BOGO) | "Add 2 to qualify" prompt on qualifying products | | Mix & Match (Bundle) | "Buy 3 for £25" callout on qualifying products | | Coupon-activated | No product-page display until the coupon is entered at checkout |

When two or more rules target the same product and all have Display mode set to Tier Table, the storefront does not render a separate table per rule. It merges them into a single table and, at every spend threshold, shows the best offer the shopper would actually get.

Two rules target the same product (call it "Widget"):

  • Rule 1 — "20% off at £50, 30% off at £100" (a tiered discount).
  • Rule 2 — "Free shipping at £50" (a flat free-shipping reward).

Without merging, the product page would render two separate tables and the shopper would have to mentally combine them. With merging, the Widget product page shows one table:

| Spend | What you get | |--------|--------------| | £50 | Free shipping | | £100 | 30% off |

The £50 row reads "Free shipping" because — at that threshold — free shipping is the headline benefit a shopper is told about. The £100 row reads "30% off" because at that threshold the tiered discount is the better offer. All three rewards (20% off, 30% off, free shipping) still apply at checkout — the merging is purely a display decision so the merchant's product page is not crowded with overlapping tables.

For merchants tuning multi-rule setups, the comparator (StorefrontFilter::reward_beats()) picks the displayed row at each threshold in this order:

  1. Free shipping and free gift outrank value-bearing rewards (% off, fixed off, fixed price). They are flagged on the table because they are the merchant's most visible upgrade.
  2. Within the same kind, the larger value wins — 30% off beats 20% off, £10 off beats £5 off.
  3. Cross-kind ties at the same threshold (e.g. 15% off vs £10 off neither uniquely better) — the first rule listed in the admin discounts table wins.

The merchant cares about #1 and #2; #3 is documented here for completeness but should rarely matter in practice — design the rule set so each threshold has one obvious "best" reward.

  • Not stacking. Stacking is a checkout-time decision controlled by the Stacking mode global setting (Settings → Discounts). The merged table is a display choice; the engine still evaluates every rule independently when the cart is calculated.
  • Not deduplication. None of the contributing rules are dropped. Delete a "duplicate" rule and the next-best offer at each threshold slides into its slot — sometimes leaving an empty row.
  • Not best-in-the-cart. The merging is per-product on the product page. The cart still shows the per-rule discount lines under whatever Stacking mode you've configured.

If you want each rule's table to render separately, set the rules to different positions (e.g. one Above Add to Cart, another In a Product Tab), or set the less-prominent rules to Custom Message or Hidden.

The storefront display also respects the shopper's checkout currency. In a multi-currency store, the crossed-out price and savings badge use the cart-currency's price entry from the rule's per-(zone, currency) price list — never an FX conversion. If a rule has no price configured for the active currency, the product-page display falls back to hidden rather than rendering a mismatched amount. See Multi-currency for the per-currency price model.

The display also honours the rule's Where does it apply? zones. A rule scoped to "EU zone" only shows the discounted price on the product page when the shopper resolves to an EU country — shoppers outside the zone see the normal catalog price. This is enforced by the zones tree-leaf check, so user-role + zone combinations don't drift between the product page and the cart.

Dino hooks into WooCommerce's standard product-page hooks, so it works with most themes out of the box. The display respects your theme's price formatting (currency symbol, decimal places, position).

If your theme uses non-standard price markup, the display may need CSS adjustments. The plugin uses clearly named CSS classes (.dd-*) for all output, making it straightforward to style.

The display fields are writable via the REST API for bulk imports — storefront_display, storefront_position, storefront_message. See the REST API reference.