Etsy Product Sync
List and update Etsy products from your Medusa store
@jytextiles/medusa-plugin-etsy-sync
A Medusa v2 plugin that syncs your Medusa products to a personal Etsy shop via the Etsy Open API v3. It handles the OAuth2 (PKCE) connect flow, draft-listing creation, listing updates, image uploads, and keeps a per-product sync record so you can publish to Etsy from the Medusa Admin.
Features
- OAuth2 PKCE connect flow — connect/disconnect an Etsy shop from Settings → Etsy in the Admin; tokens are stored and auto-refreshed.
- Product → Etsy sync — create draft listings, update them, and upload product images (single or bulk).
- Readiness checks — surfaces what's missing (shop connection, shipping profile, return policy, taxonomy) before you publish.
- Sync records — every sync is tracked per product with status and the remote Etsy listing id.
- Scheduled token refresh — a background job keeps the Etsy access token fresh so syncs don't fail mid-session.
Requirements
- Medusa 2.17.x
- Node.js >= 22
- An Etsy app (keystring + shared secret) from the Etsy developer portal
Install
12345npm install @jytextiles/medusa-plugin-etsy-sync# oryarn add @jytextiles/medusa-plugin-etsy-sync# orpnpm add @jytextiles/medusa-plugin-etsy-sync
Configure
Register the plugin in Copy to clipboardmedusa-config.ts:
1234567891011121314151617module.exports = defineConfig({// ...plugins: [{resolve: "@jytextiles/medusa-plugin-etsy-sync",options: {keystring: process.env.ETSY_KEYSTRING,sharedSecret: process.env.ETSY_SHARED_SECRET,redirectUri:process.env.ETSY_REDIRECT_URI ??"http://localhost:9000/app/settings/oauth/etsy/callback",scope:process.env.ETSY_SCOPE ?? "listings_r listings_w listings_d shops_r",},},],})
Options can be supplied via the Copy to clipboardoptions object above or the matching environment variables (env takes precedence):
Option Env var Required Description Copy to clipboardkeystring Copy to clipboardETSY_KEYSTRING yes Your Etsy app's keystring (API key). Copy to clipboardsharedSecret Copy to clipboardETSY_SHARED_SECRET yes Your Etsy app's shared secret. Copy to clipboardredirectUri Copy to clipboardETSY_REDIRECT_URI no OAuth callback URL. Must match your Etsy app's registered callback. Copy to clipboardscope Copy to clipboardETSY_SCOPE no Space-separated Etsy OAuth scopes.
Add the callback URL (Copy to clipboardredirectUri) to your Etsy app's allowed redirect URIs in the Etsy developer portal.
After installing, run your project's migrations so the plugin's tables are created:
1npx medusa db:migrate
Usage
- In the Admin, go to Settings → Etsy and click Connect to authorize your Etsy shop.
- Configure your sync settings (shipping profile, return policy, taxonomy).
- From a product page, use the Etsy widget to sync the product, or sync in bulk from the Etsy settings page.
Admin API routes
Method Route Purpose GET Copy to clipboard/admin/etsy/status Connection + readiness status GET / POST Copy to clipboard/admin/etsy/settings Read / save sync settings GET Copy to clipboard/admin/etsy/auth/authorize Start the OAuth2 PKCE flow GET Copy to clipboard/admin/etsy/auth/callback OAuth2 callback POST Copy to clipboard/admin/etsy/auth/disconnect Disconnect the shop POST Copy to clipboard/admin/etsy/sync/product/:id Sync a single product POST Copy to clipboard/admin/etsy/sync/bulk Sync multiple products GET Copy to clipboard/admin/etsy/syncs List sync records GET Copy to clipboard/admin/etsy/taxonomy Etsy taxonomy lookup GET Copy to clipboard/admin/etsy/shipping-profiles Etsy shipping profiles GET Copy to clipboard/admin/etsy/return-policies Etsy return policies
Development
1234567891011# Build the plugin (compiles to .medusa/server)npm run build# Watch mode while developing against a local Medusa appnpm run dev# Generate a migration after changing a modelnpm run db:generate# Run testsnpm run test
License
MIT

