dist/codex/saleor-commerce/skills/saleor-promotions/SKILL.md
Configure Saleor promotions — catalog promotions, order promotions, vouchers, manual discounts, gift cards, and discount stacking. Use when setting up pricing rules.
npx skillsauth add orcaqubits/agentic-commerce-claude-plugins saleor-promotionsInstall 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:
site:docs.saleor.io promotions catalog order rules for promotion types and rule configurationsite:docs.saleor.io vouchers voucher codes for voucher creation and usage patternssite:docs.saleor.io gift cards for gift card creation, activation, and redemptionhttps://docs.saleor.io/docs/developer/discounts and review the promotion model, rules, and conditionssite:docs.saleor.io manual discount order staff for staff-applied manual discountshttps://docs.saleor.io/docs/developer/gift-cards and review gift card as product and as payment methodSaleor distinguishes between two promotion types that apply at different stages:
| Type | When Applied | Effect | |------|-------------|--------| | Catalog promotion | At product display time | Reduces the visible price on product listings and detail pages | | Order promotion | At checkout time | Applies discount to the order total or specific lines during checkout |
| Aspect | Description |
|--------|-------------|
| Timing | Applied before the product reaches the cart |
| Visibility | Customers see the discounted price on product pages |
| Price display | undiscountedPrice and pricing.discount show the original and savings |
| Stacking | Multiple catalog promotions can apply to the same product |
| Aspect | Description | |--------|-------------| | Timing | Applied when conditions are met in the checkout | | Visibility | Discount shown as a line discount or order-level discount | | Conditions | Based on cart contents, order total, or specific products | | Application | Automatic when conditions match -- no code required |
Each promotion contains one or more rules:
| Field | Description |
|-------|-------------|
| name | Rule display name |
| channels | Channels where this rule applies |
| cataloguePredicate | Conditions based on product, category, collection, or variant |
| orderPredicate | Conditions based on order total or checkout lines |
| rewardValue | Discount amount (fixed or percentage) |
| rewardValueType | FIXED or PERCENTAGE |
| rewardType | For order promotions: SUBTOTAL_DISCOUNT or GIFT |
Catalogue predicate conditions: productPredicate, categoryPredicate, collectionPredicate, variantPredicate. Order predicate conditions: discountedObjectPredicate (minimum subtotal), totalPrice (order total threshold).
| Operation | Mutation | Notes |
|-----------|----------|-------|
| Create promotion | promotionCreate | Set name, type, start/end dates, rules |
| Update promotion | promotionUpdate | Modify promotion settings |
| Delete promotion | promotionDelete | Remove promotion |
| Create rule | promotionRuleCreate | Add rule to existing promotion |
| Update rule | promotionRuleUpdate | Modify rule conditions and rewards |
| Delete rule | promotionRuleDelete | Remove rule from promotion |
| Field | Description |
|-------|-------------|
| name | Promotion display name |
| type | CATALOGUE or ORDER |
| startDate | When the promotion becomes active |
| endDate | When the promotion expires (optional) |
| rules | Array of promotion rules |
| metadata | Custom key-value metadata |
Vouchers are code-based discounts that customers enter at checkout:
| Type | Description |
|------|-------------|
| ENTIRE_ORDER | Discount applied to the entire order |
| SHIPPING | Free or discounted shipping |
| SPECIFIC_PRODUCT | Discount on specific products only |
| Field | Description |
|-------|-------------|
| code | The voucher code customers enter |
| type | Voucher type (see above) |
| discountValueType | FIXED or PERCENTAGE |
| discountValue | Discount amount or percentage |
| minCheckoutItemsQuantity | Minimum items required in checkout |
| minSpent | Minimum order amount (per channel) |
| usageLimit | Total number of times the voucher can be used |
| applyOncePerCustomer | Whether each customer can use it only once |
| applyOncePerOrder | Whether the discount applies to one item or all matching items |
| onlyForStaff | Restrict to staff-created orders |
| startDate | Activation date |
| endDate | Expiration date |
| Operation | Mutation |
|-----------|----------|
| Create voucher | voucherCreate |
| Update voucher | voucherUpdate |
| Delete voucher | voucherDelete |
| Add products | voucherCataloguesAdd |
| Remove products | voucherCataloguesRemove |
Staff users can apply manual discounts to orders:
| Operation | Mutation | Scope |
|-----------|----------|-------|
| Add order discount | orderDiscountAdd | Entire order |
| Update order discount | orderDiscountUpdate | Modify existing discount |
| Delete order discount | orderDiscountDelete | Remove discount |
| Add line discount | orderLineDiscountAdd (draft orders) | Specific line item |
Manual discounts are only available for draft orders and through staff-facing operations. They cannot be combined with automatic promotions on the same order line.
Gift cards function both as a product type and as a payment method:
| Aspect | Description |
|--------|-------------|
| Product type | Create a product type with isDigital: true for gift cards |
| Variants | Each variant represents a gift card denomination |
| Purchase | Customer buys a gift card like any other product |
| Activation | Gift card is automatically created and code sent to buyer |
| Aspect | Description | |--------|-------------| | Application | Customer enters gift card code at checkout | | Balance | Gift card has a remaining balance that decreases with each use | | Partial use | Gift card can be used for partial payment; remainder stays as balance | | Multiple cards | Multiple gift cards can be applied to one checkout |
| Operation | Mutation | Notes |
|-----------|----------|-------|
| Create gift card | giftCardCreate | Staff-created gift card |
| Update gift card | giftCardUpdate | Modify balance, expiry |
| Deactivate | giftCardDeactivate | Disable without deleting |
| Activate | giftCardActivate | Re-enable a deactivated card |
| Resend code | giftCardResend | Resend gift card code via email |
| Bulk create | giftCardBulkCreate | Generate multiple cards at once |
| Add note | giftCardAddNote | Add staff note to gift card |
| Scenario | Behavior | |----------|----------| | Multiple catalog promotions | All matching promotions apply; discounts stack | | Catalog promotion + voucher | Both apply; catalog discount reduces base price, voucher applies on top | | Catalog promotion + order promotion | Both can apply; catalog reduces price, order promotion discounts checkout | | Multiple vouchers | Only one voucher code per checkout | | Voucher + manual discount | Voucher applies first; manual discount applies on remaining amount | | Gift card + other discounts | Gift card applies after all other discounts as a payment method |
startDate and endDate on promotions to automate sale periodsusageLimit and applyOncePerCustomer on vouchers to control distributionFetch the Saleor promotions and voucher documentation for exact mutation inputs, predicate syntax, and discount stacking behavior 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.