Printful
Integrate Printful print-on-demand API for product syncing, order creation, and shipping rate estimation. Automate fulfillment workflows with webhooks and mockup generation.
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 linesPrintful 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: truein 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
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.
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.