Major/new features

Adjustments Refactoring

The adjustments system in Spree has undergone a large portion of work. Adjustments (typically originating from promotions and taxes) can now be applied at a line item, shipment or order level.

This system has been designed to be backwards-compatible with older versions of Spree, so that an upgrade path is relatively easy. If you encounter any issues during an upgrade, please file an issue.

Along with this, taxes are now split into two groupings: “additional” and “included”. Additional taxes are those which increase the price of the item they’re attached to. Included taxes are those which are already included in the cost of the item. It is still necessary to track these included taxes due to tax reporting requirements in many countries.

Shipments no longer have a linked adjustment. Instead, the shipment itself has a “cost” attribute which is used in the calculation of shipping costs for an order.

Also worth noting is that the number of callbacks triggered when any aspect of an order is updated has been greatly reduced, which should lead up to speed-ups in stores. An example of this would be in prior versions of Spree, an order would trigger an update on all its adjustments when it updated. With the new system, only line items or shipments that change will have their adjustments updated.

For more information about this, Ryan Bigg wrote up a long explanation about it, and there is further discussion on #3567.

Fragment caching

In certain places in the frontend, the following changes have been applied:

  • Fragment caching for each product.
  • Fragment caching for the lists of products in home/index and products/index.
  • Fragment caching for a taxon’s children.

This can lead to significant speedups in the frontend of a Spree store.

See more about this in this comment on spree/spree#2913.

Asset renaming

An issue was brought up in #4050 where a user showed us that a require_tree use inside app/assets would also require the Spree assets that were placed in app/assets/store and app/assets/admin` respectively. This would happen in areas of the application where Spree wasn’t even used.

To fix this bug, we have moved the location of the assets to vendor/assets. Frontend’s assets are now placed in vendor/assets/spree/frontend and Backend’s are in vendor/assets/spree/backend.

Similar changes to this have also been made to extensions, where their assets are now placed in app/assets/spree/[extension_name]. Ultimately, these changes fix the bug and now we’re using the same names to refer to the same components (store -> frontend, admin -> backend) on assets as we do internally to Spree.

You will need to manually rename asset requires within your application:

  • admin/spree_backend => spree/backend
  • store/spree_frontend => spree/frontend

Risk analysis

The AVS and CVV response codes for payments are now checked to determine the possibility that an order is considered risky. If the order is considered risky, then it will transition to a ‘considered risky’ state upon finalize rather than ‘complete’. The order must be approved in the admin backend in order for it to proceed to the ‘complete’ state.

Stores may choose to override Order#is_risky to implement their own risk analysis for orders.

See issues #4021 and #4298 for further information.

Paperclip settings have been removed

The ability to configure Paperclip settings for Spree::Image has been removed from Spree. The alternative to this is to configure the Paperclip settings for Spree::Image in an initializer:

Paperclip::Attachment.default_options[:s3_protocol] = "https"
Spree::Image.attachment_definitions[:attachment][:styles] = "<styles go here>"
Spree::Image.attachment_definitions[:attachment][:path] = "<path goes here>"

These settings are for the Paperclip gem, and hence more information about them can be found in Paperclip’s documentation.

You may wish to use S3, in which case you can configure it using code like this Gist.

Minor changes


  • Switched to using friendly_id for permalink generation. This meant that we needed to rename Spree::Product’s permalink field to slug.

    Ryan Bigg

  • Add a name column to spree_payments. That should hold the Name on card option in payment checkout step.

    Washington Luiz

  • Associate line item and inventory units for better extensibility with product assemblies. Migration was added to set line_item_id for existing inventory units.

  • A channel column was added to the spree_orders table. Users can set it when importing orders from other stores. e.g. amazon

    Washington Luiz

  • Introduce Core::UserAddress module. Once included on the store user class the user address can be rememembered on checkout

    Washington Luiz

  • Added tax_category to variants, to allow for different variants of a product to have different tax categories. #3946

    Peter Rhoades

  • Removed Spree::Activator. Promotions are now activated using the Spree::PromotionHandler classes.

    Ryan Bigg

  • Promotion#event_name attribute has been removed. A promotion’s event now depends on the fields that are filled out during its creation.

    Ryan Bigg

  • Simplified OrderPopulator to take only a variant_id and a quantity, rather than a confusing hash of product/variant ids.

    Ryan Bigg

  • lib/ is no longer in autoload paths. You’ll have to manually require what you need in that dir. See

  • Introduce Spree::Core::MailMethod to manage mail settings at each delivery. This allows changes to mail settings to be applied without a server restart. See

    John Hawthorn

  • Create Spree::Migrations to warn about missing migrations. See #4080

    Washington Luiz

  • Variant#in_stock? now no longer takes a quantity. Call can_supply? instead. see #4279

    Ryan Bigg / Peter Berkenbosch

  • PromotionRule#activator_id column has been renamed to promotion_id.

    Ryan Bigg


  • Api requires authentication by default now

    Peter Berkenbosch

  • Improve products_controller #create and #update for better support to create and update variants, option types and option values. See #4172 and #4240

    Bruno Buccolo / Washington Luiz / John Dyer

  • ApiHelpers attributes can now be extended without overriding instance methods. By using the same approach in PermittedAttributes. e.g.

    Spree::Api::ApiHelpers.order_attributes.push :locked_at

    Washington Luiz

  • Admin users can set the order channel when importing orders. By sing the channel attribute on Order model

    Washington Luiz

  • Cached products/show template, which can lead to drastically (65x) faster loading times on product requests. 806319709c4ce9a3d0026e00ec2d07372f51cdb8

    Ryan Bigg

  • The parts that make up an order’s response from /api/orders/:num are cached, which can lead to a 5x improvement of speed for this API endpoint. 80ffb1e739606ac02ac86336ac13a51583bcc225

    Ryan Bigg

  • Cached variant objects which can lead to slightly faster loading times (4x) for each variant.

    Ryan Bigg

  • Added a route to allow for /api/variants/:id requests

    Ryan Bigg

  • Products response now contains a master variant separately from all the other variants. Previously all variants were grouped together.

    Ryan Bigg

  • Added API endpoint to retrieve a user’s orders: /api/orders/mine. #4022

    Richard Nuno

  • Order token can now be passed as a header: X-Spree-Order-Token. #4148

    Lucjan Suski


  • Payment step displays a name input so that users can enter Name on card Previously we had a first_name and last_name hidden input instead.

    Washington Luiz

  • Checkout now may remember user address

    Washington Luiz


  • Don’t serve JS to non XHR requests. Prevents sentive data leaking. Thanks to Egor Homakov for pointing that out in Spree codebase. See for details.

  • ‘Only show completed orders’ checkbox status will now persist when paging through orders.

    • darbs + Ryan Bigg
  • Implemented a basic Risk Assessment feature in Spree Backend. Viewing any Order’s edit page now shows the following, with a status indicator:

      Payments; link_to new log feature (ie. Number of multiple failed authorization requests)
      AVS response (ie. Billing address not matching credit card)
      CVV response (ie. code not matching)
    • Ben Radler (aka lordnibbler)
  • Moved ‘Taxonomies’ out from under ‘Configuration’ menu. It now is a sub-menu item on the products.

    • Ryan Bigg