Skip to main content

Lynqfy

System Architecture

Creator digital storefront — React 19 + Vite SPA, Firebase platform, Stripe Connect Express for creator payouts, SendGrid for delivery. Multi-tenant SaaS with a card-based landing-page builder and Free/Pro subscription tiers.

Platform stack

Top → bottom

Browser · React 19 + Vite + TypeScript + React Router 7

Feature-slice SPA — 8 domains, Zustand for state, no SSR, no Next.js

Firebase Platform

Auth (Google + email) · Firestore · Storage (product files) · Hosting (SPA rewrites) · Analytics

Cloud Functions v2 · Node.js 22 + TypeScript

Stripe webhook · checkout sessions · Connect Express · signed URLs · SendGrid email

External services

Stripe Connect Express

Creator payouts · platform fees · subscription billing

SendGrid

Download links · email retry · transactional delivery

Custom domain / DNS

Branded creator emails (Zoho) · vanity URLs

Feature slices · 8 domains

Each slice owns its components/ hooks/ pages/ services/

auth

Firebase email/password + Google sign-in. Username setup modal on first login. Plan validation hook gates pro features.

dashboard

Revenue chart, recent purchases/donations, products & pages overview. Each widget has its own Firestore-backed service + hook.

products

Create, edit, delete digital products. File upload to Firebase Storage. Price, title, download cap, visibility settings.

landing

Card-based drag-and-drop page builder. 6 card types, theme presets (Free/Pro), SEO config, draft/published status.

plans

Free vs Pro tier UI. Subscription checkout via subscriptionCheckout function. Upgrade prompts gated by planTier.

stripe

Stripe Connect Express onboarding (createConnectAccount). Platform fee: 5% Free / 0% Pro. Connect account status polling.

onboarding

Step-by-step wizard for new creators: profile setup, product creation, landing page, Connect Express linking.

marketing

Public-facing site: hero, pricing, FAQ, social proof, theme gallery, trust section. Separate from the auth bundle.

Landing-page builder · card types

A landing page is a LandingConfig with an ordered array of typed cards. Each card carries type, order, visible, planTier, and type-specific data.

header

Avatar, display name, bio — the top identity block.

product

Renders selected products with buy buttons and style variants.

gallery

Image grid or carousel with configurable max count.

link-button

Single CTA link with customizable label and URL.

social-grid

Platform icon row/grid with per-platform visibility toggle.

support-me

Donation / tip button backed by optional Stripe price.

Theme system

Each page has a ThemePreset: colors, fonts, spacing, corner radius, shadow, background (solid / gradient / pattern / image), special effects (matrix rain, particles). Free plan gets base presets; Pro unlocks all. Slug routing uses publicLandings/{mappingId} for vanity URLs.

Stripe Connect Express · creator payouts

Platform fee model. Free creators pay a 5% platform fee per sale; Pro creators pay 0%. Fees are applied at the Stripe level via the application_fee_amount field in the checkout session — no manual accounting needed.
Express onboarding. createConnectAccount initiates the Stripe Express onboarding flow.getConnectStatus polls account verification state. Creators can only receive payouts once their Connect account is fully verified.

Firestore collections

Products and landing pages are nested under each user's document

users/{uid}

email, username, plan (free|pro), stripeConnectId, createdAt

└ products/{id}

title, price, fileRef (Storage path), downloadCap, visible, ownerId

└ landingPages/{id}

username, cards[], themePresetId, seo{}, status (draft|published)

publicLandings/{id}

username → userId mapping for public slug routing

orders/{id}

productId, buyerEmail, stripeSessionId, paid, downloadCount, createdAt

Written by stripeWebhook on checkout.session.completed

downloads/{id}

orderId, buyerEmail, timestamp — download analytics

email_logs/{id}

orderId, status, sentAt — SendGrid delivery tracking

subscription_events/{id}

userId, event, stripeSubscriptionId, createdAt

transactions/{id}

Revenue aggregates per creator

Purchase → delivery pipeline

Webhook is the source of truth — fulfillment happens server-side, not on client redirect.

1

Checkout

createCheckoutSession → Stripe session

2

Payment

Stripe confirms, fires webhook event

3

stripeWebhook

Cloud Function validates signature

4

Persist

Order written to orders/{id}

5

getDownloadLink

Signed URL from Firebase Storage

6

SendGrid

emailDownloadLink delivers to buyer

Secure file delivery

No public Storage URLs. getDownloadLink generates a time-limited signed URL from Firebase Storage. Each call decrements downloadCount on the order; once the cap is hit the function returns 403. Storage rules deny all public reads.
Email retry. emailDownloadLink sends the signed URL via SendGrid immediately after the webhook. emailRetry is a separate function for manual resend — useful when SendGrid delivery fails. Both log to email_logs.

Design choices

Stripe webhook events: checkout.session.completed · payment_intent.succeeded · invoice.payment_failed · customer.subscription.updated/deleted