A full-stack newsletter and publishing platform where writers monetize content through paid subscriptions. Built with Next.js 16, Prisma 7, and the Whop SDK.
- OAuth Authentication - Secure login via Whop with PKCE flow
- Writer Registration - Users create publications with custom handles and profiles
- Rich Text Editor - Tiptap-based editor with formatting toolbar, image uploads, and paywall breaks
- Content Gating - Free, paid, and preview visibility modes with server-side enforcement
- Payment Processing - Handled by Whop (checkout, webhooks, payouts via Direct Charge)
- KYC Onboarding - Writer identity verification for receiving payouts
- Subscriptions - Monthly recurring billing with Whop Payments Network
- Explore Page - Trending writers, category filtering, cursor-paginated post feed
- Social Features - Follow writers, like posts, in-app notifications
- Embedded Chat - Whop-powered community chat on writer profiles
| Technology | Purpose |
|---|---|
| Next.js 16 | Full-stack React framework (App Router) |
| React 19 | UI library |
| TypeScript | Type safety |
| Prisma 7 | Database ORM (with driver adapter) |
| PostgreSQL | Database (via Supabase) |
| Whop SDK | Payments, subscriptions, OAuth, KYC |
| Tiptap | Rich text editor |
| UploadThing | File uploads |
| Iron Session | Encrypted cookie sessions |
| Zod | Request validation |
| Tailwind CSS | Styling |
- Node.js 18+
- PostgreSQL database (Supabase recommended)
- Whop Developer Account
- UploadThing Account
git clone https://github.com/whopio/whop-tutorials.git
cd whop-tutorials/penstacknpm installCopy the example env file and fill in your values:
cp .env.example .envSee .env.example for all required variables and where to find them.
npx prisma db pushTo populate the app with demo writers and posts:
npm run db:seedTo enable real Whop checkout for seeded writers, set SEED_EMAIL in your .env to a real email address. The seed script will create Whop sandbox companies for each demo writer. Without it, seeded writers use the demo subscribe fallback.
npm run devOpen http://localhost:3000 in your browser.
In your Whop developer dashboard (sandbox.whop.com > Dashboard > Developer), create a company-level webhook pointing to:
https://your-domain.com/api/webhooks/whop
Subscribe to these events:
payment.succeededmembership.activated
penstack/
├── prisma/
│ ├── schema.prisma # Database schema
│ └── seed.ts # Demo data seed script
├── src/
│ ├── app/
│ │ ├── [writer]/ # Writer profile + article pages
│ │ ├── api/
│ │ │ ├── auth/ # OAuth login/callback
│ │ │ ├── checkout/ # Whop checkout creation
│ │ │ ├── demo/ # Demo subscribe (for seeded writers)
│ │ │ ├── posts/ # CRUD + like toggle
│ │ │ ├── webhooks/ # Whop webhook handler
│ │ │ └── writers/ # Writer CRUD + KYC + follow
│ │ ├── dashboard/ # Writer dashboard
│ │ ├── settings/ # Profile & KYC settings
│ │ └── write/ # Post editor
│ ├── components/
│ │ ├── chat/ # Embedded Whop chat
│ │ ├── demo/ # Demo mode modal
│ │ ├── editor/ # Tiptap editor + toolbar
│ │ ├── explore/ # Feed, trending, categories
│ │ ├── post/ # Post card, content, like, paywall
│ │ ├── settings/ # Onboarding, profile, KYC
│ │ ├── ui/ # Nav, footer, notifications
│ │ └── writer/ # Writer header, subscribe, card
│ ├── constants/ # Categories, config (platform fee)
│ ├── lib/ # Auth, prisma, session, whop, utils
│ └── services/ # Business logic (posts, writers, etc.)
└── guides/ # Step-by-step tutorial
User ──────┬──── Writer ──────┬──── Post ────── Like
│ │
│ ├──── Subscription
│ │
│ └──── Follow
│
├──── Subscription (links User to Writer)
├──── Follow
├──── Like
└──── Notification
WebhookEvent (idempotency tracking)
| Environment | Dashboard | API | Payments |
|---|---|---|---|
| Sandbox | sandbox.whop.com | sandbox-api.whop.com | Test cards only |
| Production | whop.com | api.whop.com | Real payments |
Set WHOP_SANDBOX="true" for development. Remove it for production.
4242 4242 4242 4242- Successful payment- Any future expiration date and any 3-digit CVC
- Push to GitHub
- Import project in Vercel
- Add all environment variables (remove
WHOP_SANDBOXfor production) - Set Whop webhook URL to
https://your-app.vercel.app/api/webhooks/whop - Set OAuth redirect URL to
https://your-app.vercel.app/api/auth/callback - Deploy
npm run build
npm startRequires Node.js 18+ runtime, PostgreSQL database, and all environment variables configured.
This project is for educational purposes only and is not intended for production use. It demonstrates core concepts for building a subscription publishing platform but omits certain security hardening and scalability measures that would be required in a real-world application.
MIT