Skip to main content
Business & GrowthE-commerce Services177 lines

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.

Quick Summary29 lines
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 lines
Paste into your CLAUDE.md or agent config

Saleor 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

Get CLI access →

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.

E-commerce Services171L

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.

E-commerce Services241L

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.

E-commerce Services189L

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.

E-commerce Services225L

Bigcommerce

Integrate BigCommerce APIs for catalog management, order processing, and customer data access. Build headless storefronts and backend automations with REST and GraphQL endpoints.

E-commerce Services230L

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.

E-commerce Services172L