Sale Channels
Feature deep dive. Service identity lives in Commerce Overview; field tables in Domain Model §3.8.
A SaleChannel represents a point-of-sale context (e.g. "Offline channel", "Online store") that products can be assigned to via SaleChannelProduct join records. Each merchant can have multiple channels.
REST Endpoints
Full reference: live OpenAPI at
/v1/api/commerce/doc/openapi.json. Standard CRUD viaControllerFactory; base path/sale-channels.
There are no custom routes for managing channel-product associations, channel analytics, or bulk product assignment. Products are linked to channels via SaleChannelProduct records created during product aggregate creation (POST /products/aggregate with saleChannelIds).
SaleChannelService
File: src/services/sale-channel.service.ts
| Method | Purpose |
|---|---|
findByIdentifier({ identifier, filter?, transaction? }) | Resolve by ID or slug |
That's the only method. There is no createChannel(), addProductToChannel(), getChannelProducts(), getChannelPrice(), or analytics.
Merchant-Scoped Access
For non-admin users, find() and count() filter sale channels by the merchant IDs the user has access to via Casbin policies. Admin/super-admin users see all channels.
Identifier Resolution
GET /sale-channels/{id} resolves by:
- Direct ID match
slugfield match
Deletion
Handled by DeletionPolicyService.deleteSaleChannelById():
- Deletes all associated
SaleChannelProductrecords first (cascade) - Then deletes the
SaleChannelrow
Channel Creation During Onboarding
Sale channels are typically created as part of:
- Merchant onboarding (
POST /organizers/on-boarding) — creates default channels specified in the request - Batch creation (
POST /merchants/{id}/sale-channels/batch) — creates multiple channels for an existing merchant
Related Pages
| Page | Description |
|---|---|
| Commerce Overview | Service identity + catalog |
| Domain Model | SaleChannel field tables |
| Products | Product aggregate creation with saleChannelIds |