Printful
Integrate Printful print-on-demand API for product syncing, order
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: 205 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
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.