Solidus's taxation system supports both sales- and VAT-style taxes. You can use
tax rates, tax categories, and the built-in tax calculator to handle your
store's tax logic. Solidus uses the Spree::Adjustment
model to apply taxes to
orders. This way, there can be multiple tax adjustments applied to each order.
Using adjustments helps account for some of the complexities of tax, especially if a store sells internationally:
Solidus uses the Spree::TaxCategory
and Spree::TaxRate
models to specify the
rules for how tax adjustments are calculated. Tax adjustments are created for
each line item in an order.
See the Order taxation section for an overview of the order taxation process.
Tax categories can be used to ensure particular products are taxed as required. For example, if your business is based in Minnesota, you need to charge tax on tech products but do not need to charge tax on clothing. You could set up two tax categories, Clothing and Tech which you would apply to products of either type.
By default, new products do not have a set tax category. Administrators can set the tax category while creating the product or set it later while editing the product.
Tax rates define the amount of tax that should be charged on items. You might configure different tax rates for different zones and tax categories, or even for specific dates. You could also create more complex tax rates with a custom tax calculator.
In Solidus, a tax rate consists of at least four values:
Solidus calculates tax based on the matching tax rate(s) for the order's tax address .
If an order's tax_address
falls within a specific zone, the tax rates that you
have configured would apply for all the line items and shipments in that zone
that have a matching tax category.
By default, the tax_address
used for orders is the customer's shipping
address. This is how most tax jurisdictions require taxes to be calculated.
However, you can configure your store to globally use customer billing
addresses instead in any initializer file inside the config/initializers/
directory:
Spree::Config[:tax_using_ship_address] = true
Spree::TaxLocation
as the tax addressAn order's tax_address
can – through
duck typing
– be a
Spree::Tax::TaxLocation
instead of the shipping address. The tax location is
computed from the store's Spree.config.cart_tax_country_iso
setting.
Note that you can only trust the tax address if it has a country. The other address fields might be empty or raise errors.
In ecommerce, consumption tax either takes the form of sales tax or value-added tax. Some countries use other names for their taxes, but generally all modern consumption taxes would be considered one of these two types.
Solidus's models support both types of taxes. In the case of a product or shipment:
Note that sales tax in the United States can get exceptionally complex. Each state, county, and municipality might have a different tax rate.
If you intend to ship products between states, and your store is based in the
United States, we recommend that you use an external service like
Avatax
or
Tax Cloud
to automate your U.S. tax rates.
Solidus has extensions for both of these services:
solidus_avatax_certified
and
solidus_tax_cloud
.
Once the order has a tax_address
specified, tax can be calculated for all of
the line items and shipments associated with a Spree::Order
:
Note that any promotional adjustments are applied before tax adjustments. This is to comply with tax regulations for value-added taxation as outlined by the Government of the United Kingdom and for sales tax as outlined by the California State Board of Equalization .
amount
value. (price ✕ quantity ➖ promotions
.)Spree::Adjustment
object that is
associated with the order's ID.included_tax_total
or additional_tax_total
are updated.
(If the Spree::TaxRate
's included_in_price
value is set to true
,
Solidus uses the included_tax_total
column to store the sum of VAT-style
taxes. Otherwise, it uses the additional_tax_total
to store the sum of
sales tax-style taxes.)Spree::Shipments
.included_tax_total
and additional_tax_total
on all line
items and shipments a stored in the order's included_tax_total
and
additional_tax_total
values.The included_tax_total
column does not affect the order's total, while the
additional_tax_total
does.
Every time an order is changed, the taxation system checks whether tax adjustments need to be changed and updates all of the taxation-relevant totals.
See the taxation integration spec for more information on Solidus's taxation system.
Solidus is an open source platform supported by the community. We encourage everyone using Solidus to contribute back to the documentation and the code.
If you’re interested in contributing to the docs, get started with the contributing guidelines. If you see something that needs fixing and can’t do it yourself, please send us an email.