Skip to main content
Version: 3.x

Channels

Introduction

Since version 3.0, Saleor supports 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 exactly 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 and mobile-channel

There are many models which can be customized per channel. Details which fields can be defined on a per-channel basis are defined in ChannelListing models:

Permissions

Listing channels is allowed only for users with active isStaff flag.

Creating, editing, removing channel the MANAGE_CHANNELS permission is required. Changing ChannelListing does not require additional permissions. For example, changing Product availability requires only MANAGE_PRODUCTS.

Getting channel details

Use channel query to get channel details.

Available fields:

  • id: Channel object ID
  • name: Channel name
  • isActive: Flag which changes if the channel is available for shop customers.
  • slug: When using channel depending queries, the slug is used for selecting 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: Returns true 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

Request:

query {
channel(id: "Q2hhbm5lbDo3") {
id
isActive
name
slug
defaultCountry {
code
country
}
hasOrders
}
}

Response:

{
"data": {
"channel": {
"id": "Q2hhbm5lbDo0MzM=",
"isActive": false,
"name": "Mobile",
"slug": "mobile",
"currencyCode": "USD",
"defaultCountry": {
"code": "US",
"country": "United States of America"
},
"hasOrders": false
}
}

Creating a new channel

Creating a new channel is done using channelCreate mutation.

Request:

mutation {
channelCreate(
input: {
currencyCode: "USD"
defaultCountry: US
name: "Mobile"
slug: "mobile"
}
) {
channel {
id
isActive
name
slug
currencyCode
defaultCountry {
code
country
}
}
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"
},
},
"errors": []
}
}
}

Channel list

Because some of the channels may be considered non-public (for example - channel for business partners), non-staff users can not use 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 {
channelDeactivate(id: "Q2hhbm5lbDoxMQ==") {
channel {
name
isActive
}
errors {
message
}
}
}

Response:

{
"data": {
"channelDeactivate": {
"channel": {
"name": "Facebook",
"isActive": false
},
"channelErrors": []
}
}
}

And to reverse the previous operation use channelActivate:

mutation {
channelActivate(id: "Q2hhbm5lbDoxMQ==") {
channel {
name
isActive
}
errors {
message
}
}
}

Response:

{
"data": {
"channelDeactivate": {
"channel": {
"name": "Facebook",
"isActive": true
},
"channelErrors": []
}
}
}

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 as same as a channel you are about to delete. All orders will be moved to targetChannel.

channelDelete mutation takes input:

  • id: Channel ID which will be deleted
  • targetChannel: if there are existing orders, they 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 database
  • GRAPHQL_ERROR: Wrong query
  • INVALID: Invalid data provided
  • NOT_FOUND: Could not found object
  • REQUIRED: Missing required fields
  • UNIQUE: Provided value for field needs to be unique
  • CHANNEL_TARGET_ID_MUST_BE_DIFFERENT: Cannot move orders into the channel you want to delete
  • CHANNELS_CURRENCY_MUST_BE_THE_SAME: Target channel has to have the same currency