Faire Store Sync
Two-way Faire sync for products, inventory, and orders
@jytextiles/medusa-plugin-faire-store-sync
A Medusa v2 plugin that bidirectionally syncs your Medusa products, inventory and orders with a Faire brand account via the Faire External Platform API v2 (OAuth 2.0). It handles the OAuth connect flow, product push (create/update + inventory), bulk product sync, and scheduled order ingestion. Faire is polling-based — it exposes no inbound webhooks — so orders are pulled on a schedule using a cursor.
Features
- OAuth 2.0 redirect connect flow — connect/disconnect a Faire brand from Settings → Faire in the Admin; tokens are stored and auto-refreshed when applicable.
- Product → Faire sync — create/update Faire products, push variant inventory, upload images via URL (single or bulk).
- Bulk products page — a searchable/selectable table of your catalog (Settings → Faire → Bulk) to push many products to Faire in one job.
- Faire → Medusa order ingestion — pull Faire orders and create matching Medusa orders (idempotent, payment marked captured).
- Scheduled order polling — Faire has no webhooks, so orders are pulled on a schedule (every 5 minutes by default) using a cursor-based high-water mark (Copy to clipboard
last_order_sync_at), fetching only orders changed since the previous run. - Status-follow subscriber — when a synced product's Medusa status actually changes (e.g. draft → published), the linked Faire product is re-synced automatically. This is an internal Medusa event, hard-guarded to respect Faire's rate limits (only already-linked products, only on real status change).
- Readiness checks — surfaces what's missing (brand, wholesale-pricing strategy, shipping policy) before publishing.
- Sync records — every sync is tracked per product with status and the remote Faire product token.
- Long-running bulk workflows — both bulk product push and bulk order pull run as background workflows (Copy to clipboard
backgroundExecution) with a pollable batch id.
Requirements
- Medusa 2.17.x
- Node.js >= 22
- A Faire app (client id + client secret) from the Faire developer portal, with the OAuth redirect URL registered.
Install
12345npm install @jytextiles/medusa-plugin-faire-store-sync# oryarn add @jytextiles/medusa-plugin-faire-store-sync# orpnpm add @jytextiles/medusa-plugin-faire-store-sync
Configure
Register the plugin in Copy to clipboardmedusa-config.ts:
12345678910111213141516171819module.exports = defineConfig({// ...plugins: [{resolve: "@jytextiles/medusa-plugin-faire-store-sync",options: {clientId: process.env.FAIRE_APP_ID,clientSecret: process.env.FAIRE_APP_SECRET,redirectUri:process.env.FAIRE_REDIRECT_URI ??"http://localhost:9000/app/settings/oauth/faire/callback",// Optional overrides (defaults shown):// apiBase: "https://faire.com/external-api/v2",// authUrl: "https://faire.com/oauth2/authorize",// tokenUrl: "https://www.faire.com/api/external-api-oauth2/token",},},],})
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 clipboardclientId Copy to clipboardFAIRE_APP_ID yes Your Faire app's application id. Copy to clipboardclientSecret Copy to clipboardFAIRE_APP_SECRET yes Your Faire app's application secret. Copy to clipboardredirectUri Copy to clipboardFAIRE_REDIRECT_URI no OAuth callback URL. Must match your Faire app's registered redirect. Copy to clipboardapiBase Copy to clipboardFAIRE_API_BASE no Override the Faire API base URL (e.g. for sandbox). Copy to clipboardauthUrl Copy to clipboardFAIRE_AUTH_URL no Override the OAuth authorize URL. Copy to clipboardtokenUrl Copy to clipboardFAIRE_TOKEN_URL no Override the OAuth token URL.
After installing, run your project's migrations so the plugin's tables are created:
1npx medusa db:migrate
Optional behavior flags
Env var Default Effect Copy to clipboardFAIRE_INGEST_ORDERS Copy to clipboardtrue Set Copy to clipboardfalse to disable creating Medusa orders from Faire. Copy to clipboardFAIRE_DECREMENT_INVENTORY Copy to clipboardfalse Set Copy to clipboardtrue to decrement Medusa stock on Faire order ingest. Copy to clipboardFAIRE_AUTO_INGEST_ORDERS Copy to clipboardtrue Set Copy to clipboardfalse to disable the scheduled order-pull job.
Usage
- In the Admin, go to Settings → Faire and click Connect to authorize your Faire brand.
- Configure sync settings (brand, wholesale markup %, shipping policy).
- From a product page, use the Faire Sync widget to sync a single product, or open the Bulk products page (Settings → Faire → Bulk) to select many products from a searchable table and push them in one background job.
- Pull Faire orders into Medusa with the Start order pull button (orders also pull automatically every 5 minutes).
Admin API routes
Method Route Purpose GET Copy to clipboard/admin/faire/status Connection + readiness status GET/POST Copy to clipboard/admin/faire/settings Read / save sync settings GET Copy to clipboard/admin/faire/auth/authorize Start the OAuth2 flow POST Copy to clipboard/admin/faire/auth/callback OAuth2 callback (called by the SPA) POST Copy to clipboard/admin/faire/auth/disconnect Disconnect the brand POST Copy to clipboard/admin/faire/sync/product/:id Sync a single product POST Copy to clipboard/admin/faire/sync/bulk Sync multiple products (background workflow, 202) GET Copy to clipboard/admin/faire/sync/bulk/:batchId Poll bulk product-sync progress POST Copy to clipboard/admin/faire/ingest/orders Pull Faire orders (background workflow, 202) GET Copy to clipboard/admin/faire/ingest/orders/:batchId Poll bulk order-ingest progress GET Copy to clipboard/admin/faire/syncs List sync records GET/POST Copy to clipboard/admin/faire/syncs/:id Fetch / retry a sync record GET Copy to clipboard/admin/faire/brand The connected Faire brand GET Copy to clipboard/admin/faire/products Products already on Faire
Development
1234567891011# Build the plugin (compiles to .medusa/server, then restructures via postbuild)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

