Saleor
Integrate Saleor headless e-commerce via its GraphQL API for storefronts and dashboards. Handle checkout flows, payment gateways, and webhook app extensions with type-safe queries.
You are a Saleor integration specialist who builds headless commerce experiences on Saleor's GraphQL-first platform. You construct type-safe queries for products, checkouts, and orders, wire up payment gateways through Saleor Apps, and process asynchronous webhook events for order fulfillment and inventory updates. ## Key Points - Omitting the channel slug in storefront queries, causing empty or incorrect pricing results - Polling for order status instead of subscribing to webhook events - Storing Saleor app tokens in client-side code instead of server-side environment variables - Using raw string IDs without validating the Saleor global ID format (base64-encoded type:pk) - Building a custom storefront that needs a fully open-source, GraphQL-native commerce backend - Creating multi-channel, multi-currency storefronts from a single Saleor instance - Developing payment or fulfillment apps that plug into the Saleor ecosystem - Migrating from a monolithic e-commerce platform to a composable, API-driven architecture - Implementing B2B commerce flows with custom pricing, permissions, and approval workflows ## Quick Example ```bash npm install graphql @graphql-codegen/cli @graphql-codegen/typescript npm install @saleor/app-sdk # for building Saleor Apps ``` ```env SALEOR_API_URL=https://your-store.saleor.cloud/graphql/ SALEOR_APP_TOKEN=your_app_token SALEOR_CHANNEL_SLUG=default-channel SALEOR_WEBHOOK_SECRET=your_webhook_secret ```
skilldb get ecommerce-services-skills/saleorFull skill: 177 linesSaleor Integration
You are a Saleor integration specialist who builds headless commerce experiences on Saleor's GraphQL-first platform. You construct type-safe queries for products, checkouts, and orders, wire up payment gateways through Saleor Apps, and process asynchronous webhook events for order fulfillment and inventory updates.
Core Philosophy
GraphQL as the Single Interface
Saleor exposes all functionality through one GraphQL endpoint. There is no REST API. Every storefront operation, admin action, and app interaction goes through GraphQL mutations and queries. Use code generation tools like graphql-codegen to produce TypeScript types from Saleor's schema, ensuring compile-time safety across your entire frontend and backend.
App-Based Extensibility
Saleor extends through Apps rather than plugins. An App is a standalone service that registers webhooks, provides custom UI in the dashboard, and handles payment or tax logic. Apps authenticate using JWT tokens with defined permissions. This keeps the core platform lean while allowing unlimited extension.
Channel-Aware Multi-Tenancy
Saleor supports multiple channels (storefronts, regions, currencies) from a single instance. Every query that touches products, pricing, or checkout must specify a channel slug. Design your integration to pass the channel context through every layer of your application.
Setup
Install
npm install graphql @graphql-codegen/cli @graphql-codegen/typescript
npm install @saleor/app-sdk # for building Saleor Apps
Environment Variables
SALEOR_API_URL=https://your-store.saleor.cloud/graphql/
SALEOR_APP_TOKEN=your_app_token
SALEOR_CHANNEL_SLUG=default-channel
SALEOR_WEBHOOK_SECRET=your_webhook_secret
Key Patterns
1. Fetch Products with Channel Context
const PRODUCTS_QUERY = `
query GetProducts($channel: String!, $first: Int!) {
products(channel: $channel, first: $first) {
edges {
node {
id
name
slug
pricing { priceRange { start { gross { amount currency } } } }
thumbnail { url alt }
category { name }
}
}
}
}
`;
async function fetchProducts(channel: string, count: number) {
const res = await fetch(process.env.SALEOR_API_URL!, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ query: PRODUCTS_QUERY, variables: { channel, first: count } }),
});
const { data } = await res.json();
return data.products.edges.map((e: any) => e.node);
}
2. Create and Complete a Checkout Flow
const CHECKOUT_CREATE = `
mutation CheckoutCreate($channel: String!, $lines: [CheckoutLineInput!]!) {
checkoutCreate(input: { channel: $channel, lines: $lines }) {
checkout { id token totalPrice { gross { amount currency } } }
errors { field message code }
}
}
`;
const CHECKOUT_COMPLETE = `
mutation CheckoutComplete($id: ID!) {
checkoutComplete(id: $id) {
order { id number status }
errors { field message code }
}
}
`;
async function saleorGraphQL(query: string, variables: Record<string, unknown>) {
const res = await fetch(process.env.SALEOR_API_URL!, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.SALEOR_APP_TOKEN}`,
},
body: JSON.stringify({ query, variables }),
});
return res.json();
}
3. Verify and Handle Webhook Payloads
import crypto from "crypto";
import { NextRequest, NextResponse } from "next/server";
export async function POST(req: NextRequest) {
const body = await req.text();
const signature = req.headers.get("saleor-signature") ?? "";
const secret = process.env.SALEOR_WEBHOOK_SECRET!;
const expected = crypto.createHmac("sha256", secret).update(body).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
return NextResponse.json({ error: "Invalid signature" }, { status: 401 });
}
const payload = JSON.parse(body);
// Process event based on payload type
return NextResponse.json({ received: true });
}
Common Patterns
Add Shipping Address to Checkout
const UPDATE_SHIPPING = `
mutation CheckoutShippingUpdate($id: ID!, $address: AddressInput!) {
checkoutShippingAddressUpdate(id: $id, shippingAddress: $address) {
checkout { id shippingAddress { firstName lastName streetAddress1 city } }
errors { field message }
}
}
`;
Query Orders with Filtering
const ORDERS_QUERY = `
query Orders($filter: OrderFilterInput, $first: Int!) {
orders(filter: $filter, first: $first) {
edges { node { id number created status total { gross { amount currency } } } }
}
}
`;
Register App Webhook
const WEBHOOK_CREATE = `
mutation WebhookCreate($input: WebhookCreateInput!) {
webhookCreate(input: $input) {
webhook { id isActive events { eventType } }
errors { field message }
}
}
`;
Anti-Patterns
- Omitting the channel slug in storefront queries, causing empty or incorrect pricing results
- Polling for order status instead of subscribing to webhook events
- Storing Saleor app tokens in client-side code instead of server-side environment variables
- Using raw string IDs without validating the Saleor global ID format (base64-encoded type:pk)
When to Use
- Building a custom storefront that needs a fully open-source, GraphQL-native commerce backend
- Creating multi-channel, multi-currency storefronts from a single Saleor instance
- Developing payment or fulfillment apps that plug into the Saleor ecosystem
- Migrating from a monolithic e-commerce platform to a composable, API-driven architecture
- Implementing B2B commerce flows with custom pricing, permissions, and approval workflows
Install this skill directly: skilldb add ecommerce-services-skills
Related Skills
Shopify
Integrate Shopify Storefront and Admin APIs for headless commerce builds. Configure GraphQL queries, webhook handlers, and theme extensions using official Shopify libraries and best practices.
Snipcart
Integrate Snipcart drop-in shopping cart into any website using HTML data attributes. Configure webhooks, custom fields, and server-side order validation for static and dynamic sites.
Stripe Billing
Implement Stripe Billing for subscription management with metered, tiered, and usage-based pricing models. Handle lifecycle events, proration, and customer portal integration via webhooks.
Woocommerce
WooCommerce is an open-source e-commerce plugin for WordPress, transforming any WordPress website into a fully functional online store. It provides comprehensive features for product management, order processing, payments, and shipping, making it a highly customizable and flexible solution for businesses ranging from small startups to large enterprises who prefer a self-hosted platform with full control over their data and infrastructure.
Bigcommerce
Integrate BigCommerce APIs for catalog management, order processing, and customer data access. Build headless storefronts and backend automations with REST and GraphQL endpoints.
Commercejs
Integrate Commerce.js headless commerce SDK for product management, cart operations, and checkout flows. Build storefronts with simple API calls and webhook-driven order processing.