Multi-tenant by design — RLS, not application code

One admin. Every merchant. Storefronts on your own stack.

Shopnow is a focused Shopify-style backend for agencies that run a handful of merchants. Run catalog, orders, payments, and email from one place — and ship a custom Next.js storefront for every client, against a narrow Storefront API.

No platform fee · You own the Stripe relationship · Self-host friendly
Next.jsApp Router + RSC
TypeScriptStrict, end-to-end
SupabasePostgres + RLS
Stripe ConnectExpress + destination
Amazon SESPer-tenant DKIM
ZodSchemas → SDK
Overview
RA
Revenue (7d)
$48,212
+12.4%
Orders (7d)
284
+6.1%
Conversion
2.81%
−0.2%
Avg. order
$169.76
+4.0%
Revenue
Last 14 days
USD
Recent orders
View all
  • #1042
    Maya Patel
    paid$214.00
  • #1041
    Jonas Vogel
    paid$89.50
  • #1040
    Lia Romero
    refunded$542.20
  • #1039
    Owen Tan
    pending$32.00
Built for agencies

An ecommerce backend that doesn't try to be your client.

Most ecommerce platforms want to sit between you and your merchant. Shopnow stays out of the way: one admin to operate, custom storefronts you control, and a money path that goes straight to your client.

Onboard a merchant in a day

Create a tenant, run Stripe Connect onboarding, verify a domain in SES, ship the storefront. No procurement, no plan limits.

Own the storefront stack

Build the public site in Next.js — yours, not a theme. Talk to Shopnow over a publishable key. Deploy on your own Vercel.

Bill a retainer, not a rev share

No platform fee. No application_fee_amount. Charge clients what your work is worth — Shopnow takes nothing from their GMV.

Capabilities

The boring parts of ecommerce, handled correctly.

Catalog, orders, payments, customers, marketing, transactional email. Built with the constraints that keep a real ecommerce business safe in production.

Multi-tenant admin

One workspace per merchant. Isolated catalogs, orders, customers, staff — enforced by Postgres RLS, not application code.

Storefront API

A narrow, publishable-key surface for catalog reads, cart, and checkout. The only thing a public storefront can touch.

Stripe Connect, done right

Express accounts with destination charges. Each merchant is their own merchant of record — you never hold the funds.

Deliverability by default

Per-merchant DKIM/DMARC via SES, one configuration set per tenant, and a Suppression Guard on every single send.

Order snapshots

Line items snapshot title, SKU, and price at purchase. Historical receipts never drift when you rename a product.

Append-only transactions

Authorization, capture, refund — each one an insert. The full money trail is auditable forever, never mutated.

Storefront SDK

A typed client your storefront actually wants to use.

Every API input and output is a Zod schema. The SDK and TypeScript types are generated from those schemas, so the client you ship to a merchant's storefront is fully typed end-to-end — and it can only call the narrow Storefront surface.

  • Publishable-key auth. Admin endpoints are not reachable.
  • Cursor pagination only — no offset pagination, ever.
  • Structured errors with codes you can branch on.
  • One source of truth: Zod → SDK → types → docs.
storefront/checkout.ts
TypeScript
import { createStorefrontClient } from "@shopnow/storefront-sdk"

const shop = createStorefrontClient({
  publishableKey: process.env.NEXT_PUBLIC_SHOPNOW_KEY!,
  tenant: "northwave-coffee",
})

// Catalog read — typed, cursor-paginated
const { items, next_cursor } = await shop.products.list({ limit: 24 })

// Create a cart, add a variant
const cart = await shop.carts.create()
await shop.carts.addItem(cart.id, {
  variant_id: items[0] .variants[0].id,
  quantity: 1,
})

// Stripe Elements confirms client-side
const { payment_intent_client_secret } = await shop.checkout.start(cart.id)
Guardrails

Safety rails that don't bend under deadline pressure.

A multi-tenant platform has exactly four ways to fail catastrophically: cross-tenant leaks, blasted suppressions, mutated money records, and untraceable changes. Shopnow makes each of them structurally hard.

Tenant isolation, enforced in Postgres

Every tenant-scoped row carries a tenant_id. RLS policies key off auth.tenant_id(). A cross-tenant query returns zero rows by construction, and the isolation test suite proves it.

Suppression Guard on every send

Exactly one code path sends email — and it always checks (tenant_id, email, class) against suppressions first. Bounces and complaints auto-suppress. Marketing can't punch through transactional gates.

Idempotent webhooks

Stripe and SES both retry. We record event ids in the same transaction as the side effect, so replays are safe and observable, not destructive.

Audit log for every mutation

Create, update, delete, refund — every change writes an audit_events row with actor, action, entity, and before/after. You can answer 'who did this, when, and what changed' on demand.

Built focused, not bloated

The features we're not building.

Most platforms hide their scope. We publish ours. If your client needs one of these, Shopnow is not the right tool — and we'll tell you up front. Year-1 scope is deliberately narrow so the things we do ship are correct.

v1 target: 5–20 merchants, single country, single currency.
GraphQLMulti-currencyPrice listsMulti-channelMulti-warehouseB2B / quotesSubscriptionsGift cardsLoyaltyApp marketplacePage builderAdmin themingPartial refundsTax enginePredictive sendingAdmin i18n
FAQ

Short answers to fair questions.

Still unclear? Read the architecture doc or open a ticket.

Who is this for?
Agencies running ecommerce for a handful of merchants (think 5–20). One unified admin and SDK, custom storefronts per client.
Where do payments land?
Directly in each merchant's own Stripe account. The platform is never the merchant of record, so you never hold client funds and stay in PCI SAQ-A.
Can a storefront read another tenant's data?
No. The Storefront API is a separate surface scoped by a publishable key, and every query is explicitly tenant-filtered. The Admin API is unreachable from a storefront.
Do you send email for me?
Through your own SES, authenticated on your merchants' domains. We compile MJML templates, apply merge vars, and gate every send behind the Suppression Guard.

Spin up a tenant. Wire up Stripe. Ship a storefront.

The admin is free to explore. You only need a Stripe Connect account and a domain when you're ready to take real payments and send real email.