Major/New Features

Store Credits support out of the box

Adds Store Credit payment method. Store credit can be granted in Admin Panel by store owners and is frozen after first usage. Store credit behaves like a Credit Card in that once an amount is authorized, it cannot be used elsewhere.

Store Credit can be used by customers on the checkout to pay for the order completely or be combined with other payment methods. In the near future we will work on official Spree Gift Cards extension which will use Store Credit as it’s framework.

Contributed by Jeff Dutil, Peter Berkenbosch, Michael Lippold, Marc Leglise & Spark Solutions

Versioned API

While we’ve had the ability to version our API we weren’t making use of it. Now that we’re beginning to write a new API we’ve added a v1 namespace, and default routing /api requests to use /api/v1. The /api/v2 will be opt-in until we feel it is complete, and have deprecated /api/v1 (likely for Spree 4).

Conitrbuted by Ben A. Morgan

Dynamic prices depending on zone for VAT countries

The European Union has come up with new legislation requiring digital products to be taxed using the customer’s shipping address. In turn, this means that prices have to be shown depending on the current order’s tax zone.

Your order will always use the price for the current tax zone. After the address step in the checkout process, the order will fetch the prices from the Variant again in order to make sure they’re correct.

For more information, see the taxation guide.

Conitrbuted by Martin Meyerhoff

Future Discontinue of Products & Variants

Soft deleting means that the records are left in the database but behave as if they are really deleted. Because associations from other objects (like line itmes to variant) won’t normally see the deleted, core code is forced (unnaturally) to use scopes like .with_deleted

We are fixing this by adding new feilds ‘Discontinue On’ to products & variants (discontinue_on)

This fixes a design flaw in that in most stores these objects really should not be considered “deleted.” The approach proposed solves the underlying flaw and all the related bugs caused by this flaw in the following ways:

  • Migrate the timestamps deleted_at to discontinue_on (when possible), and un-delete the deleted variants (when there is not matching SKU) and products (when there is no matching slug)

  • Redefine scopes Products object (see active, not_discontinued, etc)

  • Removes all references to unscope association chains from other objects to the Product & Variant objects in places where unscope is used explicitly to work-around the default scope problem. (This is a big win because it makes the associations cleaner and easier to work with.)

  • Although it is slightly counter-intuitive, we have left the deleted_at fields in place (although their data will be moved to discontinued_at field and their values will be reset to NULL in the db migration). You can (and should!) use deleting to remove human-error mistakes (real mistakes) before the items get sold in your store, or in the case when you have duplicate slugs (Products) or SKUs (Variants) in your database. In those special cases only, you should continue to use delete. In all other cases, use the new discontinue_on feature.

  • You can only delete a Product or Variant if no orders have been placed for that product/variant. Once the variant is associated with a Line item, it can never be “deleted,” and instead you must use the new discontinue_on feature. Model-level checks (before_destroy) enforce this.

  • Note: The DB migration should fix your database correctly unless you have created new Products & Variants with matching slugs/SKUs of deleted records. In this case, you must use the included rake db:fix_orphan_line_items task to clean up your records. Both the schema migration and the script are very pro-active in helping you fix your own database.

Contributed by Jason Fleetwood-Boldt & Spark Solutions

Fully responsive (RWD) notification emails

Notification emails such as Order Confirmation email or Shipment Confirmation email are now displayed properly on any screen size (mobile, tablet, dektop). User experience of those emails were also improved with clickable products, store logo and so on.

Contributed by Spark Solutions

Return Authorizations & Customer Returns Admin Panel screens

The returns index screens provide a listing of returns authorizations and customer returns. So you can browse them more easy instead of accessing them trough an order. You can easily search and filter both Return Authorizations and Customer Returns.

Conitrbuted by Rein Aris & VinSol

Admin Panel User Experience fixes

We’ve put a lot of work to make the Admin Panel more user-friendly, this includes among other things:

  • new breadcrumbs navigation #7319

  • unified and fixed form validations #7306 #7314 #7315

  • new order’s completion date format with time #7208

  • Stock Movement form moved to the new modern look & feel #7209

  • per_page, pagination & filtering fixes for records listings #6971

Contributed by Spark Solutions & Vinsol


Update Gemfile & Run Migrations

Other Gotchas

Make sure to v1 namespace custom rabl templates & overrides.

If your rabl templates reference others with extend you’ll need to add the v1 namespace.

For example:

extends 'spree/api/zones/show'


extends 'spree/api/v1/zones/show'

Remove Spree::Config.check_for_spree_alerts

If you were disabling the alert checks you’ll now want to remove this preference as it’s no longer used.

Noteworthy Changes

Also please review each of the noteworthy changes, and ensure your customizations or extensions are not effected. If you are affected by a change, and have any of your own tips please submit a PR to help the next person!

Full Changelog

You can view the full changes using Github Compare.

Noteworthy Changes

  • API v1 namespace to begin transition to v2.

    Ben A. Morgan

  • Remove all HABTM associations in favour of HMT associations.

    This removes the Spree::ShippingMethod::HABTM error message; Allows users to extend the joins tables since they are now models; And use the Apartment gem to their hearts content.

    Ben A. Morgan & VinSol

  • Removed Spree::Alert

    Jeff Dutil

  • Remove automatic payment creation with default credit card

    Darby Perez

  • Allow checkout errors to be displayed when updating customer details

    Darby Perez

  • Add default Refund Reason to seeds.rb

    Creating a Refund will fail if there’s no refund reason record in the database. That reason has to have the name set to “Return processing” and the mutable flag set to false.


    Martin Meyerhoff

  • Add a current_price_options helper to guide price calculation in the shop

    When you use dynamic prices (as detailed above), those prices will depend on something (like the tax zon of the current order, or whether your customer is a business customer). These option are set using the new current_price_options helper. If your prices depend on something else, overwrite this method and add more key/value pairs to the Hash it returns.

    Be careful though to also patch the following parts of Spree accordingly:

    • Spree::VatPriceCalculation#gross_amount
    • Spree::LineItem#update_price
    • Spree::Stock::Estimator#taxation_options_for
    • Subclass the DefaultTax calculator

      Martin Meyerhoff

  • Added Spree.admin_path option for a dynamic admin path; making automated ‘script’ attacks on the backend more difficult.

    You can simply configure the option by assigning the path in your Spree initializer: ruby Spree.admin_path = "/my-secret-backend"

    NOTE: Plugins are not converted and still use the default /admin path. But these plugins can be changed easily by adding the path: Spree.admin_path option in the routes.

    Rick Blommers & VinSol

  • Changed to Use Time.current instead of

    Rails uses config.time_zone to set time zone for the application, but uses server time zone instead of using set config.time_zone. So, in order to use application time zone we need to use Time.current/

    Abhishek Jain

  • Removed Order#has_available_shipment, which was unnecessary since it always returned nil


  • (OOS) Out of Stock Product page: better handling of cart form user experience

    Spark Solutions

  • Spree Command Installer won’t lock you to a specific Spree patch version, we’ll produce eg. gem 'spree', '~> 3.1.0' for easier updating

    Spark Solutions

  • Spree Auth Devise & Spree Gateway available from RubyGems

    Spark Solutions

  • Added /forbidden path

    Faruk Aydin & Spark Solutions

  • Changed before_filter to before_action


  • Additional database indexes for better performance

    Spark Solutions

  • Removed Order#shipping_method_id column


  • Added OrderContents#remove_line_item method


  • Ensure that Order#guest_token is unique

    Spark Solutions

  • Added missing views for image, option_type, option_value API controllers

    Alex B.

  • Renamed Order#update! to update_with_updater! as it conflicts with rails update! method, also deprecate current update! method


  • Removed Calculator#register method


  • Added HTML5 Product Microdata information

    Rehan Jaffer

  • Moved user class extensions to a module

    Alessandro Lepore

  • Added caching for default store and current tracker

    wuboy0307 & Spark Solutions

  • Added destroy functionality to refund_reason and return_authorization_reason


  • Deprecated Spree::Validations::DbMaximumLengthValidator, added DbMaximumLengthValidator instead


  • Deprecated Spree CMD installer in favour of standard gem-like installation process

    Spark Solutions