dist/codex/saleor-commerce/skills/saleor-checkout/SKILL.md
Implement the Saleor checkout flow — checkout creation, line items, shipping/billing addresses, delivery methods, payment, and completion. Use when building checkout experiences.
npx skillsauth add orcaqubits/agentic-commerce-claude-plugins saleor-checkoutInstall 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 checkout flow steps for the end-to-end checkout processsite:docs.saleor.io checkout mutations graphql for checkout creation and update mutationssite:docs.saleor.io transaction payment checkout for the transaction-based payment flowhttps://docs.saleor.io/docs/developer/checkout and review checkout lifecycle and required fieldssite:docs.saleor.io delivery methods shipping checkout for shipping method selectionhttps://docs.saleor.io/docs/developer/payments and review payment initialization and completionThe Saleor checkout follows a sequential flow:
| Step | Mutation | Description |
|------|----------|-------------|
| 1. Create checkout | checkoutCreate | Initialize checkout with channel and lines |
| 2. Add/update lines | checkoutLinesAdd / checkoutLinesUpdate | Manage line items in the cart |
| 3. Set email | checkoutEmailUpdate | Set customer email (for guest checkout) |
| 4. Set shipping address | checkoutShippingAddressUpdate | Required for physical goods |
| 5. Set billing address | checkoutBillingAddressUpdate | Required for payment processing |
| 6. Select delivery method | checkoutDeliveryMethodUpdate | Choose shipping method or warehouse pickup |
| 7. Initialize payment | transactionInitialize | Start payment with payment App |
| 8. Process payment | transactionProcess | Handle additional payment steps (3DS, redirects) |
| 9. Complete checkout | checkoutComplete | Finalize and create the order |
Steps 3-6 can be done in any order, but all must be complete before payment initialization. The checkout validates required fields at each step.
Create a checkout by specifying the channel and initial line items:
| Field | Required | Description |
|-------|----------|-------------|
| channel | Yes | Channel slug (determines currency, country, available products) |
| lines | Yes | Array of {variantId, quantity} objects |
| email | No | Customer email (can be set later) |
| shippingAddress | No | Shipping address (can be set later) |
| billingAddress | No | Billing address (can be set later) |
Fetch live docs for the complete
CheckoutCreateInputschema -- additional fields includelanguageCode,validationRules, andmetadata.
Checkouts are always scoped to a channel:
| Aspect | Channel Impact | |--------|---------------| | Currency | Prices displayed in the channel currency | | Country | Default country and allowed shipping destinations | | Product availability | Only products with channel listings are purchasable | | Shipping methods | Only shipping zones covering the channel's countries | | Payment gateways | Only payment Apps configured for the channel | | Tax calculation | Tax rules based on channel and country |
| Operation | Mutation | Notes |
|-----------|----------|-------|
| Add lines | checkoutLinesAdd | Add new variants to checkout |
| Update lines | checkoutLinesUpdate | Change quantities of existing lines |
| Delete lines | checkoutLinesDelete | Remove lines from checkout |
| Replace all lines | checkoutLinesAdd with forceNewLine: false | Merges with existing lines |
| Field | Description |
|-------|-------------|
| variant | The product variant being purchased |
| quantity | Number of units |
| totalPrice | Calculated total for the line |
| unitPrice | Price per unit (includes discounts) |
| undiscountedTotalPrice | Price before promotions |
| requiresShipping | Whether this line needs physical delivery |
Setting the shipping address triggers recalculation of available delivery methods:
| Field | Required | Description |
|-------|----------|-------------|
| firstName | Yes | Customer first name |
| lastName | Yes | Customer last name |
| streetAddress1 | Yes | Primary street address |
| streetAddress2 | No | Additional address line |
| city | Yes | City name |
| postalCode | Varies | Postal or ZIP code |
| country | Yes | ISO 3166-1 alpha-2 country code |
| countryArea | Varies | State or province |
| phone | No | Phone number |
Required before payment. Can be set independently or copied from shipping address. Uses the same address input schema.
After setting the shipping address, query available delivery methods:
| Method Type | Description | |-------------|-------------| | Shipping method | Standard carrier-based shipping (price or weight based) | | Warehouse pickup | Click-and-collect from a physical warehouse | | Custom shipping App | Dynamic rates from a shipping App via sync webhook |
Use checkoutDeliveryMethodUpdate to set the selected method by its ID.
Fetch live docs for the
deliveryMethodunion type -- it includes bothShippingMethodandWarehousefor pickup.
Saleor uses a transaction-based payment model:
| Step | Mutation | Description |
|------|----------|-------------|
| 1. Initialize | transactionInitialize | Sends request to payment App; returns data or action needed |
| 2. Process (if needed) | transactionProcess | Handle additional steps like 3DS authentication |
| 3. Complete | checkoutComplete | Finalize checkout after successful payment |
| Field | Description |
|-------|-------------|
| id | Checkout ID |
| paymentGateway | Payment App ID and data (gateway-specific) |
| amount | Amount to charge (usually checkout total) |
| idempotencyKey | Unique key to prevent duplicate transactions |
| Field | Description |
|-------|-------------|
| transaction | Created transaction object |
| transactionEvent | Initial event (e.g., CHARGE_REQUESTED) |
| data | Gateway-specific response (e.g., client secret for Stripe) |
After successful payment, call checkoutComplete:
| Outcome | Description |
|---------|-------------|
| Success | Returns order object; checkout is consumed |
| Confirmation needed | Returns confirmationNeeded: true with confirmationData |
| Error | Returns errors array with field and message |
Checkout completion is idempotent -- calling it multiple times with the same checkout ID returns the same order.
Common checkout errors and their causes:
| Error Code | Cause | Resolution |
|------------|-------|------------|
| INSUFFICIENT_STOCK | Variant out of stock | Remove line or reduce quantity |
| INVALID_SHIPPING_METHOD | Selected method unavailable for address | Re-query available methods |
| SHIPPING_ADDRESS_NOT_SET | Missing shipping address | Set address before delivery method |
| BILLING_ADDRESS_NOT_SET | Missing billing address | Set address before payment |
| VOUCHER_NOT_APPLICABLE | Voucher invalid for this checkout | Remove voucher or adjust checkout |
| CHECKOUT_NOT_FULLY_PAID | Payment incomplete | Complete payment before checkout |
| Strategy | Description |
|----------|-------------|
| Query stale checkouts | Use checkouts query filtered by lastChange date |
| Email recovery | Send reminder emails for checkouts with email set |
| Metadata tracking | Use checkout metadata to store abandonment funnel data |
| TTL cleanup | Saleor automatically removes expired checkouts (configurable) |
Fetch live docs for checkout expiration settings and the
checkoutsadmin query filter syntax.
transactionInitialize / transactionProcess for payments (not legacy checkoutPaymentCreate)idempotencyKey on transaction initialization to prevent duplicate chargesconfirmationNeeded responses for payment methods requiring additional authenticationavailableShippingMethods and availablePaymentGateways dynamically after address changesmetadata for analytics and recovery workflowsFetch the Saleor checkout and transaction documentation for exact mutation inputs, error codes, and payment flow 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.