A high-security, production-ready P2P marketplace for plant cuttings and buds, built with Next.js 16, Auth.js v5, Prisma 7, and Stripe.
- Framework: Next.js 16 (App Router, Stable Turbopack)
- Auth: Auth.js v5 (Google OAuth + Credentials)
- Database: Prisma 7 with PostgreSQL (engineType="client")
- Payments: Stripe (Subscriptions + Payment Intents)
- UI: Tailwind CSS, Shadcn/ui, Framer Motion
- TypeScript: Strict mode with Zod validation
- ✅ User authentication (Google OAuth & Credentials)
- ✅ RBAC (Role-Based Access Control) with Admin panel
- ✅ Plant listing with admin approval workflow
- ✅ Credit-based swap system
- ✅ Tiered subscriptions (Free, Monthly ₹300, Yearly ₹1000)
- ✅ One-time credit top-ups via Stripe
- ✅ Real-time marketplace with caching optimization
- ✅ Approval queue with Framer Motion animations
- ✅ Bulk approval actions
- ✅ Dashboard statistics
- ✅ User management capabilities
- ✅ XSS/CSRF protection
- ✅ Zod schema validation on all server actions
- ✅ JWT session management
- ✅ Secure Stripe webhook handling
- App Router: Leveraging React Server Components
- Turbopack: Stable build system for faster development
- 'use cache': Explicit caching for marketplace optimization
- proxy.ts: Root-level RBAC routing (replaces middleware.ts)
User (ADMIN/USER roles)
├── Plants (PENDING/APPROVED/REJECTED)
├── SwapRequests
├── CreditTransactions
└── Subscription details
- Subscriptions: Stripe Checkout → Webhook → Update User Tier + Credits
- Credits: Payment Intent → Webhook → Add Credits to Account
- Swaps: Accept Request → Deduct 1 Credit
- Node.js 18+
- PostgreSQL database
- Stripe account
- Google OAuth credentials (optional)
- Run the setup script:
chmod +x setup.sh
./setup.sh- Configure environment variables:
cp .env.local.example .env.local
# Edit .env.local with your credentials- Set up the database:
npx prisma db push- Start development server:
npm run devVisit http://localhost:3000
# Database
DATABASE_URL="postgresql://user:password@localhost:5432/ecoexchange"
# NextAuth.js
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="generate-with-openssl-rand-base64-32"
# Google OAuth (Optional)
GOOGLE_CLIENT_ID="your-client-id"
GOOGLE_CLIENT_SECRET="your-client-secret"
# Stripe
STRIPE_SECRET_KEY="sk_test_..."
STRIPE_PUBLISHABLE_KEY="pk_test_..."
STRIPE_WEBHOOK_SECRET="whsec_..."
STRIPE_MONTHLY_PRICE_ID="price_..."
STRIPE_YEARLY_PRICE_ID="price_..."
# App
NEXT_PUBLIC_APP_URL="http://localhost:3000"ecoexchange/
├── proxy.ts # Root-level RBAC proxy
├── prisma/
│ └── schema.prisma # Prisma 7 schema
├── src/
│ ├── app/
│ │ ├── (auth)/ # Auth pages
│ │ ├── (dashboard)/ # Protected routes
│ │ │ ├── dashboard/ # User dashboard
│ │ │ ├── plants/ # Plant management
│ │ │ ├── marketplace/ # Public listings
│ │ │ ├── subscription/ # Payment management
│ │ │ └── admin/ # Admin panel
│ │ └── api/
│ │ ├── auth/ # Auth.js handlers
│ │ └── webhooks/ # Stripe webhooks
│ ├── actions/ # Server Actions
│ │ ├── plant-actions.ts
│ │ ├── admin-actions.ts
│ │ ├── subscription-actions.ts
│ │ ├── credit-actions.ts
│ │ └── swap-actions.ts
│ ├── components/
│ │ ├── ui/ # Shadcn components
│ │ ├── plants/ # Plant components
│ │ └── admin/ # Admin components
│ ├── lib/
│ │ ├── auth.ts # Auth.js v5 config
│ │ ├── db.ts # Prisma client
│ │ ├── stripe.ts # Stripe client
│ │ ├── utils.ts # Utilities
│ │ └── validations.ts # Zod schemas
│ └── types/
│ └── index.ts # TypeScript types
└── public/
User → Post Plant (PENDING) → Admin Review → APPROVED/REJECTED → Marketplace
User → Browse Marketplace → Request Swap → Owner Approves → Credit Deducted
User → Choose Plan → Stripe Checkout → Webhook → Update Tier + Add Credits
npm run dev # Start dev server with Turbopack
npm run build # Build for production
npm run start # Start production server
npm run lint # Run ESLint
npx prisma studio # Open Prisma Studio
npx prisma db push # Push schema to database- Create the page component in
src/app/(dashboard)/your-page/page.tsx - Add server actions in
src/actions/your-actions.ts - Create Zod validation schemas in
src/lib/validations.ts - Update types in
src/types/index.ts
To create an admin user:
- Register a normal account
- Open Prisma Studio:
npx prisma studio - Find your user in the User table
- Change
rolefromUSERtoADMIN - Refresh and access
/admin/approval
In Stripe Dashboard, create:
- Monthly subscription (₹300/month)
- Yearly subscription (₹1000/year)
Add the price IDs to .env.local:
STRIPE_MONTHLY_PRICE_ID="price_xxx"
STRIPE_YEARLY_PRICE_ID="price_xxx"# Install Stripe CLI
stripe login
stripe listen --forward-to localhost:3000/api/webhooks/stripe
# Copy the webhook signing secret to .env.localUse Stripe test cards:
- Success:
4242 4242 4242 4242 - Decline:
4000 0000 0000 0002
GET /api/health- Health checkPOST /api/auth/[...nextauth]- Auth.js handlersPOST /api/webhooks/stripe- Stripe webhook receiver
/- Landing page with pricing/login- Sign in page/register- Sign up page
/dashboard- User dashboard/plants- My plants/plants/new- Create plant listing/marketplace- Browse approved plants/subscription- Manage subscription/swap-requests- View swap requests
/admin/approval- Approve/reject pending plants
Built with Shadcn/ui:
- Button, Card, Input, Label
- Badge, Dialog, Dropdown Menu
- Table, Toast
- Role (ADMIN/USER)
- Subscription tier (FREE/MONTHLY/YEARLY)
- Credits (Int)
- Stripe customer ID
- Status (PENDING/APPROVED/REJECTED)
- Species, description, health score
- Metadata (difficulty, sunlight, water needs)
- Status (PENDING/ACCEPTED/REJECTED)
- Links requester, owner, and plant
- Tracks all credit movements
- Links to Stripe payment intents
- Push to GitHub
- Import to Vercel
- Add environment variables
- Deploy!
- Set
NEXTAUTH_URLto your domain - Use production Stripe keys
- Configure webhook endpoint in Stripe Dashboard
- ✅ All server actions use Zod validation
- ✅ RBAC enforced at proxy.ts level
- ✅ Stripe webhooks verify signature
- ✅ Passwords hashed with bcrypt
- ✅ JWT sessions with secure cookies
- ✅ CSRF protection enabled
- ✅ 'use cache' on marketplace for optimal performance
- ✅ Turbopack for fast builds
- ✅ Image optimization with Next.js Image
- ✅ Database queries optimized with Prisma
This is a production template. Customize as needed:
- Add email notifications
- Implement chat system
- Add image upload to Cloudinary
- Create mobile app with React Native
MIT License - Feel free to use for your projects!
- Next.js team for App Router
- Auth.js for authentication
- Prisma for database toolkit
- Stripe for payment processing
- Shadcn for UI components
For issues or questions:
- Check the inline code comments
- Review this README
- Consult official documentation linked above
Built with ❤️ for the plant community 🌿