@jytextiles/medusa-plugin-faire-store-sync
v0.2.14
Published
Medusa v2 plugin to bidirectionally sync Medusa products, inventory and orders with a Faire brand account via the Faire External Platform API (OAuth 2.0).
Downloads
2,087
Maintainers
Readme
@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
(
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 (
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
npm install @jytextiles/medusa-plugin-faire-store-sync
# or
yarn add @jytextiles/medusa-plugin-faire-store-sync
# or
pnpm add @jytextiles/medusa-plugin-faire-store-syncConfigure
Register the plugin in medusa-config.ts:
module.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 options object above or the matching
environment variables (env takes precedence):
| Option | Env var | Required | Description |
| --------------- | --------------------- | -------- | ------------------------------------------------------------------ |
| clientId | FAIRE_APP_ID | yes | Your Faire app's application id. |
| clientSecret | FAIRE_APP_SECRET | yes | Your Faire app's application secret. |
| redirectUri | FAIRE_REDIRECT_URI | no | OAuth callback URL. Must match your Faire app's registered redirect. |
| apiBase | FAIRE_API_BASE | no | Override the Faire API base URL (e.g. for sandbox). |
| authUrl | FAIRE_AUTH_URL | no | Override the OAuth authorize URL. |
| tokenUrl | FAIRE_TOKEN_URL | no | Override the OAuth token URL. |
After installing, run your project's migrations so the plugin's tables are created:
npx medusa db:migrateOptional behavior flags
| Env var | Default | Effect |
| ----------------------------- | ------- | ----------------------------------------------------------- |
| FAIRE_INGEST_ORDERS | true | Set false to disable creating Medusa orders from Faire. |
| FAIRE_DECREMENT_INVENTORY | false | Set true to decrement Medusa stock on Faire order ingest. |
| FAIRE_AUTO_INGEST_ORDERS | true | Set false 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 | /admin/faire/status | Connection + readiness status |
| GET/POST | /admin/faire/settings | Read / save sync settings |
| GET | /admin/faire/auth/authorize | Start the OAuth2 flow |
| POST | /admin/faire/auth/callback | OAuth2 callback (called by the SPA) |
| POST | /admin/faire/auth/disconnect | Disconnect the brand |
| POST | /admin/faire/sync/product/:id | Sync a single product |
| POST | /admin/faire/sync/bulk | Sync multiple products (background workflow, 202) |
| GET | /admin/faire/sync/bulk/:batchId | Poll bulk product-sync progress |
| POST | /admin/faire/ingest/orders | Pull Faire orders (background workflow, 202) |
| GET | /admin/faire/ingest/orders/:batchId | Poll bulk order-ingest progress |
| GET | /admin/faire/syncs | List sync records |
| GET/POST | /admin/faire/syncs/:id | Fetch / retry a sync record |
| GET | /admin/faire/brand | The connected Faire brand |
| GET | /admin/faire/products | Products already on Faire |
Development
# Build the plugin (compiles to .medusa/server, then restructures via postbuild)
npm run build
# Watch mode while developing against a local Medusa app
npm run dev
# Generate a migration after changing a model
npm run db:generate
# Run tests
npm run test