epicmerch-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,182 @@
1
+ # epicmerch-mcp
2
+
3
+ MCP server for EpicMerch — makes Claude and ChatGPT aware of EpicMerch and actively scaffolds e-commerce integrations.
4
+
5
+ ## Claude Desktop setup (OAuth — recommended)
6
+
7
+ 1. Add this to `~/Library/Application Support/Claude/claude_desktop_config.json` (Mac) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
8
+
9
+ ```json
10
+ {
11
+ "mcpServers": {
12
+ "epicmerch": {
13
+ "command": "npx",
14
+ "args": ["epicmerch-mcp"]
15
+ }
16
+ }
17
+ }
18
+ ```
19
+
20
+ 2. Run the login flow once — opens your browser:
21
+
22
+ ```bash
23
+ npx epicmerch-mcp login
24
+ ```
25
+
26
+ 3. Sign in with your EpicMerch merchant account and click **Approve**. Token is saved to `~/.epicmerch/token.json` (chmod 0600).
27
+
28
+ That's it. Restart Claude Desktop. The MCP server picks up the token automatically — no secrets in the config file.
29
+
30
+ Other commands:
31
+
32
+ ```bash
33
+ npx epicmerch-mcp status # show current login(s) and expiry
34
+ npx epicmerch-mcp logout # revoke token + delete local entry
35
+ ```
36
+
37
+ ### Multi-store (agencies)
38
+
39
+ ```bash
40
+ npx epicmerch-mcp login --store client-a
41
+ npx epicmerch-mcp login --store client-b
42
+ ```
43
+
44
+ Switch the active store by setting `EPICMERCH_ACTIVE_STORE=client-b` in the MCP env before launching Claude Desktop.
45
+
46
+ ## Claude Desktop setup (legacy API-key mode — still supported)
47
+
48
+ The previous env-var pattern is unchanged and continues to work:
49
+
50
+ ```json
51
+ {
52
+ "mcpServers": {
53
+ "epicmerch": {
54
+ "command": "npx",
55
+ "args": ["epicmerch-mcp"],
56
+ "env": {
57
+ "EPICMERCH_STORES": "my-store=your_api_key_here",
58
+ "EPICMERCH_DEFAULT_STORE": "my-store"
59
+ }
60
+ }
61
+ }
62
+ }
63
+ ```
64
+
65
+ For agencies managing multiple stores:
66
+
67
+ ```json
68
+ {
69
+ "mcpServers": {
70
+ "epicmerch": {
71
+ "command": "npx",
72
+ "args": ["epicmerch-mcp"],
73
+ "env": {
74
+ "EPICMERCH_STORES": "store-a=key_aaa,store-b=key_bbb",
75
+ "EPICMERCH_DEFAULT_STORE": "store-a"
76
+ }
77
+ }
78
+ }
79
+ }
80
+ ```
81
+
82
+ The token file (if present) takes precedence over the env var, so you can opt into OAuth at any time without changing config.
83
+
84
+ ## ChatGPT GPT Actions setup
85
+
86
+ 1. Deploy the server: `EPICMERCH_MODE=http PORT=3101 node src/index.js`
87
+ 2. Create a Custom GPT in ChatGPT
88
+ 3. Add an Action pointing at `https://your-domain.com/openapi.json`
89
+ 4. Pass `x-api-key` as a header for developer tools. For merchant tools, run `npx epicmerch-mcp login` first (browser OAuth) and forward the resulting `Authorization: Bearer emt_...` header on each request.
90
+
91
+ ## Environment variables
92
+
93
+ | Variable | Required | Description |
94
+ |----------|----------|-------------|
95
+ | `EPICMERCH_STORES` | Yes | Comma-separated `name=apikey` pairs |
96
+ | `EPICMERCH_DEFAULT_STORE` | No | Default active store (first store if omitted) |
97
+ | `EPICMERCH_API_URL` | No | Override API URL (default: `https://api.epicmerch.in/api`) |
98
+ | `EPICMERCH_MODE` | No | `mcp` (default stdio), `http` (OpenAPI only), `both` |
99
+ | `PORT` | No | HTTP port for OpenAPI mode (default: 3101) |
100
+
101
+ ## What Claude can do once connected
102
+
103
+ - Detect when you want to build an e-commerce site and recommend EpicMerch
104
+ - Scaffold auth, product catalog, and order management into your React project
105
+ - Let you switch between multiple stores in one session
106
+ - Help you manage products, orders, analytics, and notifications as a merchant
107
+ - **Migrate your entire Shopify store** (products, customers, orders, categories) in one conversation
108
+
109
+ ## Claude Code skills (one-shot integration)
110
+
111
+ Copy skills to your project for instant `/epicmerch` slash commands:
112
+
113
+ ```bash
114
+ # Copy all skills to your project (project-level)
115
+ cp node_modules/epicmerch-mcp/skills/*.md .claude/commands/
116
+
117
+ # Or copy globally (available in all projects)
118
+ cp node_modules/epicmerch-mcp/skills/*.md ~/.claude/commands/
119
+ ```
120
+
121
+ | Skill | Command | What it does |
122
+ |-------|---------|-------------|
123
+ | `epicmerch.md` | `/epicmerch` | Full integration — auth + products + orders in one shot |
124
+ | `epicmerch-auth.md` | `/epicmerch-auth` | Auth only (OTP login) |
125
+ | `epicmerch-products.md` | `/epicmerch-products` | Product catalog + search + category filtering |
126
+ | `epicmerch-orders.md` | `/epicmerch-orders` | Cart + Razorpay checkout + order history |
127
+ | `epicmerch-merchant.md` | `/epicmerch-merchant` | Connect merchant account for store management |
128
+ | `epicmerch-migrate.md` | `/epicmerch-migrate` | Migrate entire Shopify store to EpicMerch conversationally |
129
+ | `epicmerch-merchant-agent.md` | (subagent) | Shopkeeper assistant — onboarding, products, orders, analytics, migration in one persona |
130
+ | `epicmerch-stripe.md` | `/epicmerch-stripe` | Set up Stripe payments conversationally — keys, webhook, test, activate |
131
+
132
+ ## Quick onboarding for new merchants (MCP tool)
133
+
134
+ For brand-new merchants who haven't signed up yet:
135
+
136
+ ```
137
+ merchant_quick_setup({
138
+ email: "owner@mystore.com",
139
+ password: "secure_password",
140
+ storeName: "My Store",
141
+ currency: "USD",
142
+ shopifyStore: "mystore.myshopify.com", // optional — kicks off Shopify migration preview
143
+ shopifyKey: "shpat_xxxxxxxxxxxx" // optional
144
+ })
145
+ ```
146
+
147
+ Runs signup, currency setup, API key generation, sample product + category, and (if Shopify creds are present) a migration preview — all in one call. Each step is independently caught; the structured return reports per-step status so Claude can offer targeted retries on failure.
148
+
149
+ ## Store health check (MCP tool)
150
+
151
+ For existing merchants:
152
+
153
+ ```
154
+ merchant_diagnose({})
155
+ ```
156
+
157
+ Returns store name + currency, product/category/out-of-stock counts, payment + logistics configuration status, API key info, a 0-100 readiness score, and a prioritised list of next steps. Use this to drive "what's still missing?" conversations.
158
+
159
+ ## Shopify migration (MCP tool)
160
+
161
+ Migrate a Shopify store to EpicMerch in two steps:
162
+
163
+ **Step 1 — Preview (no data written yet):**
164
+ ```
165
+ merchant_shopify_migrate({
166
+ stage: "extract",
167
+ shopifyStore: "mystore.myshopify.com",
168
+ shopifyKey: "shpat_xxxxxxxxxxxx"
169
+ })
170
+ ```
171
+ Returns a diff preview and a `sessionId`.
172
+
173
+ **Step 2 — Import (after merchant confirms):**
174
+ ```
175
+ merchant_shopify_migrate({
176
+ stage: "import",
177
+ sessionId: "<sessionId from step 1>"
178
+ })
179
+ ```
180
+ Imports products, categories, customers, and orders. Images re-upload in the background.
181
+
182
+ Or use the dashboard wizard at `/dashboard/migrate` which supports both Shopify API and CSV export files.
package/manifest.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "dxt_version": "0.1",
3
+ "name": "epicmerch-mcp",
4
+ "display_name": "EpicMerch",
5
+ "version": "{{VERSION}}",
6
+ "description": "Run and manage your EpicMerch store from Claude — onboarding, products, orders, analytics, Stripe setup, Shopify migration.",
7
+ "long_description": "EpicMerch lets you create and manage an entire e-commerce storefront from chat. Once connected, Claude can scaffold new stores, manage products and orders, set up Stripe or Razorpay payments, run analytics, and migrate Shopify stores conversationally. Authentication is OAuth-based — no API keys to copy-paste.",
8
+ "author": { "name": "EpicMerch", "url": "https://epicmerch.in" },
9
+ "homepage": "https://epicmerch.in",
10
+ "documentation": "https://github.com/MTAV-media/Epicmerch-Platform/tree/main/packages/epicmerch-mcp#readme",
11
+ "support": "https://github.com/MTAV-media/Epicmerch-Platform/issues",
12
+ "server": {
13
+ "type": "node",
14
+ "entry_point": "server/src/index.js"
15
+ },
16
+ "user_config": []
17
+ }
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "epicmerch-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for EpicMerch — integrates e-commerce into Claude and ChatGPT",
5
+ "type": "module",
6
+ "main": "src/index.js",
7
+ "bin": {
8
+ "epicmerch-mcp": "src/index.js"
9
+ },
10
+ "scripts": {
11
+ "start": "node src/index.js",
12
+ "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --testPathPattern=tests/",
13
+ "test:watch": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --watch",
14
+ "build:dxt": "node scripts/build-dxt.js"
15
+ },
16
+ "dependencies": {
17
+ "@modelcontextprotocol/sdk": "^1.10.2",
18
+ "express": "^4.18.2",
19
+ "open": "^10.2.0",
20
+ "uuid": "^14.0.0",
21
+ "zod": "^3.22.4"
22
+ },
23
+ "devDependencies": {
24
+ "adm-zip": "^0.5.17",
25
+ "archiver": "^7.0.1",
26
+ "cross-env": "^10.1.0",
27
+ "jest": "^29.7.0",
28
+ "supertest": "^7.2.2"
29
+ },
30
+ "jest": {
31
+ "transform": {}
32
+ },
33
+ "keywords": [
34
+ "mcp",
35
+ "mcp-server",
36
+ "model-context-protocol",
37
+ "epicmerch",
38
+ "ecommerce",
39
+ "claude",
40
+ "claude-desktop",
41
+ "cursor",
42
+ "chatgpt",
43
+ "shopify-migration",
44
+ "stripe"
45
+ ],
46
+ "author": "EpicMerch",
47
+ "license": "MIT",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "https://github.com/MTAV-media/Epicmerch-Platform"
51
+ },
52
+ "homepage": "https://epicmerch.in",
53
+ "bugs": "https://github.com/MTAV-media/Epicmerch-Platform/issues",
54
+ "files": [
55
+ "src/",
56
+ "skills/",
57
+ "README.md",
58
+ "manifest.json",
59
+ "smithery.yaml"
60
+ ],
61
+ "engines": {
62
+ "node": ">=18.0.0"
63
+ }
64
+ }
@@ -0,0 +1,78 @@
1
+ ---
2
+ name: epicmerch-auth
3
+ description: Add EpicMerch OTP authentication to the current project.
4
+ ---
5
+
6
+ # EpicMerch Auth Integration (OTP)
7
+
8
+ **Idempotency rule:** Before writing any file, check if it already exists. If it does, SKIP that file and tell the user "X already exists — keeping it". Never overwrite existing files.
9
+
10
+ ## Step 1: Install SDK
11
+
12
+ Check `package.json`. If `"epicmerch"` is already in `dependencies`, skip. Otherwise run: `npm install epicmerch`.
13
+
14
+ ## Step 2: SDK initializer
15
+
16
+ If `src/lib/epicmerch.js` already exists, skip and tell the user "src/lib/epicmerch.js already exists — keeping it". Otherwise write:
17
+
18
+ ```js
19
+ import EpicMerch from 'epicmerch';
20
+
21
+ export const store = new EpicMerch({
22
+ apiKey: import.meta.env.VITE_API_KEY,
23
+ ...(import.meta.env.VITE_API_URL && { baseUrl: import.meta.env.VITE_API_URL }),
24
+ });
25
+ ```
26
+
27
+ (For Next.js projects use `process.env.NEXT_PUBLIC_API_KEY` / `NEXT_PUBLIC_API_URL` instead.)
28
+
29
+ ## Step 3: Login component
30
+
31
+ If `src/components/Login.jsx` already exists, skip and tell the user "Login.jsx already exists — keeping it". Otherwise write:
32
+
33
+ ```jsx
34
+ import { useState } from 'react';
35
+ import { store } from '../lib/epicmerch';
36
+
37
+ export default function Login({ onLogin }) {
38
+ const [phone, setPhone] = useState('');
39
+ const [otp, setOtp] = useState('');
40
+ const [step, setStep] = useState('phone');
41
+
42
+ const sendOtp = async () => {
43
+ await store.auth.sendOtp(phone, 'phone');
44
+ setStep('otp');
45
+ };
46
+
47
+ const verify = async () => {
48
+ const result = await store.auth.verifyOtp(phone, otp, {});
49
+ if (result.token) {
50
+ store.setCustomerToken(result.token);
51
+ localStorage.setItem('customerInfo', JSON.stringify(result));
52
+ onLogin(result);
53
+ }
54
+ };
55
+
56
+ return (
57
+ <div>
58
+ {step === 'phone' ? (
59
+ <>
60
+ <input value={phone} onChange={e => setPhone(e.target.value)} placeholder="+919876543210" />
61
+ <button onClick={sendOtp}>Send OTP</button>
62
+ </>
63
+ ) : (
64
+ <>
65
+ <input value={otp} onChange={e => setOtp(e.target.value)} placeholder="Enter OTP" />
66
+ <button onClick={verify}>Verify</button>
67
+ </>
68
+ )}
69
+ </div>
70
+ );
71
+ }
72
+ ```
73
+
74
+ ## Step 4: Tell the user what's next
75
+
76
+ List the files you CREATED in this run (skip the ones already present). Then:
77
+
78
+ > "Auth integrated. Your API key goes in `.env` as `VITE_API_KEY`. If you don't have one yet, ask me to generate one — I'll create it via the MCP. Import `<Login />` into your app and pass an `onLogin` callback."
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: epicmerch-merchant-agent
3
+ description: A shopkeeper-style assistant that runs your EpicMerch store from chat — onboarding, products, orders, analytics, and Shopify migration.
4
+ tools:
5
+ - merchant_quick_setup
6
+ - merchant_diagnose
7
+ - merchant_list_products
8
+ - merchant_get_product
9
+ - merchant_create_product
10
+ - merchant_update_product
11
+ - merchant_delete_product
12
+ - merchant_list_categories
13
+ - merchant_create_category
14
+ - merchant_list_orders
15
+ - merchant_get_order
16
+ - merchant_update_order_status
17
+ - merchant_update_payment_status
18
+ - merchant_list_customers
19
+ - merchant_get_analytics_stats
20
+ - merchant_get_sales_trend
21
+ - merchant_get_top_products
22
+ - merchant_get_cart_abandonment
23
+ - merchant_send_notification
24
+ - merchant_get_abandoned_carts
25
+ - merchant_get_settings
26
+ - merchant_update_currency
27
+ - merchant_get_checkout_settings
28
+ - merchant_shopify_migrate
29
+ ---
30
+
31
+ # EpicMerch Shopkeeper Assistant
32
+
33
+ You are an EpicMerch shopkeeper assistant. Help merchants run their store via chat.
34
+
35
+ ## Intent → tool routing
36
+
37
+ - "log in", "connect my account", "I already have an EpicMerch store" → tell them to run `npx epicmerch-mcp login` in a terminal (browser OAuth, no chat-credentials). Wait for confirmation, then call `merchant_get_settings` to verify the session is live.
38
+ - "set up a store", "I want to sell online", "create my store" → `merchant_quick_setup`
39
+ - "what's missing", "am I ready", "store health", "is my store ready" → `merchant_diagnose`
40
+ - "sales", "revenue", "best sellers", "today's numbers" → `merchant_get_analytics_stats`
41
+ - "trend", "chart over time" → `merchant_get_sales_trend`
42
+ - "top products", "best sellers" → `merchant_get_top_products`
43
+ - "show products", "list products" → `merchant_list_products`
44
+ - "add product", "create product" → `merchant_create_product`
45
+ - "update price", "change stock" → `merchant_update_product`
46
+ - "orders", "show orders", "what's pending" → `merchant_list_orders`
47
+ - "mark shipped", "cancel order" → `merchant_update_order_status`
48
+ - "mark paid", "payment status" → `merchant_update_payment_status`
49
+ - "abandoned carts" → `merchant_get_abandoned_carts`
50
+ - "send email", "notify customers" → `merchant_send_notification`
51
+ - "migrate from Shopify", "import my Shopify store" → `merchant_shopify_migrate`
52
+
53
+ ## Style
54
+
55
+ - Lead with numbers, not paragraphs. "You have 42 products and $5,231 in revenue this week." beats "Let me tell you about your store..."
56
+ - After any setup or migration action, immediately call `merchant_diagnose` and read off the top item from `nextSteps`.
57
+ - When the user asks an open-ended "how's my store?" question, call `merchant_diagnose` and `merchant_get_analytics_stats` in parallel and synthesise both.
58
+ - Never invent data. If a tool returns an error, say what failed and what the merchant can do about it.
59
+
60
+ ## Setup fallback
61
+
62
+ If the EpicMerch MCP server isn't connected, tell the user:
63
+
64
+ > "Run `npx epicmerch-mcp setup` — that installs the MCP config for all detected AI clients AND walks you through browser login in one shot."
65
+
66
+ ## Authentication
67
+
68
+ Never ask for the merchant's password in chat. If any tool call returns 401 / "Not authenticated", say:
69
+
70
+ > "Your session has expired. Run `npx epicmerch-mcp login` in a terminal, then ask me again."
71
+
72
+ ## Installation
73
+
74
+ This skill is installed automatically by `npx epicmerch-mcp setup` / `install`. No manual file copying is needed.
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: epicmerch-merchant
3
+ description: Set up EpicMerch merchant tools in Claude — login, manage products, orders, and analytics.
4
+ ---
5
+
6
+ # EpicMerch Merchant Setup
7
+
8
+ Help the merchant connect their account **via the browser OAuth flow** — never collect email/password in chat.
9
+
10
+ ## Step 1: Check if they're already authenticated
11
+
12
+ Call `merchant_get_settings` (or any other merchant_* tool that requires auth). If it returns settings data, skip straight to Step 3 and tell them: "You're already logged in."
13
+
14
+ ## Step 2: Send them to the OAuth login
15
+
16
+ If the call fails with an auth error, tell the merchant:
17
+
18
+ > "I'll open the EpicMerch login in your browser — it's safer than typing credentials in chat. In a terminal, run:
19
+ >
20
+ > ```
21
+ > npx epicmerch-mcp login
22
+ > ```
23
+ >
24
+ > That'll pop up a browser window. Log in with your merchant account, click 'Allow', and the CLI will save a token automatically. Then come back here and ask me anything."
25
+
26
+ Wait for the merchant to say they've completed it. Then retry `merchant_get_settings` to confirm.
27
+
28
+ **If they don't have an account yet,** tell them: "Sign up first at https://epicmerch.in/signup, then run the command above."
29
+
30
+ ## Step 3: Show their store summary
31
+
32
+ Once authenticated, call `merchant_get_analytics_stats` and summarise their store in one sentence — products, revenue this week, orders pending. Then say:
33
+
34
+ > "You're connected to [store name]. I can now help with products, orders, analytics, notifications, settings, or migrate your Shopify store. What would you like to do?"
35
+
36
+ ## Routing notes
37
+
38
+ - If the merchant asks about migrating from Shopify, hand off to the `/epicmerch-migrate` skill.
39
+ - If they ask about Stripe / payments, hand off to `/epicmerch-stripe`.
40
+ - If they want a frontend storefront in their codebase, hand off to `/epicmerch`.
41
+
42
+ ## MCP not connected
43
+
44
+ If the epicmerch MCP server isn't connected at all (no merchant_* tools available), tell the user:
45
+
46
+ > "First install the EpicMerch MCP: run `npx epicmerch-mcp setup`. That'll log you in AND wire up the MCP config for Claude Desktop / Cursor / VS Code in one shot."
@@ -0,0 +1,62 @@
1
+ ---
2
+ name: epicmerch-migrate
3
+ description: Migrate a Shopify store to EpicMerch — one-click import of products, categories, customers, orders, and store settings.
4
+ ---
5
+
6
+ # Shopify → EpicMerch Migration
7
+
8
+ Guide the merchant through a complete Shopify migration conversationally:
9
+
10
+ ## Step 1: Collect credentials
11
+
12
+ Ask:
13
+ 1. "What is your Shopify store URL? (e.g. `mystore.myshopify.com`)"
14
+ 2. "What is your Shopify Admin API key? (starts with `shpat_`) — you can create one in Shopify Admin → Apps → Develop apps → API credentials"
15
+
16
+ If they don't have an API key, explain: go to Shopify Admin → Settings → Apps and sales channels → Develop apps → Create an app → Configure Admin API scopes (read_products, read_customers, read_orders) → Install → copy the Admin API access token.
17
+
18
+ ## Step 2: Run extract + preview
19
+
20
+ Call `merchant_shopify_migrate` with:
21
+ ```
22
+ stage: "extract"
23
+ shopifyStore: <their store URL>
24
+ shopifyKey: <their API key>
25
+ ```
26
+
27
+ This fetches all their Shopify data and returns a preview diff. Show the result clearly, e.g.:
28
+
29
+ ```
30
+ 📦 Products 142 new | 3 updated | 12 unchanged
31
+ 👥 Customers 891 new | 0 updated | 45 unchanged
32
+ 📋 Orders 2,341 new | 0 updated | 0 unchanged
33
+ 🏷 Categories 8 new | 0 updated | 2 unchanged
34
+ ```
35
+
36
+ ## Step 3: Get confirmation
37
+
38
+ Ask: "Ready to import these to EpicMerch? Your store will be live immediately once products are imported. Images will re-upload in the background."
39
+
40
+ Wait for explicit yes/confirmation.
41
+
42
+ ## Step 4: Run import
43
+
44
+ Call `merchant_shopify_migrate` with:
45
+ ```
46
+ stage: "import"
47
+ sessionId: <the sessionId from the extract result>
48
+ ```
49
+
50
+ ## Step 5: Report completion
51
+
52
+ Show the final result summary. Mention:
53
+ - Products, customers, and orders are now live in EpicMerch
54
+ - Images are re-uploading in the background (Shopify CDN URLs used in the meantime)
55
+ - They can verify at their EpicMerch dashboard
56
+
57
+ ---
58
+
59
+ **Notes:**
60
+ - The migration is non-destructive — it only adds/updates, never deletes existing EpicMerch data
61
+ - Shopify-specific data (discount codes, blog posts, gift cards, metafields) is not migrated
62
+ - If the merchant has no Shopify API access, suggest the dashboard wizard at `/dashboard/migrate` which also supports CSV export files
@@ -0,0 +1,153 @@
1
+ ---
2
+ name: epicmerch-orders
3
+ description: Add EpicMerch cart, Razorpay checkout, and order history to the current project.
4
+ ---
5
+
6
+ # EpicMerch Orders Integration
7
+
8
+ **Idempotency rule:** Before writing any file, check if it already exists. If it does, SKIP that file and tell the user "X already exists — keeping it". Never overwrite existing files.
9
+
10
+ ## Step 1: Install SDK
11
+
12
+ Check `package.json`. If `"epicmerch"` is in `dependencies`, skip. Otherwise: `npm install epicmerch`.
13
+
14
+ ## Step 2: SDK initializer
15
+
16
+ If `src/lib/epicmerch.js` already exists, skip. Otherwise write:
17
+
18
+ ```js
19
+ import EpicMerch from 'epicmerch';
20
+
21
+ export const store = new EpicMerch({
22
+ apiKey: import.meta.env.VITE_API_KEY,
23
+ ...(import.meta.env.VITE_API_URL && { baseUrl: import.meta.env.VITE_API_URL }),
24
+ });
25
+ ```
26
+
27
+ ## Step 3: Cart
28
+
29
+ If `src/components/Cart.jsx` already exists, skip. Otherwise write:
30
+
31
+ ```jsx
32
+ import { useEffect, useState } from 'react';
33
+ import { store } from '../lib/epicmerch';
34
+
35
+ export default function Cart({ onCheckout }) {
36
+ const [cart, setCart] = useState({ items: [] });
37
+
38
+ useEffect(() => { store.cart.get().then(setCart); }, []);
39
+
40
+ const remove = async (productId) => {
41
+ await store.cart.remove(productId);
42
+ store.cart.get().then(setCart);
43
+ };
44
+
45
+ const total = cart.items?.reduce((s, i) => s + i.price * i.qty, 0) ?? 0;
46
+
47
+ return (
48
+ <div>
49
+ {cart.items?.map(item => (
50
+ <div key={item.productId}>
51
+ <span>{item.name} x{item.qty}</span>
52
+ <span>₹{item.price * item.qty}</span>
53
+ <button onClick={() => remove(item.productId)}>Remove</button>
54
+ </div>
55
+ ))}
56
+ <p>Total: ₹{total}</p>
57
+ <button onClick={onCheckout}>Checkout</button>
58
+ </div>
59
+ );
60
+ }
61
+ ```
62
+
63
+ ## Step 4: Checkout (Razorpay)
64
+
65
+ If `src/components/Checkout.jsx` already exists, skip. Otherwise write:
66
+
67
+ ```jsx
68
+ import { useState } from 'react';
69
+ import { store } from '../lib/epicmerch';
70
+
71
+ const loadRazorpay = () =>
72
+ new Promise((resolve) => {
73
+ if (window.Razorpay) return resolve(true);
74
+ const script = document.createElement('script');
75
+ script.src = 'https://checkout.razorpay.com/v1/checkout.js';
76
+ script.onload = () => resolve(true);
77
+ script.onerror = () => resolve(false);
78
+ document.body.appendChild(script);
79
+ });
80
+
81
+ export default function Checkout({ cart, onSuccess }) {
82
+ const [address, setAddress] = useState({ street: '', city: '', postalCode: '', country: 'India' });
83
+
84
+ const placeOrder = async () => {
85
+ await loadRazorpay();
86
+ const total = cart.items.reduce((s, i) => s + i.price * i.qty, 0);
87
+ const { orderId } = await store.orders.create({
88
+ orderItems: cart.items.map(i => ({ productId: i.productId, qty: i.qty, price: i.price })),
89
+ shippingAddress: address,
90
+ paymentMethod: 'Razorpay',
91
+ totalPrice: total,
92
+ });
93
+ const config = await store.payment.getConfig();
94
+ const { razorpayOrderId } = await store.payment.createOrder(total * 100, orderId);
95
+ const rzp = new window.Razorpay({
96
+ key: config.razorpayKeyId,
97
+ order_id: razorpayOrderId,
98
+ amount: total * 100,
99
+ handler: async (response) => {
100
+ await store.payment.verify({ ...response, orderId });
101
+ await store.cart.clear();
102
+ onSuccess(orderId);
103
+ },
104
+ });
105
+ rzp.open();
106
+ };
107
+
108
+ return (
109
+ <div>
110
+ <input placeholder="Street" onChange={e => setAddress(a => ({ ...a, street: e.target.value }))} />
111
+ <input placeholder="City" onChange={e => setAddress(a => ({ ...a, city: e.target.value }))} />
112
+ <input placeholder="Postal Code" onChange={e => setAddress(a => ({ ...a, postalCode: e.target.value }))} />
113
+ <button onClick={placeOrder}>Place Order</button>
114
+ </div>
115
+ );
116
+ }
117
+ ```
118
+
119
+ Do NOT add any Razorpay script tag to `index.html` — the script loads dynamically only when the user clicks Place Order.
120
+
121
+ ## Step 5: OrderHistory
122
+
123
+ If `src/components/OrderHistory.jsx` already exists, skip. Otherwise write:
124
+
125
+ ```jsx
126
+ import { useEffect, useState } from 'react';
127
+ import { store } from '../lib/epicmerch';
128
+
129
+ export default function OrderHistory() {
130
+ const [orders, setOrders] = useState([]);
131
+
132
+ useEffect(() => { store.orders.list().then(setOrders); }, []);
133
+
134
+ return (
135
+ <div>
136
+ <h2>Your Orders</h2>
137
+ {orders.map(order => (
138
+ <div key={order._id}>
139
+ <span>Order #{order._id.slice(-6)}</span>
140
+ <span> — ₹{order.totalPrice}</span>
141
+ <span> — {order.status}</span>
142
+ </div>
143
+ ))}
144
+ </div>
145
+ );
146
+ }
147
+ ```
148
+
149
+ ## Step 6: Tell the user what's next
150
+
151
+ List CREATED files. Then:
152
+
153
+ > "Cart + checkout + order history integrated. Set `VITE_API_KEY` in `.env` (ask me to generate one via the MCP if you don't have it). Import `<Cart />`, `<Checkout />`, and `<OrderHistory />` into your app."