npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

medusa-plugin-printify

v0.3.1

Published

Printify print-on-demand integration plugin for Medusa v2

Readme


Why this plugin

  • Real fulfillment, not just sync. Automatic order submission, real-time webhook status, and a Medusa Admin widget that surfaces production state on every order page.
  • Type-safe, tested, CI-driven. TypeScript strict mode, Jest coverage, and OIDC-signed npm releases driven by conventional-commit PR titles.
  • Decoupled and unopinionated. No storefront assumptions; works with any Medusa v2 host application.

Features

  • Product sync — pull your Printify catalog into Medusa on a schedule or on-demand.
  • Order fulfillment — automatically submit Medusa orders to Printify when they are placed.
  • Webhook handling — real-time status updates (shipped, in-production, delivered, etc.).
  • Admin UI — manage shops, browse synced products, and monitor order status from the Medusa Admin.
  • Webhook auto-registration — registers all required Printify webhook topics on startup.

Screenshots

| Printify dashboard | Synced products | |---|---| | Printify dashboard | Products

| Order widget | Order details | |---|---| | Order widget | Order details |

Quick start

pnpm add medusa-plugin-printify

Add to medusa-config.ts:

import { defineConfig } from "@medusajs/framework/utils"

export default defineConfig({
  plugins: [
    {
      resolve: "medusa-plugin-printify",
      options: {
        apiKey: process.env.PRINTIFY_API_KEY,
        webhookSecret: process.env.PRINTIFY_WEBHOOK_SECRET,
        shopId: process.env.PRINTIFY_SHOP_ID,
        webhookBaseUrl: process.env.PRINTIFY_WEBHOOK_URL,
      },
    },
  ],
})

Run migrations:

pnpm medusa db:migrate

Done. See Configuration for all options.


Table of contents


Requirements


Installation

In your Medusa application directory:

pnpm add medusa-plugin-printify

Configuration

1. Add environment variables

cp .env.template .env

Add the following to your Medusa application's .env:

PRINTIFY_API_KEY=your_printify_personal_access_token
PRINTIFY_WEBHOOK_SECRET=your_webhook_secret
PRINTIFY_SHOP_ID=your_printify_shop_id        # optional, but required for order submission
PRINTIFY_WEBHOOK_URL=https://your-domain.com  # base URL for webhook registration (no trailing slash)

To find your API key: go to printify.com/app/account/api and generate a personal access token.

To find your shop ID: call GET https://api.printify.com/v1/shops.json with your API key.

The webhook secret is a string you choose — Printify will use it to sign webhook payloads so you can verify they are genuine.

2. Register the plugin in medusa-config.ts

import { defineConfig } from "@medusajs/framework/utils"

export default defineConfig({
  // ... other config
  plugins: [
    {
      resolve: "medusa-plugin-printify",
      options: {
        apiKey: process.env.PRINTIFY_API_KEY,
        webhookSecret: process.env.PRINTIFY_WEBHOOK_SECRET,
        shopId: process.env.PRINTIFY_SHOP_ID,
        webhookBaseUrl: process.env.PRINTIFY_WEBHOOK_URL,
      },
    },
  ],
})

All available options:

| Option | Type | Required | Description | |---|---|---|---| | apiKey | string | Yes | Printify personal access token | | webhookSecret | string | Yes | Secret used to verify webhook signatures | | shopId | string | No | Printify shop ID — required for order submission and webhook registration | | webhookBaseUrl | string | No | Base URL of your Medusa server (e.g. https://api.mystore.com) — required for webhook registration | | enableNotifications | boolean | No | Emit Medusa notification events for Printify order status changes | | notificationEmail | string | No | Email address to receive Printify fulfillment notifications |

3. Run database migrations

In your Medusa application directory:

pnpm medusa db:migrate

This creates the printify_shop, printify_product, and printify_order tables.


Local Development

Prerequisites

  • Docker (for the local PostgreSQL instance)
  • pnpm

Plugin setup

Clone this repository and install dependencies:

git clone https://github.com/greedychipmunk/medusa-plugin-printify
cd medusa-plugin-printify
pnpm install

Copy the environment template and fill in your values:

cp .env.template .env

Start the local PostgreSQL instance:

docker compose up -d

Generate the plugin's database migrations:

pnpm medusa plugin:db:generate

Publish the plugin to the local Yalc registry so your Medusa application can install it:

pnpm medusa plugin:publish

Link to a local Medusa application

In your Medusa application directory, install the locally published plugin:

pnpm medusa plugin:add medusa-plugin-printify

Run migrations in the Medusa application:

pnpm medusa db:migrate

Watch for changes

In the plugin directory, start the dev watcher — changes are automatically pushed to the local Yalc registry and picked up by your Medusa application:

pnpm dev

Run tests

pnpm test              # all tests
pnpm test -- --watch   # watch mode

Production Deployment

1. Build the plugin

pnpm build

2. Publish to npm

Releases are handled automatically by .github/workflows/release.yml when a PR with a conventional-commit title (feat:, fix:, or feat!:) is merged to main. There is no manual npm publish step.

3. Install in your Medusa application

pnpm add medusa-plugin-printify

4. Set environment variables on your server

Ensure the following are set in your production environment:

PRINTIFY_API_KEY=...
PRINTIFY_WEBHOOK_SECRET=...
PRINTIFY_SHOP_ID=...
PRINTIFY_WEBHOOK_URL=https://api.your-production-domain.com

5. Run migrations

pnpm medusa db:migrate

6. Configure your reverse proxy

The plugin exposes a webhook endpoint at POST /webhooks/printify. Ensure this path is reachable from the public internet so Printify can deliver webhook events. No authentication is needed on this route — the plugin verifies the x-pfy-signature HMAC header internally.

On startup, the plugin automatically registers all required webhook topics with Printify using the webhookBaseUrl you configured.


API Reference

All admin routes require authentication. Storefront routes are public.

Admin routes

| Method | Path | Description | |---|---|---| | GET | /admin/printify/shops | List all synced Printify shops | | POST | /admin/printify/shops | Trigger a shop sync from Printify | | GET | /admin/printify/products | List synced products (supports ?shop_id= filter) | | POST | /admin/printify/products | Trigger a product sync from Printify | | GET | /admin/printify/orders | List Printify orders (supports ?status= and ?medusa_order_id= filters) | | POST | /admin/printify/orders/:id/submit | Manually submit a Printify order to production |

Webhook endpoint

| Method | Path | Description | |---|---|---| | POST | /webhooks/printify | Receives Printify webhook events |

Handled events: order:status-changed, order:shipped, order:sent-to-production, order:shipment:delivered, product:updated, product:deleted, shop:disconnected


Order Fulfillment Flow

  1. A customer places an order in your Medusa storefront.
  2. The order.placed subscriber detects any line items with metadata.printify_product_id.
  3. A Printify order is created and submitted to production automatically.
  4. Printify sends webhook events as the order moves through production and shipping.
  5. The plugin updates the local Printify order record and emits Medusa events for each status change.
  6. The Printify order widget on the Medusa Admin order detail page reflects the current status.

Admin Dashboard

The plugin adds two pages and one widget to the Medusa Admin:

  • Printify (sidebar) — lists synced shops with a one-click sync button.
  • Printify › Products — browse all synced products with search and a sync button.
  • Order detail widget — appears below the order details on any order page, showing the linked Printify order status and a manual submit button for pending orders.

Contributing

PRs welcome. See CONTRIBUTING.md for setup. PR titles must follow Conventional Commits — the release workflow uses them to bump versions automatically.

Security

See SECURITY.md for how to report vulnerabilities.

License

Licensed under the MIT License.