Setup & Installation
Reference page for everything that happens between "I have a Shopify store with B2B enabled" and "Soryk is wired into it." If you just want to install and go, the Getting Started walkthrough is faster. This page is the deep version.
Shopify B2B activation
Soryk works on all paid Shopify plans (since April 2026) with B2B turned on. B2B isn't a separate plan — it's a feature included in Plus that you have to explicitly enable.
- In Shopify admin, go to Settings → Plan and confirm you have any paid plan (Basic, Grow, Advanced, or Plus). Then go to Settings → Customers and ensure B2B is enabled.
- Open Settings → Customers → B2B and click Set up B2B.
- Create at least one B2B catalog (you can use the default storefront catalog as a base) and one price list for your wholesale tier.
- Verify that Customers → Companies appears in the left nav. If it's there, you're good.
Full Shopify documentation: Shopify B2B help center.
If "B2B" doesn't appear in your settings. You're either not on Plus or your store is on a region/version that hasn't rolled out B2B yet. Open a Shopify support ticket — Soryk cannot work around this.
Required Shopify access scopes
Soryk requests these scopes during install. We don't request anything we don't actively use, and the list hasn't expanded since v1.0.
read_products, write_products
read_orders, write_orders
read_draft_orders, write_draft_orders
read_customers, write_customers
read_companies, write_companies
read_inventory
read_locations
read_metaobject_definitions, write_metaobject_definitions
read_metaobjects, write_metaobjects
| Scope group | Why we need it |
|---|---|
| Products / inventory / locations | Catalog browsing in the agent app, traffic-light stock indicators, multi-warehouse threshold overrides. |
| Orders / draft orders | Place orders for customers, save quotes, attach Soryk tags for commission attribution. |
| Customers / companies | Read and create B2B companies + locations, attach contacts. |
| Metaobjects (read + write) | Soryk's storage layer — agents, rules, payments, audit log all live in metaobjects you own. |
Soryk metaobjects
Soryk creates a small set of metaobject definitions on first install via Shopify's token-exchange flow. They're idempotent — installing twice doesn't duplicate. Uninstalling Soryk leaves them in place; your data stays portable.
| Metaobject | Stores |
|---|---|
soryk_agent | Agent profile: email, name, assigned companies, role, territory shape, locale. |
soryk_commission_rule | Commission rules with scope, base, rate, priority. |
soryk_commission_payment | Recorded payouts (which orders, which method, which date). |
soryk_commission_alert | Refund alerts on already-paid commissions. |
soryk_commission_override | Manual attribution corrections. |
soryk_quote | Saved carts as quotes, with public token + expiry. |
soryk_saved_cart | WIP carts saved by an agent for later. |
soryk_pending_company | Companies awaiting merchant approval. |
soryk_pending_loc_change | Location add/edit awaiting approval. |
soryk_pending_discount | Agent discount requests above the auto-approve cap. |
soryk_shop_config | Singleton: all merchant settings. |
soryk_audit_log | Immutable record of admin actions (mirrored to Redis). |
soryk_visit_form / soryk_visit_submission | Custom visit-report templates and submissions. |
Your data, in your store. Every byte Soryk writes lives inside Shopify metaobjects. You can query them directly via the Admin GraphQL API at any time — Soryk has no exclusive access.
Settings reference (all 12)
Stored in the soryk_shop_config metaobject. Edit them from Admin → Settings.
| Setting | Default | Type | What it controls |
|---|---|---|---|
inventoryMode | off | off | quantity | traffic_light | How stock appears in the agent app. Off = nothing, quantity = exact numbers, traffic_light = green/yellow/red dots. |
lowStockThreshold | 10 | number | Global threshold for the yellow "low" indicator. |
outOfStockThreshold | 0 | number | Global threshold for the red "out" indicator. |
inventoryThresholdsByLocation | {} | map | Per-fulfillment-location overrides. Useful for multi-warehouse setups where stock pressure varies. |
catalogFilters | [] | array (max 3) | Up to three filter chips in the agent catalog. Source: vendor / product type / tag / metafield. Metafield options auto-derive. |
requireCompanyApproval | true | bool | If true, new companies (admin or agent-created) go to a pending queue for merchant approval. |
commissionsOnOnlineOrders | false | bool | Include online storefront orders in commission calculations. Off by default — Soryk only counts agent-mediated draft orders. |
territoryEnabled | false | bool | Enable territory filtering. When on, agents only see companies / locations matching their territory. |
agentDiscountMaxPercent | 0 | 0–100 | Maximum % discount an agent can auto-apply. Above this → discount approval queue. |
managerOrderAttribution | team_agent | team_agent | manager_only | When a manager places an order on behalf of a team member: tag with the team member's email or the manager's. |
buyerPortalEnabled | false | bool | Enable the white-label buyer self-service customer app. |
paymentTermLabels | {} | map | Custom labels overriding Shopify's default PaymentTermsTemplate names (e.g. "2/10 Net 30"). |
Environment variables
For the hosted version (default), all of this is configured for you. If you self-host (Pro / Scale), here's what you need.
Required
JWT_SECRET | Signs JWT for agent / buyer / admin sessions. |
SHOPIFY_API_KEY | Shopify Partner app key. |
SHOPIFY_API_SECRET | Shopify Partner app secret. |
SHOPIFY_APP_URL | Public URL where Soryk is reachable. Used for OAuth callbacks and session-token verification. |
Recommended in production
KV_REST_API_URL + KV_REST_API_TOKEN | Upstash Redis. Powers OTP storage, quote tokens, rate limiting, audit log mirror, analytics cache, push subscriptions. Without it, rate-limit degrades open and the audit mirror is disabled. |
RESEND_API_KEY | Transactional email (magic links, OTPs, quote sends). Without the key, email calls return {delivered: false, reason: "no api key"} — flow continues, but nothing reaches your customers. |
ANTHROPIC_API_KEY | Territory AI audit (Claude Opus 4.7). Without the key the audit endpoint returns a 500 with a clear message; territory matching itself still works. |
VAPID_PUBLIC_KEYVAPID_PRIVATE_KEYVAPID_SUBJECT | push notifications notifications. Without these, push send is a no-op and the toggle hides itself in the agent settings. |
GOOGLE_OAUTH_CLIENT_IDGOOGLE_OAUTH_CLIENT_SECRET | Optional Google SSO for agents and buyers. |
Optional
JWT_SECRET_PREVIOUS | Supports the documented zero-downtime JWT rotation procedure. See Security → JWT rotation. |
Self-hosting notes
Soryk is a Next.js 16 app (App Router). Out-of-the-box deploy targets:
- Vercel — recommended. All env vars set in the dashboard. Upstash + Resend integrate via Vercel marketplace one-click.
- Cloudflare Workers / Pages — supported with the Next.js adapter. Upstash plays especially well here.
- Self-hosted Node 20+ — runs anywhere Node runs. You'll need a Redis-compatible store for production (Upstash REST is easiest; standard Redis works with a small adapter swap).
Self-hosting is available on Pro and Scale tiers. Most merchants don't need it — the hosted version on EU infra (Frankfurt) covers GDPR and gives you faster updates with zero ops.