This guide explains Spree’s promotions system for coupon codes and discounts. After reading it, you should be familiar with:

  • The process of creating a new promotion in Spree
  • How exactly a promotion qualifies to be eligible
  • The rules & adjustments components of a promotion

1 Overview

Promotions are used to give discounts or other types of rewards to customers.

Discounts can be things such as a discount of $20 for the first item and $2 for additional items for a maximum of five items. They could also be a flat percent off for the entire order, say 15%, or a specific dollar figure, such as $10 off.

Rewards could be things such as free shipping, or a flat-rate off per item in the order.

2 Creating a new promotion

To create a new promotion, you must go to the admin dashboard for your Spree store. If your application includes the spree_promo gem, you will see the “Promotions” link at the top of the screen:

Promotions tab

When you click on this tab, you’ll be taken to a list of all the promotions within your system. In this next screenshot, there’s only one promotion called “50% off all products”:

Promotions listing

To create click the “New Promotion” button up the top-right of this screen:

New promotion button

On the new promotion screen, you can enter the details for the promotion that you wish to create.

New promotion screen

2.1 General fields

The name of the promotion is what will be displayed on the checkout page, along with the discount price, once the promotion has been applied to the order. The description field is used to provide a helpful description of this promotion which is displayed on the promotion listing page in the admin interface.

The advertised checkbox allows you to select if this promotion should be returned in a call to Spree::Promotion.advertised. This method will return all advertised promotions, and you can use it to display the promotions that buyers can use.

If “Coupon code added” is selected from the event dropdown, an additional field called “Code” must be filled out with the code that users will enter on the payment screen to activate this promotion on their order.

If “Visit static content page” is selected from the event dropdown, an additional field called “Path” must be filled out with a path that, once visited, triggers the promotion on the order.

Events are explained in the Events section below.

2.2 Expiry fields

The usage limit field limits the number of times a promotional code can be used. This can be left blank to indicate an infinite amount of usage.

The starts at field takes a date from when the promotion is first able to be used, while the expires at sets an end date after which the promotion can no longer be used. Both of these fields can be left blank to indicate no start or end date on the promotion, respectively.

2.3 Events

There are number of events that occur that would activate a promotion.

If an item is added to the cart, then all eligible promotions with the “Add to cart” event selected are applied to that order.

If the order contents change, say if a line item’s quantity was updated or a new item was added to the cart, then the eligible “Order contents changed” promotions are applied to that order.

When the user signs up and places an order, or places an order and, during the process, registers either as a guest user or a new user in the system, then the eligible “User signup” promotions are applied to that order.

If the user enters the coupon code on the payment page, then the “Coupon code added” promotion that matches that coupon code is applied to the order. If there is no promotion with that code or the promotion has expired, the user is notified of this event and asked to try again.

If the “Visit static content page” is selected for a promotion, the user must visit a static content page provided by Spree’s ContentController for this promotion to be applied to their current order.

3 Eligibility

Promotions are only activated if they are considered eligible. Eligibility is a combination of general settings that control expiry of promotions and Promotion Rules that control eligibility based on the current order and user.

As described above, some of the qualifiers for eligibility are the number of times a promotion has been used and effective start and end dates.

There are further rules for eligibility which are only available after a promotion has been created.

3.1 Promotion rules

To control eligibility based on the current order and user, as many rules as required may be added to the promotion. You are able to select if all or any of the rules need to apply for a promotion to be eligible. There can only be one rule of each type applied to a single promomotion.

The Rules area on the promotions screen looks like this:

Rules for a promotion

In the above screenshot, there is one rule that must be matched in order for the promotion to be eligible.

To create a new rule, select a new type of rule from the “Add rule of type” dropdown at the bottom right of this area and then click add. A new rule will appear on the page momentarily and you can fill in the details with it.

The following types of rules are available:
  • Item Total - the order’s item total must exeed or be at least equal to the specified amount
  • Products - order must include chosen products, or include products from a chosen product group
  • User - promotion is only available to the specified users
  • First Order - this must be the user’s first order
  • User Logged In - the user must be logged in as a real user, and not a guest

4 Promotion Actions

To configure the outcome of a promotion, Promotion Actions are added in the same manner as Promotion Rules. This means a promotion could result in mulitple actions being performed such as a discount adjustment created on the order, an email being delivered or a predefined set of items being added to the cart.

The default available actions are:

  • Create adjustment - creates an adjustment against the order using a calculator (including flat rate per order / item, free shipping, etc).
  • Create line items - will add specific products or variants to the order.

It is easy to add new action types by defining a subclass of PromotionAction which implements the perform method. Call register on your subclass to make it available to choose in the admin interface. See Promotion::Actions::CreateAdjustment for an example.

5 Promotion adjustments

The typical outcome of a promotion is to provide a discount on the order with a negative value adjustment. This is achieved by adding an action to your promotion of the type ‘Create Adjustment’.

Promotion actions

In the above example, there is a promotion adjustment that decreases the order amount by 10%. The calculators by default are:

  • Flat percent - Deducts a given percent from the order.
  • Flat rate (per item) - Deducts a given amount from the order, based on the number of items that have been added to the order.
  • Flat rate (per order) - Deducts a given amount from the order, regardless of the number of items.
  • Flexible rate - Allows for fine grained control over adjustments, allowing for a specific discount for the first item, different discount for further items and up to a certain quantity of items.
  • Free shipping - Any shipping costs on an order are automatically waived.

A calculator is selected when configuring the ‘Create Adjustment’ action and this is responsible for computing the amount of the adjustment. Spree will not allow the credit amount to exceed item total + shipping, and the amount will always be negative. The credit adjustment associated with the promotion is subject to recalculation based on changes in the order.

Please be sure to read the section on calculators for a more complete understanding of this crucial concept.

Spree will only allow an order to have one promotion adjustment active at a time. Each time the order is updated, e.g. when adding to the card or updating quantities, the eligibility of all the promotion created adjustments is re-checked and only the most valuable promotion adjustment that is still eligible will be counted.

Any other adjustments are preserved but have their eligible attribute set to false so they are not displayed or counted in any totals. This allows a previously de-activated adjustment to become active again if it becomes eligible or its value changes.

This project is maintained by a core team of developers and is freely available for commercial use under the terms of the New BSD License.