A pay-per-article micropayment platform for independent publishers — built end to end, from architecture to go-to-market, as a registered company.
Funjibly is a pay-per-article micropayment platform for independent publishers. Readers load a portable wallet once and unlock articles across any participating publisher's site; publishers keep 80% of every sale. I designed and built the platform end to end — architecture, infrastructure, and product decisions — and operate it as a registered LLC. It's live in production with a complete pipeline from publisher signup through automated payout.
Modular monolith
A single, well-organized backend with clear boundaries between routes, controllers, and services — rather than a premature microservices split for a system at this stage.
Google OAuth with JWT-based sessions, and role-based access control
Authentication runs through Google OAuth with JWT session tokens; access control distinguishes readers, publishers, and admin functions.
External, managed data layer
MongoDB Atlas as the primary datastore, Redis for caching — both managed services, keeping operational surface area intentionally small.
Stripe Connect for marketplace payments
Splits every transaction between platform and publisher automatically, with predictable, transparent payouts on the publisher side.
Azure Communication Services for transactional email
Routed through a single email service class with a fire-and-forget delivery pattern, so outbound email never blocks a request.
Infrastructure as Code
Terraform manages both staging and production environments end to end.
CI/CD via GitHub Actions
Staging deploys automatically on push to main. Production promotion is a manual, deliberate workflow dispatch — separating shippable from shipped.
Azure Container Apps and Static Web Apps
API runs on Container Apps, frontend on Static Web Apps — compute that scales to near-zero cost at low traffic.
Observability
Application Insights tracks failed requests, exceptions, and dependency errors, with alert thresholds tuned to catch real failures without flagging routine bot traffic.
Stack
Node.js, Express, and TypeScript on the backend; React and Vite on the frontend.
Claude as a coding partner
Used throughout the build for implementation speed, and for catching issues that are easy to introduce without a second engineer reviewing. One example: a timing bug in the publisher embed code, caused by two conditional script tags racing on load order, fixed by collapsing them into a single deterministic block.
Tests run in ephemeral CI environments
Every GitHub Actions run starts clean rather than depending on leftover local state. Core business logic under test includes revenue-share calculation and metering/auth-boundary logic — the areas where a quiet bug would cost publisher trust fastest.
Pivot: Hard paywall → four paywall modes
Started with a hard paywall only. After determining that a single rigid model didn't fit the real range of publisher use cases, expanded to four modes — hard, metered, dynamic, and integrated (layering on top of existing tools like Leaky Paywall or Piano.io).
Pivot: Manual onboarding → self-serve
Started by onboarding each publisher manually. Rebuilt it as a fully self-serve flow — apply, verify, connect Stripe, add one embed snippet, get paid automatically — reducing both the operational bottleneck and the relationship-dependency weight publishers were placing on direct hand-holding.
Formed as an LLC
Treated as a real company from the start, not a side experiment.
Stripe Connect as a trust mechanism, not just a payment processor
Publishers need to see transparent, predictable payouts before they'll adopt anything new — that's what the integration was built to prove, not just to process transactions.
Adjusted the sales approach based on what didn't work
Cold-pitching a finished product landed poorly. A two-call model replaced it — a research-first call to understand a publisher's actual pain points, followed by a pitch call that opens with what they said. That shift changed how every subsequent conversation was run.