Saleor 3.8 & 3.9: flat rates, tax exemption API, and GraphiQL

Karol Kielecki
Saleor
Published in
5 min readJan 25, 2023

This article summarizes the 3.8 and 3.9 releases of Saleor. We introduced flat rates along with a tax exemption API, GraphiQL V2, and more.

Saleor 3.8: GraphiQL 2 and tax exemption API

GraphiQL 2

We have switched to the long-awaited GraphiQL 2 which adds many enhancements compared to the previous playground. Notable improvements are:

  • improved user interface
  • query history
  • merge fragments into query
  • sharable playgrounds - see the video below:

Tax exemption API

We’ve added a new permission to manage this API - MANAGE TAXES.

You can use the following mutation to disable taxes from a specific checkout - you can also set a tax exemption for orders. You need to provide a checkout ID, or order ID, and set the flag to false.

mutation {
taxExemptionManage(id: "checkout-id", taxExemption: false) {
taxableObject {
__typename
... on Checkout {
token
}
}
}
}

Check our documentation to learn more about tax exemption API.

Filtering by slugs

You can now filter through a slug in the following objects:

  • Attribute
  • Category
  • Collection
  • Menu
  • Page
  • Product
  • ProductType
  • Warehouse

New product filters

You can use the following new product filters:

  • isAvailable
  • publishedFrom
  • availableFrom
  • isVisibleInListings

Datagrid

Now you can manage product data with a spreadsheet interface directly in the dashboard, bulk updates, copy-paste from external sources, and more! 🚀

All summarized pull requests that have been merged are available in the following Saleor 3.8 Changelog.

Saleor 3.9: new tax calculation API

Introduction to tax improvements

With v3.9, we introduced the complete rework of the tax calculation engine. The new tax API allows defining tax rates per country and tax class. What’s more, you can also customize taxes per channel. The following concept introduces tax configuration (a channel configuration) and tax classes (tax for specific countries). We’ve also decided to drop the Vatlayer plugin because our new engine covers a major part of its logic.

Tax configuration

The tax configuration object defines different configuration options for a channel, such as tax calculation method, whether to charge taxes in this channel or whether prices are entered, including tax. The tax configuration object is created automatically for each sales channel. In the API, it is represented by the TaxConfiguration object. See the API reference for descriptions of all properties.

Below are some common examples of getting and managing the tax configuration.

Fetching tax configurations

To fetch a list of tax configurations with their properties, use the following query:

query TaxConfigurations {
taxConfigurations(first: 10) {
edges {
node {
id
channel {
slug
}
chargeTaxes
displayGrossPrices
pricesEnteredWithTax
taxCalculationStrategy
}
}
}
}

To query a specific tax configuration by ID, use the query below (in this case, we’re only asking for the taxCalculationStrategy field):

query TaxConfiguration {
taxConfiguration(id: "VGF4Q29uZmlndXJhdGlvbjox") {
taxCalculationStrategy
}
}

Updating the tax configuration

The taxConfigurationUpdate mutation allows you to update a specific tax configuration. The example below shows how to set the tax calculation strategy to dynamic taxes (in API represented as the TAX_APP option):

mutation {
taxConfigurationUpdate(
id: "VGF4Q29uZmlndXJhdGlvbjox"
input: {taxCalculationStrategy: TAX_APP}
) {
errors {
field
message
}
taxConfiguration {
taxCalculationStrategy
}
}
}

Overriding tax configuration per country

You can override channel-specific tax configurations for different countries. Let’s consider the following example: there is a single sales channel that uses flat rates for EU countries, but for the US, it uses the Avalara integration. To represent such a scenario in Saleor, we need to set the flat rates as the channel’s default tax calculation strategy and override the configuration for the US to use dynamic taxes:

mutation {
taxConfigurationUpdate(
id: "VGF4Q29uZmlndXJhdGlvbjox"
input: {
taxCalculationStrategy: FLAT_RATES,
updateCountriesConfiguration: [
{
countryCode: US,
taxCalculationStrategy: TAX_APP,
displayGrossPrices: false,
chargeTaxes: true
}
]}
) {
errors {
field
message
}
taxConfiguration {
taxCalculationStrategy
countries {
country {
code
}
chargeTaxes
taxCalculationStrategy
displayGrossPrices
}
}
}
}

Flat tax rates

Flat tax rates are the default tax calculation strategy that is enabled for any new sales channel. With this method, you can configure static tax rates and associate them with products, product types, or shipping methods. Tax rates can be defined either as default country rates or can be overridden for specific products with tax classes. During checkout, Saleor uses either default country rates or overridden values from tax classes.

Enabling flat rates for a channel

To enable flat rates, use the following mutation:

mutation {
taxConfigurationUpdate(
id: "VGF4Q29uZmlndXJhdGlvbjox"
input: {taxCalculationStrategy: FLAT_RATES}
) {
errors {
field
message
}
taxConfiguration {
taxCalculationStrategy
}
}
}

Creating a default national tax rate

The default national tax rate is used for products and shipping methods when there is no other tax class assigned to them. In the following mutation, we used the Polish default tax rate (23%):

mutation {
taxCountryConfigurationUpdate(
countryCode: PL
updateTaxClassRates: [{rate: 23}]
) {
taxCountryConfiguration {
country {
code
}
taxClassCountryRates {
rate
}
}
errors {
field
message
}
}
}

Assigning a specific tax rate to a product

To create a tax rate that would be used only for specific products, you must create a tax class and assign it to the product. The example below shows a tax class “Healthcare products” with an 8% tax rate for Poland:

mutation {
taxClassCreate(
input: {
name: "Healthcare products",
createCountryRates: [{countryCode: PL, rate: 8}]}
) {
errors {
field
message
}
taxClass {
id
countries {
rate
}
}
}
}

To assign a tax class to a product, use the following mutation:

mutation {
productUpdate(id: "UHJvZHVjdDox", input: {taxClass: "VGF4Q2xhc3M6Mg=="}) {
errors {
field
message
}
product {
taxClass {
name
}
}
}
}

Setting flat tax rates via dashboard

You can also see how to manage flat rates via your dashboard in the video below. As you have probably already noticed, we have introduced a new, fresh look to the Saleor Dashboard.

A flat tax rate is not the only change delivered. Please check the Saleor 3.9 changelog to read more about all improvements.

In this blog post, we highlighted some of the key changes and improvements in Saleor 3.8 and 3.9. Follow our Twitter and sign up for our newsletter to stay up to date with the latest info about Saleor!

Cheers!

– The Saleor Team

--

--