Specification
2. System Architecture

2. System Architecture

Vespertene Shop follows a decoupled headless commerce architecture. The Next.js storefront communicates with the Medusa backend via REST API. All file storage is handled by Cloudflare R2. Payments are processed by Stripe, with webhooks firing back to the Medusa backend to trigger order fulfilment and download link generation.

2.1 Services & Responsibilities

ServiceRoleURL
Vercel (Next.js)Storefront — SSR, caching, auth guardsshop.vespertene.com
Fly.io (Medusa v2)Backend API, business logic, webhooksapi.shop.vespertene.com
Supabase (PostgreSQL)Primary database, connection pooling via PgBouncerInternal only
Cloudflare R2ZIP file storage, presigned URL deliveryCDN-backed
StripePayment processing, refunds, webhook eventsExternal
ResendTransactional emails — orders, invites, resetsExternal
Cloudflare DNSDNS routing, DDoS protection, Bot Fight ModeDNS layer
SentryFrontend + backend error trackingExternal
Better UptimeUptime monitoring and alertsExternal

2.2 Request Flow

  1. Customer DNS request → Cloudflare → Vercel (storefront) or Fly.io (API)
  2. Storefront fetches product/order data from Medusa API with JWT auth
  3. Stripe Elements communicates directly with Stripe — card data never touches your server
  4. Stripe webhook fires to Medusa backend on payment success
  5. Medusa generates download links and triggers Resend confirmation email
  6. Download request → Medusa validates token → R2 presigned URL (15 min expiry)
  7. Browser redirects to R2 presigned URL → ZIP served directly from Cloudflare CDN

2.3 Architecture Diagram

Customer Browser


Cloudflare DNS/CDN ──────────────────────────────┐
      │                                           │
      ▼                                           ▼
Vercel (Next.js) ──── API calls ────► Fly.io (Medusa v2)
      │                                     │    │    │
      │ Stripe.js                           │    │    │
      ▼                                     ▼    ▼    ▼
   Stripe ◄──── Webhook ────────── Supabase  R2  Resend
⚠️

Stripe card data never passes through your server. Stripe Elements handles it directly — you only receive a payment intent confirmation.

2.4 Environments

EnvironmentBackendFrontendDatabasePurpose
Developmentlocalhost:9000localhost:3000Local PostgreSQLLocal development
StagingFly.io (staging app)Vercel PreviewSupabase dev schemaPre-production testing
ProductionFly.io (prod app)Vercel ProductionSupabase prod schemaLive users