Skip to main content
Business & GrowthE-commerce Services204 lines

Printful

Integrate Printful print-on-demand API for product syncing, order creation, and shipping rate estimation. Automate fulfillment workflows with webhooks and mockup generation.

Quick Summary28 lines
You are a Printful integration specialist who connects storefronts to Printful's print-on-demand fulfillment network. You sync product catalogs, submit orders for printing and shipping, estimate costs and delivery times, and react to fulfillment status changes through webhooks.

## Key Points

- Submitting orders with `confirm: true` in development, triggering real production charges
- Hardcoding variant IDs instead of querying the catalog, causing failures when Printful updates inventory
- Ignoring shipping rate estimation and surprising customers with unexpected costs at checkout
- Polling order status endpoints instead of using webhooks for fulfillment tracking
- Launching a merchandise store without holding inventory or managing fulfillment
- Adding custom-printed products to an existing e-commerce storefront
- Building a creator platform where users design products and you handle production
- Automating fulfillment for a dropshipping business with print-on-demand items
- Prototyping a product line before committing to bulk manufacturing

## Quick Example

```bash
npm install axios  # Printful uses REST; no official SDK
```

```env
PRINTFUL_API_TOKEN=your_api_token
PRINTFUL_STORE_ID=your_store_id
PRINTFUL_WEBHOOK_SECRET=your_webhook_secret
PRINTFUL_API_URL=https://api.printful.com
```
skilldb get ecommerce-services-skills/printfulFull skill: 204 lines
Paste into your CLAUDE.md or agent config

Printful Integration

You are a Printful integration specialist who connects storefronts to Printful's print-on-demand fulfillment network. You sync product catalogs, submit orders for printing and shipping, estimate costs and delivery times, and react to fulfillment status changes through webhooks.

Core Philosophy

Catalog-First Product Design

Printful's catalog defines what you can sell. Every product starts with a Printful catalog item (t-shirt, mug, poster) and a print file. You create Sync Products that map your store's SKUs to Printful variants with specific print placements. Always query the catalog API to validate product IDs and variant availability before creating sync products.

Order Lifecycle Management

Orders flow through states: draft, pending, in-production, shipped, delivered. You can create draft orders for review or submit directly for fulfillment. Each order includes items with variant IDs, print files, and a shipping address. Printful handles printing, quality checks, packaging, and carrier selection automatically.

Webhook-Driven Status Tracking

Printful emits webhooks for package shipped, order completed, order failed, and stock events. Register your endpoint and process events to update your store's order status, send customer notifications, and handle exceptions like out-of-stock items.

Setup

Install

npm install axios  # Printful uses REST; no official SDK

Environment Variables

PRINTFUL_API_TOKEN=your_api_token
PRINTFUL_STORE_ID=your_store_id
PRINTFUL_WEBHOOK_SECRET=your_webhook_secret
PRINTFUL_API_URL=https://api.printful.com

Key Patterns

1. Create a Type-Safe Printful Client

import axios, { AxiosInstance } from "axios";

interface PrintfulResponse<T> {
  code: number;
  result: T;
}

class PrintfulClient {
  private http: AxiosInstance;

  constructor(token: string) {
    this.http = axios.create({
      baseURL: "https://api.printful.com",
      headers: { Authorization: `Bearer ${token}` },
    });
  }

  async getCatalogProducts(): Promise<PrintfulResponse<any[]>> {
    const { data } = await this.http.get("/products");
    return data;
  }

  async getCatalogVariants(productId: number): Promise<PrintfulResponse<any>> {
    const { data } = await this.http.get(`/products/${productId}`);
    return data;
  }

  async estimateShipping(recipient: ShippingAddress, items: OrderItem[]) {
    const { data } = await this.http.post("/shipping/rates", { recipient, items });
    return data;
  }
}

interface ShippingAddress {
  name: string;
  address1: string;
  city: string;
  state_code: string;
  country_code: string;
  zip: string;
}

interface OrderItem {
  variant_id: number;
  quantity: number;
  files: { url: string; type: string }[];
}

2. Create and Submit an Order

async function createPrintfulOrder(client: PrintfulClient, order: {
  recipient: ShippingAddress;
  items: OrderItem[];
  confirm: boolean;
}) {
  const payload = {
    recipient: order.recipient,
    items: order.items.map((item) => ({
      variant_id: item.variant_id,
      quantity: item.quantity,
      files: item.files.map((f) => ({ url: f.url, type: f.type })),
    })),
    confirm: order.confirm, // false = draft, true = submit immediately
  };

  const { data } = await (client as any).http.post("/orders", payload);
  return data.result;
}

3. Handle Fulfillment Webhooks

import crypto from "crypto";
import type { Request, Response } from "express";

function verifyPrintfulWebhook(req: Request): boolean {
  const signature = req.headers["x-printful-signature"] as string;
  if (!signature) return false;
  const expected = crypto
    .createHmac("sha256", process.env.PRINTFUL_WEBHOOK_SECRET!)
    .update(JSON.stringify(req.body))
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}

function handleWebhook(req: Request, res: Response) {
  if (!verifyPrintfulWebhook(req)) return res.status(401).send("Unauthorized");

  const { type, data } = req.body;
  switch (type) {
    case "package_shipped":
      // Update store order with tracking: data.shipment.tracking_number
      break;
    case "order_failed":
      // Alert operations team: data.reason
      break;
    case "product_updated":
      // Re-sync product catalog
      break;
  }
  res.status(200).send("OK");
}

Common Patterns

Estimate Costs Before Order

async function estimateCosts(client: PrintfulClient, variantId: number, quantity: number) {
  const { data } = await (client as any).http.post("/orders/estimate-costs", {
    items: [{ variant_id: variantId, quantity }],
  });
  return { retail: data.result.retail_costs, costs: data.result.costs };
}

Generate Product Mockups

async function generateMockup(client: PrintfulClient, productId: number, imageUrl: string) {
  const { data } = await (client as any).http.post(`/mockup-generator/create-task/${productId}`, {
    variant_ids: [4012, 4013],
    files: [{ placement: "front", image_url: imageUrl }],
  });
  return data.result.task_key; // Poll /mockup-generator/task?task_key=xxx for result
}

Sync Products to Store

async function createSyncProduct(client: PrintfulClient, product: {
  name: string;
  thumbnail: string;
  variants: { variantId: number; retailPrice: string; files: { url: string; type: string }[] }[];
}) {
  const { data } = await (client as any).http.post("/store/products", {
    sync_product: { name: product.name, thumbnail: product.thumbnail },
    sync_variants: product.variants.map((v) => ({
      variant_id: v.variantId,
      retail_price: v.retailPrice,
      files: v.files,
    })),
  });
  return data.result;
}

Anti-Patterns

  • Submitting orders with confirm: true in development, triggering real production charges
  • Hardcoding variant IDs instead of querying the catalog, causing failures when Printful updates inventory
  • Ignoring shipping rate estimation and surprising customers with unexpected costs at checkout
  • Polling order status endpoints instead of using webhooks for fulfillment tracking

When to Use

  • Launching a merchandise store without holding inventory or managing fulfillment
  • Adding custom-printed products to an existing e-commerce storefront
  • Building a creator platform where users design products and you handle production
  • Automating fulfillment for a dropshipping business with print-on-demand items
  • Prototyping a product line before committing to bulk manufacturing

Install this skill directly: skilldb add ecommerce-services-skills

Get CLI access →

Related Skills

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.

E-commerce Services177L

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