StoreStock: Vision & Concept
Advanced store availability, locator, and Click & Collect operations for multi-location Shopify retailers.
The Gap in the Market
Existing Shopify solutions are fragmented and basic. Merchants currently need multiple apps (store locator, availability checker, pickup manager) that don’t integrate. StoreStock solves this with one merchant-first system and a clean storefront experience.
Real Demand
Multi-location retailers need per-location stock visibility to stop losing walk-in and pickup sales.
No Direct Competitor
Most apps do maps. Few do stock. Almost none do POS + pickup ops in a unified, theme-agnostic way.
High Perceived Value
Location-aware inventory and pickup ops are premium features with measurable revenue impact.
Revenue Potential
With 100 merchants (60 Starter, 30 Pro, 10 Business), monthly revenue is projected at ~$17,700 (~R336,000). Operational costs remain low at early scale.
Competitive Analysis
Comparison of StoreStock vs existing Shopify App Store solutions.
| Merchant Count | Monthly Revenue | Estimated Costs | Net Profit | Profit Margin |
|---|---|---|---|---|
| 10 merchants | $1,770 (~R33,600) | $150 (~R2,850) | $1,620 (~R30,750) | 91.5% |
| 50 merchants | $8,850 (~R168,150) | $150 (~R2,850) | $8,700 (~R165,300) | 98.3% |
| 100 merchants | $17,700 (~R336,300) | $200 (~R3,800) | $17,500 (~R332,500) | 98.9% |
| 500 merchants | $88,500 (~R1,681,500) | $600 (~R11,400) | $87,900 (~R1,670,100) | 99.3% |
Tier Mix Assumptions Used
- Starter: 60% of merchants @ $79/month
- Professional: 30% of merchants @ $249/month
- Business: 10% of merchants @ $549/month
This reflects realistic adoption: most merchants start on Starter, fewer graduate to higher tiers.
StoreStock Advantages
All-in-One System
Availability, locator, SEO, and ops. Merchants stop duct-taping three apps together.
South African Focus
Suburb search, mall context, WhatsApp deep-links, and SA retail realities built in.
Merchant-First UX
Polaris admin with full control over locations, details, and storefront presentation.
Privacy-Correct Proximity
No proximity until customers explicitly allow location. Clear controls to update or clear location.
Premium Pricing That Matches Value
$79 / $249 / $549 tiers aligned to meaningful operational outcomes, not vanity widgets.
Tiered Growth Path
Start on availability. Upgrade into discovery and ops. No migrations, no rebuilds.
Cost Analysis
Breakdown of operational costs for building and running StoreStock at scale.
Development Costs (One-time)
| Item | Cost | Notes |
|---|---|---|
| Development Time (Phase 1) | $0 | Building yourself |
| Shopify Partners Account | $0 | Free to create |
| Development Store | $0 | Free for testing apps |
| Domain Name | ~$12/year (~R220) | storestock.app or similar |
Monthly Operational Costs
| Service | Cost | Notes |
|---|---|---|
| GCP Cloud Run | $5-20/month (R90-R370) | Scales automatically, pay per request. |
| GCP Cloud SQL (PostgreSQL) | $10-50/month (R180-R900) | Managed database. 1GB sufficient for early scale. |
| Google Maps Geocoding API | $0-10/month (R0-R180) | $200 free credit monthly. Most addresses cached. |
| Google Maps JavaScript API | $0-20/month (R0-R370) | Store locator map loads (Professional+). |
| WhatsApp API (Twilio/MessageBird) | $0-30/month (R0-R550) | Business tier notifications, scales with usage. |
| Shopify App Store Fee | 0% (first $1M) | Shopify takes 0% on first $1M revenue, then 15%. |
| Total | $25-130/month (~R460-R2,400) | Scales with merchant count and usage |
Revenue Projections
Tier Mix Assumptions Used
- Starter: 60% of merchants @ $79/month
- Professional: 30% of merchants @ $249/month
- Business: 10% of merchants @ $549/month
Used consistently across all projections below.
| Merchant Count | Monthly Revenue | Estimated Costs | Net Profit | Profit Margin |
|---|---|---|---|---|
| 10 merchants | $1,770 (~R33,600) | $150 (~R2,850) | $1,620 (~R30,750) | 91.5% |
| 50 merchants | $8,850 (~R168,150) | $150 (~R2,850) | $8,700 (~R165,300) | 98.3% |
| 100 merchants | $17,700 (~R336,300) | $200 (~R3,800) | $17,500 (~R332,500) | 98.9% |
| 500 merchants | $88,500 (~R1,681,500) | $600 (~R11,400) | $87,900 (~R1,670,100) | 99.3% |
Pricing Strategy
Three tiers designed for the South African market. Scalable from boutiques to large retail chains.
- Up to 5 locations
- Locations Drawer & Search
- Product Availability Summary
- Store-specific Stock Alerts (email)
- Location-based proximity (only after permission)
- No Store Locator
- No Click & Collect Ops
- No POS Integration
Target: Brands with 1–5 locations
- Everything in Starter, plus:
- Up to 20 locations
- Advanced Store Locator (Maps JS API)
- SA Optimisation (Suburb/Mall)
- Local SEO & Schema Injection
- Performance Dashboard
- Store Attributes Filtering
- No Click & Collect Ops
- No POS Integration
Target: Growing retailers (5–20 locations)
- Everything in Professional, plus:
- Up to 75 locations
- POS Embedded UI
- Click & Collect Operations
- Reserve at Store
- Network Stock View
- Smart Replenishment
- Transfer Requests
- WhatsApp Notifications
Target: Established multi-store retailers
Development Phases
StoreStock will be built in 3 progressive phases, each aligned to the pricing tiers.
Phase 1: Starter MVP - Store Availability
4-6 weeksLaunch as: Starter plan ($79/month) (~R1,500)
Focus on product page availability + locations drawer, with merchant-first location management and geocoding. Proximity is only enabled after explicit customer location permission.
Week 1-2: Foundation
- Project setup with Shopify CLI (Remix template)
- Database schema (locations, settings) with Prisma
- OAuth and shop installation flow
- Polaris admin UI foundation
- Location import from Shopify Locations API
Week 3-4: Core Availability
- Location CRUD (add, edit, delete)
- Business hours management
- Google Geocoding integration + manual overrides
- Theme App Extension: product block + drawer
- App Proxy endpoint for storefront availability
Week 5-6: Alerts & Polish
- Stock alerts (email) per store
- Location permission state UX (pre vs post permission)
- Update location + clear location controls
- Deployment to GCP (Cloud Run + Cloud SQL)
- App Store listing (unlisted first)
Deliverable: Working store availability app with correct privacy-first proximity
Phase 2: Professional - Store Locator & SEO
3-4 weeksLaunch as: Professional plan ($249/month) (~R4,700)
Dedicated store locator map, SA context improvements, schema injection, and performance analytics.
Week 7-8: Locator Page
- Store locator section/template (full page OR embedded)
- Google Maps JavaScript API integration
- Search by suburb/city/postal with Places autocomplete
- Store photos for cards
Week 9-10: SEO + Analytics + Billing
- Local SEO schema injection (JSON-LD)
- Open now status + filtering
- Performance dashboard (demand heatmap + supply leaks)
- Shopify Billing API integration + plan gating
Deliverable: Full store locator with SEO and performance insights
Phase 3: Business - Omnichannel Ops
6-8 weeksLaunch as: Business plan ($549/month) (~R10,500)
Click & Collect operations, POS extension, network stock view, transfers, WhatsApp notifications, and advanced analytics.
Week 11-13: Click & Collect Core
- Pre-checkout store selection + inventory-aware allocation
- Time slots + capacity limits + blackout dates
- Reserve at store (soft allocation + auto release)
- Order tagging + operational status model
Week 14-16: POS + Ops
- POS UI Extension (pickup tile)
- Staff pick list and one-tap "Mark Ready"
- Network stock view (cross-store visibility)
- Transfer requests + approvals + tracking
Week 17-18: Notifications + Analytics
- WhatsApp pickup-ready alerts + reminders (plus email fallback)
- Advanced analytics (comparisons, trends, exports)
- Pickup feedback loop automation
- Smart replenishment recommendations
Deliverable: Complete omnichannel ops layer for Shopify retailers
Starter Plan ($79/mo)
Essential store availability that converts intent into foot traffic. Ideal for brands with 1–5 locations.
Store Availability on Product Pages
- Product page availability summary (e.g. “Available at Sandton City · 5 in stock”)
- Variant-aware stock per store
- Optional exact quantities or simple “In stock”
- Open / closed status based on store hours
Locations Drawer
- Expandable drawer listing all store locations
- Sort by availability
- Sort by closest / farthest (only after location permission)
- Filter: available stores only
- Search stores by name
- Store actions:
- Get directions
- Notify me (out of stock)
Location & Proximity Logic
- Pre-location permission:
- No proximity logic
- No distance display
- Google Maps destination-only link
- Post-location permission:
- Distance per store
- Proximity sorting
- Full Google Maps route (start + end)
- Customer controls:
- Update location
- Clear location
- localStorage caching with optional customer metafield fallback
Stock Alerts
- Store-specific “Notify me” alerts
- Email notifications when stock returns
- Direct recovery link to product
- Optional low-stock indicators
Merchant Admin (Polaris)
- Import locations from Shopify Locations API
- Auto-sync new locations
- Full location management:
- Business hours (per day)
- Contact details
- Active / inactive toggle
- Custom sort order
- Google Geocoding integration:
- Batch geocoding
- Manual override
- Validation
Theme Integration
- Theme App Extension
- No hard theme edits
- Works across all Shopify themes
Implementation Guide
- Install: Install StoreStock → Grant permissions
- Import Locations: Dashboard → Locations → “Import from Shopify”
- Configure Display:
- Toggle exact quantities (optional)
- Set low-stock threshold (optional)
- Set distance unit (km/miles) for when location is enabled
- Enable Alerts: Settings → Notifications → Configure email templates
- Theme Integration: Theme Editor → Product page → Add “Store Availability” block
- Test: Check pre-permission state, then enable location, then update/clear location
Professional Plan ($249/mo)
Discovery, SEO dominance, and demand intelligence. Ideal for 5–20 locations.
Advanced Store Locator
- Google Maps JavaScript API
- Full page or embedded section
- Custom map styling
- Marker clustering and zoom-to-fit
- Rich store cards:
- Images
- Parking info
- Mall / entrance guidance
South African Market Optimisation
- Suburb-first search (before postal codes)
- Mall logic (e.g. “Entrance 5 · Upper Level”)
- Google Places autocomplete
- “Use my location” shortcut
- WhatsApp deep-links to stores or managers
Store Attributes & Filtering
- Merchant-defined store attributes via metafields
- Filter by:
- Open now
- Custom attributes (generator, wheelchair access, etc.)
Local SEO & Google Shopping
- Automatic JSON-LD schema injection
- Product + local availability schema
- Eligibility for “In stock nearby” in Google Shopping
- Zero manual SEO setup
Performance Dashboard
- Customer demand heatmap by search location
- Supply leak insights (searches with no stock)
- Track:
- Store views
- Get Directions clicks
- Availability vs conversion
- Store-level performance comparison
Implementation Guide
- Google Maps Setup:
- Create GCP Project → Enable Maps JavaScript API + Places API
- Generate API key → Restrict to your domain
- Paste key into StoreStock Settings → Maps
- Configure Locator:
- Add Store Locator page OR embed section
- Configure filters (attributes via metafields)
- SEO:
- Enable schema injection
- Validate via Google Rich Results Test
Business Plan ($549/mo)
Full omnichannel operations with native POS and Click & Collect. Built for established multi-store retailers.
Click & Collect Operations
- Works alongside Shopify Click & Collect
- Pre-checkout store selection
- Inventory-aware allocation
- Time slot booking:
- Capacity limits
- Lead times
- Blackout dates
- Auto “Ready at” time calculation
POS Embedded UI
- Native Shopify POS tile
- Pickup queue with badge counts
- Pick lists per location
- One-tap “Mark Ready”
- No extra hardware
- No external dashboards
Reserve at Store
- Reserve stock without upfront payment
- Store-specific soft allocation
- Auto-release after 24 hours
- Pay in store
- Inventory-safe logic
Network Stock View
- Real-time stock visibility across all stores
- POS quick lookup
- Staff-assisted referrals to nearby branches
- Keeps sales inside the brand
Smart Replenishment
- Detect low-stock patterns per store
- Demand-aware replenishment suggestions
- Inter-store transfer recommendations
Transfer Requests
- Staff-initiated transfer requests
- Approval workflows
- Status tracking:
- Requested
- Approved
- In transit
- Received
Notifications
- WhatsApp pickup-ready alerts
- WhatsApp reminders for uncollected orders
- Email fallbacks
- Per-store templates
Advanced Analytics & Feedback
- Multi-store comparisons
- Trend analysis
- Pickup prep-time metrics
- No-show tracking
- Exportable reports
- Automated pickup experience feedback
Implementation Guide
- Enable Click & Collect:
- Shopify Admin → Shipping and delivery → Enable local pickup
- Configure pickup locations in Shopify
- Configure StoreStock Ops:
- Enable time slots, capacity limits, lead times, blackout dates
- Enable reserve at store rules (hold time + auto-release)
- Setup POS:
- Shopify Admin → Apps → StoreStock → Add to POS
- Add pickup tile to Smart Grid
- Notifications:
- Connect WhatsApp provider (Twilio/MessageBird)
- Enable email fallback templates
User Flows by Tier
Starter: Product Page Availability (Pre-Permission → Optional Permission demonstrate)
Customer Journey (pre-location permission):
- Lands on product page
- Sees “Available at V&A Waterfront · 5 in stock” (no distance)
- Clicks “View all locations”
- Drawer opens with store list (no distance, no proximity sorting)
- Clicks “Get directions” (destination-only link)
Customer Journey (after allowing location):
- Customer taps “Enable location to sort by distance” (CTA in block or drawer)
- Browser requests location permission
- Distances appear and list can sort by closest/farthest
- Google Maps opens with route (start + end) when tapping directions
- Customer can Update location or Clear location at any time
Technical flow: Theme App Extension → App proxy → Fetch inventory from Shopify → Merge with location data → (If lat/lng) calculate distances → Return list + permission state
Professional: Store Locator Flow
Customer Journey:
- Visits store locator page/section
- Sees interactive map with pins for all locations
- Searches “Sandton” or uses “Use my location”
- Filters by “Open now” and store attributes
- Clicks store card to view details (hours, contact, mall context)
- Clicks “Get directions” or “Check stock”
Business: Click & Collect Flow
Customer Journey:
- On product page, selects store for pickup (pre-checkout) and chooses a time slot
- Adds to cart with store preference
- At checkout, local pickup is aligned to the chosen store
- Completes checkout
- Receives email confirmation, then WhatsApp/email when ready
Staff Journey:
- Staff views pickup queue (dashboard or POS tile)
- Staff picks items, then marks ready
- Customer receives WhatsApp + email
- Customer collects, staff marks collected
Business: POS-Integrated Flow
Staff Journey (POS):
- Staff opens POS, sees “StoreStock Pickups” tile with badge
- Taps tile, sees pickup queue for this location
- Marks ready from POS
- Customer gets WhatsApp notification
- Marks collected when customer arrives
Network Stock Visibility:
- Customer asks in-store about a size/variant
- Staff checks StoreStock network view
- Shows which store has stock
- Staff initiates transfer request if needed
Tech Stack
Frontend
- Remix: React framework for Shopify apps (official template)
- Polaris: Shopify's design system for admin UI
- Theme App Extensions: Liquid + JavaScript for storefront blocks
- Vanilla JavaScript: For storefront drawer/modal (no framework bloat)
Backend
- Node.js: Runtime environment
- Remix (server): Routing, loaders, actions
- Prisma ORM: Type-safe queries and migrations
- PostgreSQL: Multi-tenant database for shops, locations, settings
Hosting & Infrastructure
- GCP Cloud Run: Containerized hosting (auto-scaling)
- GCP Cloud SQL: Managed PostgreSQL database
- GCP Secret Manager: API keys and credentials
- GCP Cloud Build: CI/CD pipeline
Shopify APIs
- Admin API (GraphQL): Locations, inventory levels, webhooks
- Storefront API (GraphQL): Inventory + product/variant context
- App Proxy: Storefront requests routed to our backend
- Billing API: Subscription management and plan gating
- POS Extensions API: Tiles and actions (Business plan)
External APIs
- Google Geocoding API: Address → coordinates
- Google Maps JavaScript API: Locator map
- Twilio/MessageBird WhatsApp API: Pickup notifications (Business plan)
Architecture Overview
Multi-Tenant Architecture
One app instance serves all merchants. Every database query is filtered by shopId to ensure
data isolation.
// ALWAYS filter by shop
const locations = await prisma.location.findMany({
where: {
shopId: currentShop.id,
isActive: true
}
});
// NEVER do this (leaks data)
const locations = await prisma.location.findMany({
where: { isActive: true }
});
Data Flow: Customer Checks Availability
1. Customer visits product page
2. Theme App Extension requests App Proxy:
/apps/store-availability/check?product_id=...&variant_id=...
(lat/lng only present after permission)
3. Shopify forwards to our backend with shop context
4. Backend:
a) Identify shop
b) Fetch shop locations (DB)
c) Fetch inventory levels (Shopify)
d) If lat/lng present: calculate distances + enable proximity sorting
e) Return list + permission state
5. Frontend renders summary + drawer
Webhooks
Required Webhooks
APP_UNINSTALLED- Clean up shop dataLOCATIONS_CREATE- New location added (prompt to import)LOCATIONS_UPDATE- Location details changedLOCATIONS_DELETE- Location removedINVENTORY_LEVELS_UPDATE- Optional for caching optimisations
Database Schema
Prisma schema for multi-tenant architecture.
// prisma/schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model Shop {
id String @id @default(uuid())
shopifyDomain String @unique
accessToken String
locations Location[]
settings Settings?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Location {
id String @id @default(uuid())
shopId String
shop Shop @relation(fields: [shopId], references: [id], onDelete: Cascade)
shopifyLocationId String
name String
address String
city String
province String?
country String
postalCode String?
latitude Float?
longitude Float?
phone String?
email String?
managerName String?
whatsAppNumber String?
suburb String?
mallName String?
businessHours Json?
isActive Boolean @default(true)
sortOrder Int @default(0)
photoUrl String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([shopId, shopifyLocationId])
@@index([shopId])
@@index([city])
@@index([suburb])
}
model Settings {
id String @id @default(uuid())
shopId String @unique
shop Shop @relation(fields: [shopId], references: [id], onDelete: Cascade)
showExactQuantity Boolean @default(true)
showBusinessHours Boolean @default(true)
showContactDetails Boolean @default(true)
lowStockThreshold Int @default(5)
googleMapsApiKey String?
whatsAppApiKey String?
primaryColor String @default("#000000")
currentPlan String @default("starter")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
Source of Truth for AI Implementation
Structured summary for pasting into Claude Code or other AI coding assistants.
Project Context
PROJECT: StoreStock - Shopify App
PURPOSE: Store availability + locator + omnichannel ops (Click & Collect + POS)
TARGET: Multi-location retailers
MARKET: SA-first UX improvements
TECH: Remix + Prisma + Postgres + GCP + Shopify APIs
PHASES:
1) Starter MVP: availability + drawer + email alerts + privacy-first location
2) Professional: locator map + SA search + schema + dashboard + billing
3) Business: Click & Collect ops + POS tile + network stock + transfers + WhatsApp notifications
PRICING:
- Starter: $79/mo (~R1,500)
- Professional: $249/mo (~R4,700)
- Business: $549/mo (~R10,500)
Key Technical Decisions
FRAMEWORK: Remix (Shopify official template)
DATABASE: PostgreSQL (Cloud SQL)
ORM: Prisma
ADMIN UI: Shopify Polaris
STOREFRONT: Theme App Extensions + Vanilla JS
HOSTING: GCP Cloud Run
SECURITY:
- Filter all DB queries by shopId
- Encrypt tokens/keys at rest
- Validate webhook signatures
PERFORMANCE:
- Cache geocoding results
- Debounce storefront requests
- Index by shopId, suburb, city
- Only compute distances after explicit customer permission (lat/lng present)
API Contract (Availability Check)
// GET /apps/store-availability/check
Request:
?product_id=123
&variant_id=456
&lat=-33.9036 (optional; only after permission)
&lng=18.4208 (optional; only after permission)
Response:
{
"hasCustomerLocation": false,
"locations": [
{
"id": "uuid",
"name": "Sandton City",
"address": "...",
"suburb": "Sandton",
"latitude": -26.1076,
"longitude": 28.0567,
"distance": null,
"stockLevel": 5,
"businessHours": { "mon": { "open": "09:00", "close": "18:00" } },
"isOpen": true,
"phone": "...",
"whatsAppNumber": "..."
}
]
}