Saleor
Integrate Saleor headless e-commerce via its GraphQL API for storefronts
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: 178 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
Bigcommerce
Integrate BigCommerce APIs for catalog management, order processing,
Commercejs
Integrate Commerce.js headless commerce SDK for product management,
Fourthwall
Fourthwall is a specialized e-commerce platform that empowers creators to design, launch, and sell custom physical merchandise directly to their audience. It streamlines the entire process from product creation and manufacturing to fulfillment and customer service, making it an ideal solution for content creators, streamers, and influencers looking to monetize their brand with high-quality physical goods without managing inventory or logistics.
Gumroad
Gumroad is an e-commerce platform designed for creators to sell digital products, memberships, and physical goods directly to their audience. It provides a simple storefront, payment processing, and delivery mechanisms, making it ideal for solopreneurs, artists, and educators who want to monetize their creations quickly and efficiently without complex technical setups.
Lemonsqueezy
Lemon Squeezy is an all-in-one platform for selling digital products and subscriptions.
Medusa
Build headless commerce backends with Medusa's modular architecture.