Marryio
My own SaaS — I conceived it, designed it, and shipped it as a solo founder. 17 templates, 3 user roles, real Indonesian payment rails, live in production since 2026.
- 17 Wedding templates
- 3 User roles
- 5 Production add-ons
- 8+ Transactional emails
- 8 Wedding planner tabs
- 1 SaaS in production
The brief.
I founded Marryio after spotting a gap: Indonesian wedding invitations sat between two extremes — cheap WhatsApp graphics with zero UX, and bespoke custom-coded sites that cost millions of rupiah and take weeks. Multi-tenant SaaS was the obvious answer, but no one filled it because the market is messy — 17 regional preferences, family-religious-event variations, and payment rails that international tools don't speak.
I designed, built, and launched Marryio solo. One platform, three roles (Client, Reseller, Superadmin), 17 templates with their own scene systems and animations, and Indonesian payment rails that actually clear — QRIS, GoPay, virtual accounts, refund flows.
The stack.
Frontend
- Next.js 16
- React 19
- TypeScript
- Tailwind v4
- Shadcn UI + Magic UI
Animation
- GSAP + ScrollTrigger (templates)
- Framer Motion (UI)
- Lenis smooth scroll
Backend & Data
- Supabase (auth, Postgres, RLS)
- Server Actions
- React.cache for auth dedup
Payments
- Midtrans Snap API
- QRIS · GoPay · VA · ShopeePay
- Webhook signature verification
Infrastructure
- Cloudflare R2 (media)
- Upstash Redis (rate-limit)
- Vercel + standalone Docker
Ops
- Resend (transactional email)
- Pino structured logging
- Cron (expiry · cleanup)
What it does.
-
Multi-tenant architecture
Three roles (Client, Reseller, Superadmin) sharing the same database with row-level security. Reseller has its own credit ledger, mutation history, and bypass logic for addon gates. RLS policies enforce isolation at the database — not the application.
-
17 distinctive templates
Each template has its own scene system, palette per scene, custom GSAP scroll choreography, and unique mobile experience. Layouts range from split-screen to pinned scroll, scene carousel, sticky card stack, arc slider, and an interactive Minangkabau map with POIs.
-
Wedding Planner add-on
A separate workspace with 8 tabs: checklist (60+ default tasks, 6 cultural task packs), budget (12 categories with auto-sync from invitation orders + vendors), savings tracker with velocity projection, vendor mini-CRM, documents, outfits, traditional seserahan, and 2-way timeline sync with the invitation rundown.
-
E-Invitation card system
Canvas-rendered shareable cards in 5 designs (Noir Prestige, Blush Garden, Sage Botanica, Minimalist Mono, Royal Gold) × 3 sizes (portrait 4:5, square 1:1, story 9:16). Optional QR code embedded for guest check-in.
-
QR Check-in flow
Each guest auto-receives an 8-character unique QR code. On the wedding day, hosts use a public scanner (browser camera + jsQR) to update check-in time. RSVP and physical check-in tracked independently — confirmation online vs attendance offline.
-
Reseller credit ledger
Resellers buy credit packages (Satuan / Starter / Growth / Pro), spawn client invitations from their pool, and the addon gate auto-includes 'analytics + extend_forever' so reseller-managed invitations live forever. Three-layer defense against expiry-bug regressions in publishInvitationAction.
Architecture highlights.
-
Auto-lock protection
Published invitations lock automatically — clients can't accidentally edit a live wedding page on the morning of the event. Name-change detection forces a re-lock so a manual unlock can't quietly publish the wrong couple's names.
-
Per-tenant data isolation
Every query carries the tenant's scope at the database level. A reseller sees only their own client invitations and credit ledger. A client sees only their own invitation, RSVPs, and gallery. Isolation is enforced by the database, not the application — there is no path that bypasses it.
-
Resilient by default
Slow auth backend, rate-limiter outage, or webhook hiccup never takes the public invitation page down for a viewing guest. Auth and rate-limit checks fail open when their dependency is degraded; the guest still gets their invitation.
-
Wedding Planner sync at planner-speed
Budget, vendors, outfits, and timeline stay in sync as the invitation order grows. Adding a venue, a Wedding Planner add-on, or a custom outfit reflects across the planner workspace in under a second — no manual refresh, no inconsistent rows between tabs.
-
Real payment-rail integration
QRIS, GoPay, virtual accounts, and refund flows that actually clear with Indonesian banks. Webhook signature verification, refund status polling across T+1 to T+3 settlement windows, and idempotent order updates — the parts a global payment SDK doesn't ship.
-
Self-host friendly
The platform runs on a managed cloud today, but the same build is deployable as a self-contained container. Useful for the client who wants their wedding data on their own infrastructure, or for the reseller who wants to white-label without depending on a third-party tenant.
What I learned.
-
Constraints sharpen craft
Single market, single engineer — every constraint forced a sharper decision. The seventeen-template constraint pushed a reusable scene-and-palette system, not seventeen forked codebases.
-
Indonesian payment rails are a moat
Webhook authentication, refund status polling across multi-day settlement windows, QRIS dynamic QR generation — none of this is in a tutorial. The debugging is institutional knowledge a global competitor has to rebuild from scratch.
-
Accessibility is recruiter-grade work
Reseller and Superadmin dashboards meet WCAG focus, semantics, and contrast standards. Recruiter-grade portfolios get audited; a wedding SaaS that ignores accessibility loses the family member with a screen reader who's trying to read the invitation.
Need a build like this?
I'm open to full-time, freelance, and corporate engineering work — SaaS, AI integration, and motion-rich web. Discovery call is free.