Service · Multi-Store · Shopify · Unified Ops

Two stores, ten stores —
one ops platform.

Running multiple Shopify storefronts that share a warehouse, an accounting file, or a fulfilment account? The integration layer that holds it all together is almost always a graveyard of per-store scripts, separate logins, and duplicated credentials. One unified platform replaces all of it. The seventh storefront is a 30-minute job.

Storefronts unified
6
Time to add new store
~30m
Per-store SaaS fees
$0
Production automations
6
The shape of the problem

Each store is a silo. Each tool a different dialect.

Most multi-store Shopify operations look the same from the outside. There's one or two brands you grew, then you added a clearance site, a wholesale site, a B2B site, an acquired brand. Each one runs on Shopify. Each one feeds the same warehouse, the same QuickBooks file, the same ShipStation account. Each one needs the same automations.

And each one has its own copy-pasted script, its own login, its own credentials, its own crontab entry, its own staff member who remembers how to restart it. When something breaks — an OAuth token expires, a supplier feed changes format — the fix has to be applied N times. So it doesn't get applied. So things stay broken.

The platform is what shuts that down.

The architecture

Six storefronts. One dashboard. One automation surface.

Conceptually simple. One Python codebase. One credential file. One dashboard. The dashboard renders one tab per storefront, one card per automation. Adding a storefront means adding a SHOPIFY_NEWSTORE_CLIENT_ID and a SHOPIFY_NEWSTORE_CLIENT_SECRET to the .env file, then registering the store in the config. The auth layer, the dashboard, the scheduling — all reused.

automation-hub/.env · one credential surface ini
# One file. One source of truth. All stores.
SHOPIFY_RAWBLEND_CLIENT_ID=...
SHOPIFY_RAWBLEND_CLIENT_SECRET=shpss_...
SHOPIFY_COMMERCIAL_EQUIPMENT_CLIENT_ID=...
SHOPIFY_COMMERCIAL_EQUIPMENT_CLIENT_SECRET=shpss_...
SHOPIFY_UKONSERVE_CLIENT_ID=...
SHOPIFY_UKONSERVE_CLIENT_SECRET=shpss_...
# ... and so on for every storefront

QBO_CLIENT_ID=...
QBO_CLIENT_SECRET=...
QBO_REFRESH_TOKEN=...     # rotated automatically

SHIPSTATION_API_KEY=...
Screenshot · Automation Hub dashboard · six store tabs across the top
What gets unified

Every handoff between stores and the back office.

Inventory

Supplier feeds → all stores

Supplier CSVs, Google Sheets, Excel uploads land in inventory across every relevant storefront automatically. No per-store scripts.

Fulfilment

ShipStation → all storefronts

Labels generated from any storefront flow back into the right QB invoice via a shipment-number prefix convention. One sync job, all stores.

Accounting

QBO purchase orders

Batch-process invoices needing carrier prep, fetch PDFs, tag the right way, email the warehouse. Same pattern across stores.

Cost sync

Supplier price lists → QB

When a supplier sends a new price list, it propagates to PurchaseCost on every product across every relevant storefront.

Reporting

Cross-store dashboard

Once every store is feeding one observability surface, a 'today's sales across all stores' card becomes hours of work, not weeks.

Auth

OAuth, centralised

One auth pattern (client_credentials grant) used identically for every store. Rotate a credential by editing one line in one file.

Why this works

Boring tech, deliberately.

Local-first. The platform runs on a Windows PC in the warehouse (or a cheap VPS — your choice). Flask serves localhost. Windows Task Scheduler triggers automations. State on local disk. No cloud round-trip per run, no recurring infrastructure bill.

One credential file. Per-store config files proliferate and nobody knows where anything lives. A single .env at the hub root with deterministic key naming (SHOPIFY_<STORE>_CLIENT_ID) means rotation is "edit one line."

Idempotent everything. Every automation can be re-run without side effects. When something fails, recovery is "run it again." No state to repair, no half-applied updates to undo.

One dashboard. Each automation writes a status JSON when it finishes. The Flask app polls these and renders one card per automation per store. Staff get one URL to bookmark, one-click manual runs, one-click log access. Diagnosis without a phone call.

Adding the seventh store

Thirty minutes. Not a week.

Adding a new storefront — actual sequence
$ # 1. Create custom app in Shopify admin · grab client_id and client_secret
$ vim .env
add: SHOPIFY_NEWSTORE_CLIENT_ID=...
add: SHOPIFY_NEWSTORE_CLIENT_SECRET=shpss_...
$ vim config/stores.json
add: { "slug": "newstore", "prefix": "NS", "timezone": "Australia/Brisbane" }
$ python -m scripts.test_store_auth newstore
NEWSTORE: auth ok · 1247 products · 24h token live
$ python -m automations.newstore.stock_sync --dry-run
1247 SKUs would update · 0 errors
ready to schedule

Hours, not weeks. The OAuth flow, the dashboard wiring, the logger, the status JSON, the scheduling — all reused. The new automation is one Python module that imports shared.shopify_client and a registry entry.

What it costs

One-off build, zero recurring.

Per-store SaaS fees
$0
Indicative build · 3 stores
from $9,800
Indicative build · 6 stores
from $14,500
Per-store maintenance
On retainer or none

The platform is yours. Source code, deployment guide, runbook. No retainer required — we'll bill discovery and build, hand it over, and you decide whether you want ongoing maintenance or pull it in-house.

Related Builds

Other angles on the
same platform.

Every page on this list is drawn from the same Raw Blend build — different problems, same operating model.

Multiple stores feeling
like multiple problems?

Tell us about your storefronts, your back-office stack, and the handoffs that hurt the most. Discovery is a 30-minute call — we'll tell you whether your setup is workable, what the build would cost, and what we'd ship first.

Discovery is free · Quote in 48 hours · No retainer required