Channels
Introduction
Since version 3.0, Saleor has supported multiple sales channels. This feature allows the shop owner to configure many aspects of the store depending on the channel used.
- Your store needs at least one channel to display products
- You can add as many channels as you need
- Each channel has precisely one currency
- Channels can be deactivated for customers
Popular use cases:
- If you sell internationally, you can use separate channels for different currencies or regions
- If you want to have different prices in the custom mobile app and website, you can set up
website-channel
andmobile-channel
There are many models you can customize per channel. The details of which fields you can define on a per-channel basis are described in the ChannelListing
models:
Permissions
Listing channels is allowed only for users with the active isStaff
flag.
You need the MANAGE_CHANNELS
permission to create, edit, and remove channels.
Changing ChannelListing
does not require additional permissions. For example, changing Product availability requires only MANAGE_PRODUCTS
permission.
Getting channel details
Use channel
query to get channel details.
Available fields:
id
: Channel object IDname
: Channel nameisActive
: Flag signalling that the channel is available for shop customers.slug
: When using channel-dependant queries, the slug is used to select the right one (for example, when requesting Product details)currencyCode
: Currency code used by the channel.defaultCountry
: Default country for the channel. The default country will be used in checkout to determine the stock quantities or calculate taxes when the country was not explicitly provided, either as a query parameter or through a shipping address.hasOrders
: Returnstrue
when there are already created orders using that channel. If that's the only channel using this currency, you won't be able to remove it.warehouses
: Warehouses that are available in the given channel.stockSettings
: contains all stock-related settings, f.e. the allocation strategy for the channel.
Request:
query {
channel(id: "Q2hhbm5lbDo3") {
id
isActive
name
slug
defaultCountry {
code
country
}
hasOrders
warehouses {
slug
}
stockSettings {
allocationStrategy
}
}
}
Response:
{
"data": {
"channel": {
"id": "Q2hhbm5lbDo0MzM=",
"isActive": false,
"name": "Mobile",
"slug": "mobile",
"currencyCode": "USD",
"defaultCountry": {
"code": "US",
"country": "United States of America"
},
"hasOrders": false
"warehouses": [
{
"slug": "oceania"
},
{
"slug": "europe"
}
]
"stockSettings": {
"allocationStrategy": "PRIORITIZE_HIGH_STOCK"
}
}
}
Creating a new channel
You can create a new channel using channelCreate
mutation.
During checkout creation, you can define the allocation strategy. Right now the
two possible options are available: PRIORITIZE_HIGH_STOCK
and PRIORITIZE_SORTING_ORDER
,
the PRIORITIZE_SORTING_ORDER
strategy is used as default.
You can read more about the allocation strategies here
.
Request:
mutation {
channelCreate(
input: {
currencyCode: "USD"
defaultCountry: US
name: "Mobile"
slug: "mobile"
stockSettings: { allocationStrategy: PRIORITIZE_HIGH_STOCK }
}
) {
channel {
id
isActive
name
slug
currencyCode
defaultCountry {
code
country
}
stockSettings {
allocationStrategy
}
}
errors {
code
field
message
}
}
}
Response:
{
"data": {
"channelCreate": {
"channel": {
"id": "Q2hhbm5lbDo0MzM=",
"isActive": false,
"name": "Mobile",
"slug": "mobile",
"currencyCode": "USD",
"defaultCountry": {
"code": "US",
"country": "United States of America"
},
"stockSettings": {
"allocationStrategy": "PRIORITIZE_HIGH_STOCK"
}
},
"errors": []
}
}
}
Channel list
Because some of the channels may be considered non-public (for example - a channel for business partners), non-staff users cannot use the channels
query.
Request:
query {
channels {
name
}
}
Response:
{
"data": {
"channels": [
{
"name": "Mobile"
},
{
"name": "Website"
}
]
}
}
Activate / Deactivate channel
If you want to make the channel unavailable for customers, you can change it's status to deactivated
using channelDeactivate
mutation:
mutation {
channelDeactivate(id: "Q2hhbm5lbDoxMQ==") {
channel {
name
isActive
}
errors {
message
}
}
}
Response:
{
"data": {
"channelDeactivate": {
"channel": {
"name": "Facebook",
"isActive": false
},
"channelErrors": []
}
}
}
And to reverse the previous operation use the channelActivate
mutation:
mutation {
channelActivate(id: "Q2hhbm5lbDoxMQ==") {
channel {
name
isActive
}
errors {
message
}
}
}
Response:
{
"data": {
"channelDeactivate": {
"channel": {
"name": "Facebook",
"isActive": true
},
"channelErrors": []
}
}
}
Reorder warehouses within channels
The warehouses assigned to the channel can be sorted. The provided order defines the
warehouses' order used in PRIORITIZE_SORTING_ORDER
allocation strategy.
The sort_order
in moves
input represents the new relative position of the item.
So when 1 is provided, the item will be moved one position forward; when -1 - one
position backward.
Let's assume that we have a channel
with three channels in the following order.
{
"data": {
"channel": {
"id": "Q2hhbm5lbDox",
"warehouses": [
{
"id": "V2FyZWhvdXNlOjU1NTZiOWI0LTc1ZTItNGI3YS1hZWM1LTQxOTY4NDA2OGE4OA==",
"slug": "europe"
},
{
"id": "V2FyZWhvdXNlOjQwZWY1MTQwLWQ5OTYtNDVlNy04NzUzLTlkZThkMTdhMjg1Yw==",
"slug": "oceania"
},
{
"id": "V2FyZWhvdXNlOjY4M2FkMzZhLTRmNjktNDI2ZS1iYzUyLTMyZGJiZTQ2NjUyZA==",
"slug": "americas"
}
]
}
}
}
To move the americas
warehouse to the first place and the europe
warehouse to
third, we can run the following mutation.
mutation {
channelReorderWarehouses(
channelId: "Q2hhbm5lbDox"
moves: [
{
# move for `americas` warehouse
id: "V2FyZWhvdXNlOjY4M2FkMzZhLTRmNjktNDI2ZS1iYzUyLTMyZGJiZTQ2NjUyZA=="
sortOrder: -2
}
{
# move for `europe` warehouse
id: "V2FyZWhvdXNlOjU1NTZiOWI0LTc1ZTItNGI3YS1hZWM1LTQxOTY4NDA2OGE4OA=="
sortOrder: 1
}
]
) {
channel {
id
warehouses {
id
slug
}
}
errors {
field
code
message
warehouses
}
}
}
And as a response, we get:
{
"data": {
"channelReorderWarehouses": {
"channel": {
"id": "Q2hhbm5lbDox",
"warehouses": [
{
"id": "V2FyZWhvdXNlOjY4M2FkMzZhLTRmNjktNDI2ZS1iYzUyLTMyZGJiZTQ2NjUyZA==",
"slug": "americas"
},
{
"id": "V2FyZWhvdXNlOjQwZWY1MTQwLWQ5OTYtNDVlNy04NzUzLTlkZThkMTdhMjg1Yw==",
"slug": "oceania"
},
{
"id": "V2FyZWhvdXNlOjU1NTZiOWI0LTc1ZTItNGI3YS1hZWM1LTQxOTY4NDA2OGE4OA==",
"slug": "europe"
}
]
},
"errors": []
}
}
}
Removing a channel
Channels can be removed only when:
- There are no orders created in them.
- If there are orders created,
targetChannel
is required. Its currency has to be the same as the channel you are about to delete. All orders will be moved totargetChannel
.
channelDelete
mutation takes input:
id
: ID of the Channel that will be deletedtargetChannel
: all existing orders will be moved into this channel
channelDelete(
id: ID!
input: ChannelDeleteInput
): ChannelDelete
input ChannelDeleteInput {
targetChannel: ID!
}
Errors
type ChannelError {
field: String
message: String
code: ChannelErrorCode!
}
enum ChannelErrorCode {
ALREADY_EXISTS
GRAPHQL_ERROR
INVALID
NOT_FOUND
REQUIRED
UNIQUE
CHANNEL_TARGET_ID_MUST_BE_DIFFERENT
CHANNELS_CURRENCY_MUST_BE_THE_SAME
}
ChannelErrorCode
values:
ALREADY_EXISTS
: Object already exists in the databaseGRAPHQL_ERROR
: Wrong queryINVALID
: Invalid data providedNOT_FOUND
: Could not found objectREQUIRED
: Missing required fieldsUNIQUE
: Provided value for field needs to be uniqueCHANNEL_TARGET_ID_MUST_BE_DIFFERENT
: Cannot move orders into the channel you want to deleteCHANNELS_CURRENCY_MUST_BE_THE_SAME
: Target channel has to have the same currency