dist/cursor/saleor-commerce/skills/saleor-channels/SKILL.md
Configure Saleor channels — multi-currency, multi-region, per-channel pricing, warehouse allocation, and multi-brand setups. Use when managing multi-channel commerce.
npx skillsauth add orcaqubits/agentic-commerce-claude-plugins saleor-channelsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Fetch live docs:
https://docs.saleor.io/docs/developer/channels for channels overviewsite:docs.saleor.io channel configuration currency countries for channel setup referencesite:docs.saleor.io per-channel pricing product for channel-aware pricingsite:docs.saleor.io warehouse allocation channels for warehouse-channel mappingsite:docs.saleor.io multi-brand multi-tenant channels for multi-brand patternsA channel represents a distinct sales context within a single Saleor instance. One Saleor deployment can serve multiple storefronts, regions, brands, or business models -- each as a separate channel.
| Aspect | Detail | |--------|--------| | One instance | Single Saleor backend, shared catalog and infrastructure | | Many channels | Each channel has its own currency, countries, pricing, and settings | | Isolation | Customers see only channel-scoped data (prices, availability) | | Staff access | Staff can manage all channels from one Dashboard |
| Field | Type | Purpose |
|-------|------|---------|
| name | string | Human-readable channel name |
| slug | string | URL-safe identifier (used in API queries) |
| currencyCode | string | ISO 4217 currency code (e.g., USD, EUR, GBP) |
| defaultCountry | string | ISO 3166-1 alpha-2 country code |
| countries | string[] | Countries where this channel operates |
| isActive | boolean | Whether the channel is publicly accessible |
| stockSettings.allocationStrategy | enum | PRIORITIZE_HIGH_STOCK or PRIORITIZE_SORTING_ORDER |
| orderSettings.automaticallyConfirmAllNewOrders | boolean | Auto-confirm orders |
| orderSettings.automaticallyFulfillNonShippableGiftCard | boolean | Auto-fulfill digital gift cards |
| checkoutSettings.useLegacyErrorFlow | boolean | Legacy vs new error handling |
Products have base prices, but each channel can define its own pricing:
| Pricing Layer | Scope | Purpose | |--------------|-------|---------| | Product variant price | Per channel | Base selling price in channel currency | | Cost price | Per channel | Cost of goods for margin calculation | | Channel currency | Per channel | All prices in this channel use this currency | | Tax configuration | Per channel | Tax calculation rules | | Discounts | Per channel | Promotions scoped to specific channels |
| Entity | Channel-Scoped Fields |
|--------|----------------------|
| Product variant | channelListings.price, channelListings.costPrice |
| Product | channelListings.isPublished, channelListings.publishedAt, channelListings.isAvailableForPurchase |
| Collection | channelListings.isPublished, channelListings.publishedAt |
| Shipping method | channelListings.price, channelListings.minimumOrderPrice, channelListings.maximumOrderPrice |
| Voucher | channelListings.discountValue, channelListings.minSpent |
Each channel defines a set of countries it serves:
| Aspect | Detail | |--------|--------| | Shipping | Only shipping methods for assigned countries are available | | Tax | Tax rules are applied based on channel country settings | | Address validation | Checkout validates against channel's country list | | Warehouse selection | Warehouses are linked to countries within channels |
Warehouses and channels are connected through country assignments:
| Concept | Relationship | |---------|-------------| | Warehouse | Has a list of shipping zones it serves | | Shipping zone | Has a list of countries | | Channel | Has a list of countries | | Allocation | Saleor allocates stock from warehouses that serve the channel's countries |
| Strategy | Behavior |
|----------|----------|
| PRIORITIZE_SORTING_ORDER | Allocate from warehouses in their configured sort order (default) |
| PRIORITIZE_HIGH_STOCK | Allocate from the warehouse with the most stock |
Most storefront queries require a channel argument:
| Query | Channel Behavior |
|-------|-----------------|
| products(channel: "us") | Returns products published in the US channel |
| product(slug: "tee", channel: "us") | Returns US-channel pricing and availability |
| collections(channel: "us") | Returns collections published in the US channel |
| checkout(channel: "us") | Creates checkout with US currency and settings |
| shippingMethods(channel: "us") | Returns methods available for US channel countries |
Queries without the channel argument are reserved for staff/admin operations and return data across all channels.
| Mutation | Purpose |
|----------|---------|
| channelCreate | Create a new channel with currency and country settings |
| channelUpdate | Modify channel settings (countries, stock strategy) |
| channelDelete | Remove a channel (irreversible) |
| channelActivate | Make a channel publicly accessible |
| channelDeactivate | Hide a channel from public access |
| Input Field | Required | Purpose |
|-------------|----------|---------|
| name | Yes | Display name |
| slug | Yes | URL-safe identifier |
| currencyCode | Yes | Channel currency |
| defaultCountry | Yes | Primary country |
| addCountries | No | Additional countries |
| stockSettings | No | Allocation strategy |
| orderSettings | No | Auto-confirm, fulfillment rules |
Channels enable multi-brand commerce from a single Saleor instance:
| Brand | Channel | Storefront | Currency |
|-------|---------|-----------|----------|
| Brand A (US) | brand-a-us | brand-a.com | USD |
| Brand A (EU) | brand-a-eu | brand-a.eu | EUR |
| Brand B (US) | brand-b-us | brand-b.com | USD |
| Wholesale | wholesale | wholesale.brand-a.com | USD |
| Aspect | Approach | |--------|----------| | Product catalog | Shared catalog, per-channel publication and pricing | | Customers | Shared customer base across channels | | Orders | Each order belongs to one channel | | Staff permissions | Channel-level access control for staff members | | Apps | Apps can be channel-aware or cross-channel | | Warehouses | Shared warehouses, per-channel allocation |
| Permission | Scope |
|------------|-------|
| MANAGE_CHANNELS | Create, update, delete channels |
| Channel-restricted staff | Staff members can be limited to specific channels |
| App permissions | Apps operate across all channels unless filtered |
us-store, eu-store)PRIORITIZE_SORTING_ORDER allocation strategy when warehouse priority mattersFetch the Saleor channels documentation for exact mutation inputs, allocation strategy details, and multi-brand configuration patterns before implementing.
development
Build with Spree's headless Next.js storefront — the official `spree/storefront` repo (Next.js 16 App Router with Server Actions and Turbopack, React 19 Server Components, Tailwind CSS 4, TypeScript 5, `@spree/sdk`, Sentry), server-only auth (httpOnly JWT cookies + publishable key), MeiliSearch faceted catalog, one-page checkout with Apple/Google Pay/Klarna/Affirm/SEPA, multi-region market routing, GA4 + JSON-LD SEO, and Vercel/Docker deployment. Use when forking or customizing the storefront, or evaluating headless adoption.
tools
Build Spree extensions as Rails engines — gem scaffolding, `bin/rails g spree:extension`, mounting routes/migrations/assets, the modern `prepend` decorator pattern (`*_decorator.rb` with `self.prepended(base)`), generators (`spree:model_decorator`, `spree:controller_decorator`), the four customization surfaces in preference order (Events > Webhooks > Dependencies > Decorators), Spree::Dependencies for swapping service objects, gem release/versioning, and the deprecated Deface engine. Use when building a reusable Spree extension or adding non-trivial customization to an app.
development
Build with Spree's event bus and Webhooks 2.0 — `Spree::Events` publication, `Spree::Subscriber` DSL with `subscribes_to` and `on`, wildcard matching, lifecycle events (`{model}.created/.updated/.deleted` via `publishes_lifecycle_events`), the canonical event catalog (order.*, payment.*, shipment.*, product.*), Webhooks 2.0 endpoints, HMAC-SHA256 signing (`X-Spree-Webhook-Signature`), exponential-backoff retries, and Sidekiq job orchestration. Use when wiring event-driven business logic, building webhook consumers, or replacing ActiveSupport callback chains.
tools
Cross-cutting Spree development patterns — the customization preference hierarchy (Events > Webhooks > Dependencies > Decorators), `Spree::Dependencies` service-object swapping, the `_decorator.rb` + `prepend` + `self.prepended` idiom, idempotent subscribers and webhook receivers, multi-store scoping discipline, prefixed IDs, calculator polymorphism (shipping/promotion/tax share the base), service-object composition with `dry-monads` or simple results, why to avoid `class_eval` reopening and Deface, and Spree-on-Rails idioms (Hotwire/Turbo Stimulus, ActiveStorage, Action Cable, Sidekiq). Use when designing the architecture of a Spree extension or solving cross-cutting concerns.