- moduł został przepisany kompletnie pod PrestaShop 9.x
What the module is for
- A loyalty program without coupons. A returning customer is automatically moved to a higher level, and sees reduced prices immediately in the catalog, on the product page, and in the cart.
- Rewarding ongoing activity. The module assigns the customer to a discount group based on the total value of their orders. The customer keeps this group until they reach the next threshold or drop below the current one. This way, the customer sees lower prices in the store all the time, not only after entering a code. The module works with both tax-inclusive and tax-exclusive prices, so stores displaying net prices are also supported.
Discount levels
- Level = amount range + customer group. Each level has a minimum and maximum amount in the store’s default currency and an assigned PrestaShop customer group. The discount percentage is the discount of that group, set in Customers > Groups.
- Level name and benefit. An optional name (e.g. Silver, Gold, Platinum) and a short benefit description, e.g. “Priority support” – both fields are filled in separately for each store language, and the customer sees them in the cart and on the summary page.
- Validation checks. Ranges cannot overlap, amounts are rounded to two decimal places before validation, one customer group can belong to only one level, and the Visitor and Guest groups cannot be used as a level.
- Gaps and totals above thresholds. A total that falls into a gap between levels (e.g. 0–499 and 500–999) or exceeds the maximum of the highest level leaves the customer at the highest level already reached.
- Group outside thresholds. A customer whose total does not reach the first threshold is assigned to the selected default group – usually the standard Customer group with a 0% discount.
- Quick group creation. The “Create discount group” button on the levels tab opens the new customer group form in PrestaShop.
How the customer total is calculated
Nine calculation methods
- Total of included orders (full history).
- Total of included orders from the last 3, 12, or 24 months.
- Included order statuses. You choose which statuses count toward the total, e.g. payment accepted, delivered, paid remotely, overdue payment paid, and remote payment accepted. If the counted statuses include unpaid order statuses, the settings display a warning.
- Products by order prices. Order items are counted at the prices they were sold for (excluding discount codes), and quantities covered by merchandise returns or refunds are deducted. An order in which all quantities were returned does not add the shipping cost.
- Shipping and tax optional. Separate switches let you exclude shipping cost and tax from the total.
- Multiple currencies. Orders in another currency are converted to the store’s default currency using the rate saved in the order.
- Calendar periods in the store time zone. “Last 3 months” is counted from the same day of the month, and in a shorter month – from its last day (May 31 minus 3 months is February 28 or 29).
Total with the current cart
- Level based on that level’s prices. The customer gets the highest level whose threshold is reached by the total of orders and cart valued at the prices of that very level – just as orders count amounts actually paid. Thanks to this, the level does not switch on every page refresh and does not drop after the cart is paid.
- Order awaiting payment. An order, e.g. by bank transfer, keeps the current level as long as the cart is empty, so the level does not drop on the order confirmation page. However, it never raises the level, and a new cart is priced exclusively from paid orders.
When the level changes
- When entering the store. The level of a logged-in customer is recalculated on every store page, so the expiry of a period or protection takes effect from the next page view. The page on which the level changes already shows the prices of the new level.
- After a cart change. The level block and savings block in the cart refresh automatically (AJAX) after adding or removing a product.
- After an order status change. Paying for an order increases the total, while cancellation or refund decreases it – a status change in the back office immediately recalculates the customer’s level.
- In bulk from the back office. Synchronization assigns all customers to the correct groups, e.g. after installing the module or after changing thresholds.
- Email notifications. An optional email informs the customer about a level change and gives the current total and discount percentage. Templates are available in 9 languages: Polish, English, German, French, Spanish, Italian, Czech, Russian, and Ukrainian. For totals including the cart, a change triggered by the cart sends at most one email per day.
- Change history. Every promotion, downgrade, default group assignment, protection start, and protection expiry is saved with the date and customer total.
Level protection period
- Keeping the level after the total drops. When protection is enabled, the customer keeps the current level for the configured number of days (up to 3650) before the module allows it to be lowered.
- Only for a level earned by orders. Protection starts when a counted order is cancelled or refunded, or when orders fall out of the 3, 12, or 24 month period. A level reached only thanks to the cart contents is not protected.
- Visible to the customer. The block in the cart and the summary page show the date until which protection is active. After it expires, the level changes on the next store page view.
Rules for combining discounts and exclusions
- Do not combine with product discounts. The group discount does not apply to products that already have a specific price or another product discount.
- Do not combine with coupons and cart discounts. The group discount is not applied when there is a discount code or another cart rule in the cart.
- Customer groups are preserved. The module can keep the customer’s existing groups and only add the current level group, or remove the customer from the other level groups. The Visitor, Guest, and Customer groups are always kept.
- Removing remaining level groups. When assigning a new level, the module can remove the customer from the remaining level groups. The Visitor, Guest, and Customer groups always remain.
What the customer sees in the store
- The “Your cumulative discount” block on the cart page. It shows the current level, customer total, discount percentage, level benefit, protection date, and the discount and threshold of the next level.
- The “Savings from cumulative discount” block in the cart and at checkout. It shows how much the customer saves thanks to the group discount. The amount is calculated using the same price path as the store prices, taking into account specific prices, exclusions, and discount combination rules.
- “Price before group discount” on the product page and in quick view. A crossed-out price without the group discount, calculated for the same quantity and in the same tax mode as the price next to it.
- The “My discount summary” page in the customer account. A table of all levels with thresholds, benefits, and discount amounts, the current level highlighted, progress to the next level, and the history of level changes with amounts in the customer’s currency.
- Link in the customer account. Markup for Classic, Hummingbird 1.x (PrestaShop 9.0), and Hummingbird 2.x (PrestaShop 9.1) themes.
- Only for the right customers. The blocks and refresh script are visible only to logged-in customers outside ignored groups, when the module is enabled and has configured levels.
Administration panel
- Tabs. Dashboard, Settings, Discount levels, Groups and exceptions, Product exclusions.
- Dashboard. Number of levels, registered customers, customers assigned to levels, active protections, and saved events. In addition, program adoption in percent, customer distribution by level, and the 20 most recent level changes.
- Bulk synchronization. Batch processing (from 10 to 500 customers, recommended 100) with a progress bar, resume after interruption, and counters: processed, updated, already correct, skipped, protected, errors. Emails during synchronization are optional and disabled by default. Synchronization is unavailable for the “current cart only” total.
- Permissions and security. Saving settings, levels, and synchronization require the module’s “configure” permission and the right to edit the modules page. An employee with view-only access does not see settings, levels, or customer data. Each form and synchronization request has its own module CSRF token, also when tokens in back office URLs are disabled.
Multistore
- Levels and settings for each store. Each store has its own thresholds, groups, order statuses, and other settings.
- Customer level separately in each store. When more than one store is active, the module saves the customer’s level separately for each store and applies it in prices. The customer’s default group in PrestaShop remains unchanged.
- Safe editing. Levels are added and edited in the context of a single store. In the “All stores” context, the list shows the store column.
- Synchronization and statistics. Each customer is evaluated against the thresholds and settings of their store, and statistics count customers separately for each store.
Prices, orders, and documents
- Discount calculated by PrestaShop. The level discount is a customer group discount, so it applies everywhere PrestaShop applies a group discount: in the catalog, on the product page, in the cart, in the order, and on the invoice.
- Compatibility with the native PrestaShop group. Automated tests compare prices on the product page, product list, in the cart, in the order summary, in the order data, and on the PDF invoice with the price of the same group in PrestaShop itself.
- Class overrides. The module installs overrides for the Product, Customer, Group, and Order classes, as well as invoice and PDF credit slip templates. An indicator in the header shows whether they are active.
- Price filter in faceted search. The module adjusts the price query of the ps_facetedsearch module so that it takes into account the specific prices of the group resulting from the customer’s level.
Compatibility, installation, and update
- PrestaShop 1.7.0–9.x, PHP 7.0–8.5. Automated tests (Playwright, Chromium) cover PrestaShop 1.7.2.4, 1.7.5.2, 1.7.6.7, 1.7.7.2, 1.7.8.5, 1.7.8.10, 8.0.0, 8.1.7, 8.2.6, 9.0.2, and 9.1.5 on PHP 7.0–8.1, with the Classic, Warehouse, and Hummingbird 2.x themes. The syntax of all files is checked on PHP 7.0–8.5.
- Update from earlier versions. Update scripts cover versions from 1.5.7; updating from 1.6.3 and from 1.8.2 is verified by tests. The update replaces overrides installed by older versions with current ones, leaves a copy of every changed file, and in case of a conflict with another module restores the previous files.
- Reset and uninstall. Reset repairs hooks, the database schema, and overrides without losing levels, customer states, or history. Uninstall removes the module tables and settings only when PrestaShop actually removes the module.
- Languages. The module interface is available in Polish and English, email templates in 9 languages.
Important operating limits
- With the total including the current cart, the customer may see the threshold of the next level even though the level has not been reached. The total in the block is calculated at the current level’s prices, and the next threshold at its lower prices.
- Adjusting the ps_facetedsearch price filter modifies that module’s file; it is repeated during module installation, update, and reset, and reverted on uninstall.
- In multistore mode, invoices and PDF credit slips on PrestaShop older than 8.1.2 use the group saved in PrestaShop, not the level from the store.
- On PrestaShop 1.7.7.x, some module texts in the store are displayed in English (a limitation of template translations in this PrestaShop version).
Link to the module demo:
Admin panel demo:
https://moduly-prestashop.eu/rabaty-kumulacyjne/admin-dev
Front office demo:
https://moduly-prestashop.eu/rabaty-kumulacyjne