PrestaShop Discounts: Specific Prices, Cart Rules and Scheduling

Set up PrestaShop discounts, vouchers and scheduled sales. Control stacking, eligible products, price references, timezones and expiry.

mypresta.rocks · Updated 11/01/2026

Choose a discount mechanism by what it changes: a product price, a basket reward or a stored base price. Then test eligibility, stacking and expiry before you announce the offer.

What we would do

We would start with a native dated reduction or cart rule when it covers the offer, and add automation only for a requirement such as recurrence, stock eligibility or a permanent scheduled edit. The route depends on the shop you already run: its pricing and checkout modules, theme, ERP or supplier imports, product and combination data, customer groups, markets and currencies, and the team available to maintain the campaign. Identify which system owns the price before changing it.

Rehearse the campaign on a private staging copy with the same relevant configuration and representative data, isolated from live customer emails, payments and fulfilment exports. Record expected prices and basket totals, test both date boundaries and the reversal, then apply the reviewed settings in a planned live window. Transfer the agreed configuration rather than replacing the live database with the staging database, which would discard intervening orders.

Keep the previous settings, the campaign's rule identifiers and any before-values needed for reversal. Name the person who checks the first live prices and orders, the person who can withdraw the offer, and the evidence that would trigger that decision. A price change is ready when the customer journey passes, rather than when a rule has merely been saved.

If you want the chosen module configured, the PrestaShop Module Installation & Configuration Service covers one existing module and its agreed verification journey; campaign design, licences, additional modules and custom development are scoped separately.

Choose specific prices, catalogue rules or cart rules

The familiar PrestaShop discount tools act at different stages. A specific price changes a product's calculated price. A cart rule provides a basket reward, optionally requiring a code. A catalogue price rule creates specific-price rows for matching products.

NeedNative toolWhat to verify
One product or combination at a different priceProduct > Pricing > Specific pricesDates, country, currency, group, customer, combination and quantity.
A category or other catalogue segment discountedCatalog > Discounts > Catalog price rulesCondition groups and the generated product prices.
Voucher, minimum-spend reward, free shipping or giftCatalog > Discounts > Cart rulesEligibility, reward scope, usage caps and compatibility.
Permanent base-price changeProduct edit, suitable import or a controlled bulk-edit processStored prices, shop scope, preview and rollback.
Recurring or stock-dependent campaignAn extension or custom automationTrigger, schedule, floor, exclusions, logs and expiry.

A qualifying specific-price reduction normally gets discount presentation in a compatible theme. A row that only sets a fixed price does not guarantee a strikethrough or sale badge. A cart voucher usually appears in cart totals rather than changing the browsing price.

PrestaShop 9.1 introduced a redesigned discount interface as an experimental feature. Its four types are Catalogue, Cart, Free Shipping and Free Gift. The official announcement describes that feature separately from the legacy form. For legacy Cart Rules and Catalog Price Rules, use the corresponding screens under Catalog > Discounts. Check which interface your shop enables.

Create a product or catalogue reduction

One product

  1. Open Catalog > Products, edit the product and open Pricing.
  2. Add a specific price and select its shop, currency, country, group or customer scope as needed.
  3. Choose the combination when the offer applies only to a size, colour or other variant.
  4. Set From quantity to 1 for an ordinary offer, or a higher threshold for a quantity tier.
  5. Set the fixed price or reduction. For an amount reduction, check its currency and whether the amount includes tax.
  6. Set From and To for a temporary offer. Save and test the applicable audience and a customer outside it.

For example, give a jacket a 20% reduction for a defined weekend, or offer a quantity tier such as five units at EUR 8 each. “From quantity” means the quantity considered in the current cart or price calculation. It is not a count of lifetime sales.

Specific prices use from and to. Zero-date boundaries can represent an unrestricted date window. An old unrestricted row is one possible reason a product keeps showing a different price, but check every matching condition and the priority rules before deleting anything.

A category or other segment

Open Catalog > Discounts > Catalog price rules. This has its own form and condition groups, rather than the per-product dialog. Set the scope, quantity, dates and reduction, then add conditions. Native conditions include category, brand/manufacturer, supplier, attribute and feature. Do not assume there is a native price-range selector.

For an “Outdoor 15%” weekend, select the Outdoor category, From quantity 1, the 15% reduction and the intended date range. Test one product inside the selection and one outside it. Review condition-group logic when combining several criteria.

Catalogue rules create a discount layer; they do not permanently rewrite the product base price. Their rows can appear beside manually created specific prices, so inspect id_specific_price_rule when tracing their origin. Multiple eligible specific prices are resolved through matching and priorities; do not assume they all add together or that the lowest number always wins.

This read-only inventory uses product 42 and the example prefix ps_. It includes future, expired and context-inapplicable rows:

SELECT id_specific_price, id_specific_price_rule, id_product,
       id_product_attribute, id_shop, id_shop_group, id_currency,
       id_country, id_group, id_customer, id_cart, from_quantity,
       price, reduction, reduction_type, reduction_tax, `from`, `to`
FROM ps_specific_price
WHERE id_product = 42
ORDER BY `from`, from_quantity;

A stored percentage of 0.250000 means 25%. To identify the effective price, reproduce the actual shop, customer, country, currency, combination, quantity and time. Check the generated feed too: cart vouchers do not generally become a product feed's sale price, and feed integrations need their own audience and date handling.

Build a voucher or automatic basket offer

Open Catalog > Discounts > Cart Rules. The legacy form has three tabs:

  • Information: name, internal description, optional code, Highlight, Partial use, Priority and status.
  • Conditions: customer or group eligibility, dates, minimum amount, carrier and country restrictions, product selection and usage limits.
  • Actions: percentage or amount reduction, its target and tax basis, free shipping and a free gift.

Leave Code empty for an automatic rule that applies when eligible. Set a code for a distributed voucher. Highlight advertises an applicable voucher to the customer; it is not another discount condition. Partial use can create a voucher for unused fixed-value balance and needs deliberate handling. See the legacy cart-rule documentation for the fields.

Set total available uses and the per-user cap. A per-user cap of one means one redemption of that rule; it does not make the offer exclusive to the customer's first-ever order. First-order eligibility needs a suitable additional check.

Check the minimum amount's tax, currency and shipping choices. Then choose the reward target: Order (without shipping), Specific product, Cheapest product or Selected product(s) where the percentage action supports it. Free gifts, prepriced Packs and sold gift vouchers are different tools with different accounting effects.

Cart-rule date_from and date_to are required in this legacy system. The back office rejects an end date earlier than the start. Review the intended dates even though that validation exists. Usage caps and active status can end availability before the date does.

Control stacking and discount only eligible lines

Specific-price reductions and cart rules can combine. If a EUR 100 product is reduced by 25%, then a 10% voucher applies to the remaining EUR 75, the result is EUR 67.50: a combined 32.5% reduction. Similarly, 30% followed by 20% gives 44%, not 50%. Confirm the actual result with your rules and core version.

For percentage cart rules, Exclude discounted products can remove already reduced lines from that percentage's base. It is not a general fixed-amount-voucher exclusion control. Between cart rules, check both Priority and compatibility restrictions. Lower numerical priorities are evaluated ahead of higher ones; priority alone does not mean “never combine”.

Use the exact selected-products setup

  1. In Conditions > Product selection, define the eligible products or categories and required quantities.
  2. In Actions, choose a Percent (%) reduction.
  3. Set Apply a discount to > Selected product(s).
  4. Add an eligible and a protected product to the same cart. Confirm that only eligible lines receive the percentage reduction.

Product selection under Conditions can make a cart eligible without restricting an order-wide reward to those lines. Choosing Order (without shipping) after adding a category condition is therefore different from Selected product(s). Specific product is another action, not the category selector.

For catalogue rules, define eligible sets positively. A “Never on sale” category or feature can help staff manage policy, but core does not automatically treat that marker as a global veto. A product can also belong to an eligible category, so audit overlaps. Fixed-amount rewards and a global exclusion policy may need a compatible integration. Module-specific setup belongs in the Discount Exclusion Manager help page. It applies one exclusion policy to vouchers, catalogue reductions and promotional prices; supported percentage and fixed reductions stay within the eligible basket share. Free shipping and gifts keep their own calculation, so decide whether a protected item may still qualify the basket for either reward and test that policy separately.

Calculate the margin before the sale

Use consistent tax-exclusive figures for a VAT-registered margin calculation. If costs stay fixed, a EUR 100 item with EUR 70 cost contributes EUR 30 before a discount. At EUR 80, it contributes EUR 10. A 20% price cut removed two-thirds of that contribution.

Price beforeCostContribution beforePrice after 20% offContribution after
EUR 100EUR 50EUR 50EUR 80EUR 30
EUR 100EUR 70EUR 30EUR 80EUR 10
EUR 100EUR 85EUR 15EUR 80EUR -5

Review thin-margin products, new arrivals, limited editions, gift cards and services as possible exclusions. Their suitability depends on costs and your merchandising policy, not launch age alone. Selling a EUR 50 gift card for EUR 40 reduces receipts by EUR 10 against its face value; the eventual contribution depends on redemption costs, incremental spending and unused balances. Test any further voucher stacking.

Do not assume a supplier's minimum advertised price clause is enforceable. Such clauses can constitute prohibited resale price maintenance in Europe. Assess the agreement in the relevant jurisdiction before encoding it as mandatory policy. The Finnish competition authority explains this risk.

State exclusions alongside the offer and on affected products before checkout. Revisit the protected list as costs, stock and commercial priorities change.

Schedule dates, clocks and cache boundaries

Native dated prices and cart rules are checked during price calculation and voucher eligibility. They do not require a cron job to flip an activation switch. Cart rules use date_from/date_to; specific prices use from/to. Native recurrence such as every weekend is a separate requirement from one dated window.

PS_TIMEZONE sets PHP's timezone through shop configuration. Check the database session too: some cart-rule discovery uses SQL NOW(), while other checks use PHP time. Align the relevant clocks and test daylight-saving transitions. One campaign instant cannot be midnight in every country. Write the chosen timezone into the campaign brief and translate the deadline for each audience. Do not change the whole shop's timezone to fix one campaign without reviewing the effect on other schedules.

Do not promise a second-perfect transition. The native specific-price resolver compares a minute-level current time and includes the end boundary. Test immediately before and after the intended cutoff, through the next minute, with existing and new carts.

A read-only schedule inventory can show current and future cart-rule windows. It does not prove all the listed rules are usable:

SELECT id_cart_rule, code, active, date_from, date_to,
       quantity, quantity_per_user
FROM ps_cart_rule
WHERE date_to >= NOW()
ORDER BY date_from;

SELECT id_cart_rule, code, date_from, date_to
FROM ps_cart_rule
WHERE date_to < date_from;

The second query can find inconsistent rows from imports or other code even though the native form validates reversed dates. Use your actual prefix and verify the database's notion of “now”.

Coordinate expiry across PrestaShop caches, any full-page cache, reverse proxy and CDN. Set suitable TTLs or purge affected pages around both boundaries. Purging one layer does not prove that another layer or an already open browser page has updated. Test a warm cached page, cart recalculation and the final checkout total.

If you schedule a cache-clear command, use the correct PHP binary, filesystem user and shop root. Log completion and failures, and schedule any separate module or CDN purge. The cron expression 0 0 27 11 * runs every year on 27 November, not just in 2026. Use a one-time scheduler for a one-off campaign and check its timezone. Starting a job at midnight does not guarantee that it finishes at midnight.

Schedule banners, homepage content, email and sale landing pages separately from the price. Keep usage limits, exclusions, start time and end time consistent in every channel.

Distinguish recurrence, base edits and stock triggers

A temporary discount leaves the stored base price in place. A permanent change, such as an 8% category-wide increase after supplier costs rise, needs a controlled base-price edit. Preview the affected products, fields and shops, save before-values, then verify the written prices and a rollback path.

For future permanent edits, a scheduled bulk job needs a working runner. Its execution depends on cron frequency, locks, failures and job completion. Check current product and combination pricing as well as any later edits before rolling back. Product price, wholesale cost and combination impact are different targets. Module-specific instructions belong in the Mass Price Updater help page.

If a supplier import or ERP owns retail prices, agree where the permanent change belongs. A successful local edit can be overwritten by the next synchronisation. Rehearse that next import as well as the edit, and record whether a later legitimate price change should survive an undo. Restoring an old snapshot without checking subsequent writes can erase a correction made after the campaign. For a temporary campaign, withdraw the layer created by that campaign rather than resetting every product to an assumed old price.

“After the 100th cumulative unit sold, change the price” requires a historical sales counter. Keep this historical-sales trigger separate from a native From quantity threshold. Define qualifying statuses, refunds, returns, combinations, shop scope and concurrency before building it. Do not subtract refunded and returned quantities blindly if those records overlap.

A stock-clearance policy can instead mean: no qualifying sale for 30 days, stock above three, no conflicting reduction, and a final price above your floor. An illustrative rule might apply 15% while preserving a 20% minimum margin and excluding protected SKUs. The history, stock source, currency, tax basis and floor formula all need an explicit definition.

For recurring windows and stock-based reductions, use a tool with preview, recorded applications, expiry and rollback; configuration belongs in the Smart Dynamic & Scheduled Discounts help page. On PrestaShop 8 and later its discount path uses runtime price calculation; older supported versions can materialise temporary native specific-price rows. That compatibility mechanism is separate from rewriting a product's base price.

For any automation, compare dry-run eligibility with actual results, including skipped products, the base price, reduction, floor and final price. Check task status and failure logs. A registered periodic task still needs its runner to execute; it is not a promise of immediate action.

Build a flash sale with an honest reference and deadline

Before advertising a reduction on consumer goods, determine the legally applicable prior price. For public price-reduction announcements on consumer goods in the EU, the general reference is the lowest price applied during at least the 30 days immediately before the reduction. A native crossed-out regular price is not automatically that reference. Keep a reliable history and check national options and exceptions, including perishables, recently introduced goods and progressive reductions. A short sale does not by itself remove the requirement. See the Commission's Article 6a guidance.

Build the actual product reduction or voucher only after checking that reference. Verify every percentage claim against it. Raising a base price just before a sale does not create an honest prior price. General catalogue reductions, personalised offers and conditional bundles can have different legal treatment; check the actual announcement.

Where public prior-price disclosure applies, Omnibus Price Compliance records public prices and displays supported references for the relevant product or combination, shop, country and currency. Installation starts recording; it cannot reconstruct missing history. Its references remain hidden without enough evidence for the relevant period and reduction start, and its cart references stay hidden when a cart rule applies. Check the actual display in your theme and keep the evidence behind the comparison; installing it is not proof that every advertised saving is substantiated.

Use one real campaign deadline. A countdown should display the same target instant for the intended audience and must not restart when the visitor reloads. Render the campaign's single end timestamp from the server and let JavaScript display the remaining time beside the product price and in the cart. Enforce eligibility and recheck the payable total on the server. Account for browser clock differences, minute-level resolver boundaries, cached pages and delayed jobs when testing the timer against expiry.

Display only genuine stock and sales information. “Only two left” must reflect the stock context you mean; a view counter must not be a random number. A remaining quantity that stays unchanged is not by itself proof of deception, since stock can be replenished or simply not sell.

Announce eligible products, exclusions and timing clearly. Test a dedicated sale destination, any sale badge and theme price output. Keep customer messages relevant, including early access where you actually provide it. Campaign-specific configuration belongs in the Sales Revolution help page.

Prepare for traffic using measured capacity. Review Smarty and CCC under Advanced Parameters > Performance; PHP OPcache is configured at the host/PHP level. Test representative sale pages, carts and checkout under controlled load, including cache invalidation at the boundaries.

Work through a jacket promotion before announcing it

Suppose you want a public weekend reduction on an eligible jacket while a gift card stays at face value. Use the guide's illustrative EUR 100 jacket, EUR 70 cost and 20% reduction, plus a EUR 50 gift card. The following figures are tax-exclusive, before shipping and other charges, to make the discount allocation visible.

  1. Approve the economics. The jacket falls to EUR 80 and contributes EUR 10 against the stated cost. Include your actual payment, fulfilment and campaign costs before approving the offer; that EUR 10 is not net profit.
  2. Check the reference evidence. Match the jacket's product or combination, shop, country and currency to the recorded public prices and applicable prior-price policy. If the relevant lowest prior price was already EUR 80, a current EUR 80 offer does not substantiate “20% off” against that reference, even though the base price is EUR 100. Resolve the claim or offer before publication.
  3. Record the scope. List the eligible jacket and the protected gift card, the intended audience, date window and timezone. For a public product-page offer, create the jacket's dated reduction and check that catalogue rules do not also include the gift card.
  4. Rehearse the mixed basket. Compare the observed lines and total with the expected figures below. Then test a 10% voucher: decide whether it may further reduce the jacket and whether it may reduce the gift card. A correct campaign reduction does not establish that another voucher respects the same boundary.
  5. Approve the customer view. Keep dated evidence of the reference, product listing, product page and payable basket, together with the saved rules. Rehearse expiry with that basket still open, then have the named owner approve the live switch and check the first applicable orders.
Basket lineBefore this offerExpected after this offer
Eligible jacketEUR 100EUR 80
Protected gift cardEUR 50EUR 50
Total before shipping and other chargesEUR 150EUR 130

For a separate cart-rule scenario, start with the undiscounted EUR 100 jacket and EUR 50 gift card, with no product reduction or other voucher applied. An order-wide 20% reward produces EUR 120; restricting the reward to the jacket produces EUR 130. That difference is the acceptance check for the Selected product(s) setup above. Put free shipping or a gift through a separate check if either is part of the offer.

Test the complete campaign and review its result

  1. Record the objective, dates, timezone, eligible products, protected items and audience.
  2. Verify price history and all advertised references before announcing the offer.
  3. Test an eligible customer and an ineligible customer, inside and outside the date window.
  4. Test the minimum spend, quantity threshold, carrier restrictions, currencies and usage caps.
  5. Place mixed carts with eligible, protected and already discounted items. Test another voucher and confirm stacking.
  6. Check product listings, detail pages, cart, payment, invoice and product feeds where relevant.
  7. Test start and end with warm caches, an open browser page and an existing cart.
  8. Confirm scheduled jobs, cache purges and creative changes complete and report failures.
  9. Retain the rule settings, observed totals and rollback information.

Find the fault before changing the offer

What you seeEvidence to collectWhat to inspect
A voucher is refused or disappears after a cart change.The code, customer, cart contents and total, address, carrier, currency and test time.Active status, exact code, dates, remaining uses, customer eligibility, minimum-spend basis, product restrictions and compatibility with other vouchers. Repeat after login or an address change to identify which context changes eligibility.
A product remains reduced after this campaign ends.The product and combination, customer context, time, displayed price and freshly recalculated cart price.All matching specific prices, generated catalogue rows and caches. Identify which rule or integration owns the remaining reduction before removing it; another valid offer may still apply.
The product page and checkout disagree.The page URL and audience, the page's cached response and the payable basket in that same context.The theme's price output, cache boundaries and whether a personalised price has been cached for the wrong audience. A voucher shown only in totals can also explain a legitimate difference.
A scheduled permanent edit has not appeared.The job status, run history, selected shop and written values, plus the next import's result.Whether the runner completed, whether the job targeted the intended price field and whether another integration subsequently overwrote it.

After the event, compare revenue, units, average order contribution, new and returning customers, returns and the following full-price period. Distinguish incremental demand from orders pulled forward. A post-sale dip can have several causes; monthly promotions do not inevitably train customers to avoid full price. Choose a cadence from your own margin and customer behaviour rather than a universal frequency rule.

For the wider calendar, use seasonal promotion planning. For price display and tax interactions, use prices and VAT.

What to ask your developer or agency

  • Which native rules, pricing modules and imports currently affect these products, and which system owns each price? Ask for an inventory tied to the installed shop, rather than a generic compatibility answer.
  • Can you show the expected and observed mixed-basket totals, including protected items, existing vouchers, gifts and shipping, in each affected market?
  • Where is the prior-price evidence for each public reduction claim, and what happens when the necessary history is missing?
  • Who checks the live start and expiry, where do scheduled-job failures surface, and who can act if the advertised offer and payable price differ?
  • Which exact rules or stored values does reversal affect, and how will you preserve new orders, later price edits and unrelated promotions?

Keep the answers, settings and test evidence with the campaign brief so the person covering the sale can diagnose or withdraw it without guessing how it was built.

Questions owners ask

Can I make an emailed voucher private just by hiding the code?

A code can be forwarded. Use customer or group eligibility when the audience must be restricted, then test with an account outside that audience. Removing a banner or leaving Highlight off does not revoke a code that customers already know.

Does adding a discounted product to the cart reserve that price?

Do not promise a reservation for an unfinished cart. Treat it as subject to recalculation and show the cutoff terms before checkout. The worked campaign includes a cart left open across expiry; also agree how staff handle a shopper who returns after the advertised deadline.

Can I change the exclusions after the campaign email has gone out?

Record the change and review what customers were promised before editing the rule. Update the sale destination and customer messages together, and give support staff the old and new terms. A technical restriction alone does not explain an altered offer to someone holding the original email.

Should I restore the shop backup if a discount goes wrong?

Withdraw the affected offer through its supported reversal route and reconcile orders already placed at the unexpected price separately. A whole-shop restore can discard new orders and other work. Keep the evidence of the fault and agree the customer response before attempting to alter completed orders.

Loading...
Back to top