A comprehensive web application for U.S. businesses and accountants to discover, reserve, purchase, and track transferable tax credits (ITC, PTC, 45Q, 48C, 48E).
- Role-Based Access Control: Three roles (Company, Accountant, Admin) with distinct permissions
- Tax Credit Marketplace: Browse and filter available tax credits with transparent pricing
- Reserve & Purchase: 72-hour holds or immediate purchase via Stripe Checkout
- Compliance Workflow: Document upload and KYC tracking
- Broker Management: Admin approval workflow with PDF generation
- Email Notifications: Automated emails for holds, payments, and approvals
- Audit Logging: Track all system changes
- CSV Exports: Export inventory and purchase data
- Frontend: Next.js 14 (App Router), React, TypeScript, Tailwind CSS
- Backend: Next.js API Routes, NextAuth.js
- Database: PostgreSQL with Prisma ORM
- Payments: Stripe Checkout
- Email: Resend
- PDFs: @react-pdf/renderer
- Node.js 18+ and npm
- PostgreSQL database (Replit DB or Supabase)
- Stripe account (test mode for development)
- Resend account (optional for email)
Create a .env.local file in the root directory with the following variables:
# Database (provided by Replit or configure Supabase)
DATABASE_URL=postgresql://user:password@host:port/database
# NextAuth
NEXTAUTH_SECRET=your-nextauth-secret-here
NEXTAUTH_URL=http://localhost:5000
# Stripe
STRIPE_SECRET_KEY=sk_test_your_stripe_secret_key
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret
STRIPE_PRICE_FEE_PERCENT=0.02
STRIPE_FEE_FLAT_USD=499
# Email (Resend)
RESEND_API_KEY=re_your_resend_api_key
FROM_EMAIL=noreply@suverse.io
# Admin Credentials
ADMIN_EMAIL=admin@suverse.io
ADMIN_PASSWORD=ChangeMe_2025npm install# Push Prisma schema to database
npm run db:push
# Seed database with demo data and admin user
npm run db:seedThis creates:
- Admin user:
admin@suverse.io/ChangeMe_2025 - 5 demo tax credit inventory items
npm run devOpen http://localhost:5000 in your browser.
- Email: admin@suverse.io
- Password: ChangeMe_2025 (configured in .env.local)
- Access: Full system access, inventory management, purchase approval
- Register at
/registerwith role "Company (Buyer)" - Provide company details (legal name, EIN, state, etc.)
- Access: Browse marketplace, reserve/purchase credits, view own purchases
- Register at
/registerwith role "Accountant" - Access: Invite clients, view client purchases, browse marketplace
- Register/Login → Company provides business details
- Browse Marketplace → Filter by credit type, tax year, price
- Reserve or Purchase:
- Reserve: Creates 72-hour hold, reduces available inventory
- Purchase: Redirects to Stripe Checkout
- Payment → Stripe processes payment, webhook updates status
- Broker Review → Admin approves/rejects purchase
- Certificate → Closing certificate PDF generated and emailed
- Manage Inventory → Add/edit tax credit lots
- Review Purchases → Approve or reject paid orders
- Generate Certificates → System auto-generates PDFs on approval
- Export Data → Download CSV reports
- Invite Clients → Send email invitations to companies
- View Client Purchases → Monitor client orders and status
- Download Certificates → Access client closing certificates
POST /api/auth/register- User registrationPOST /api/auth/[nextauth]- NextAuth login
GET /api/inventory- List available credits (with filters)POST /api/holds- Create 72-hour holdPOST /api/checkout- Create Stripe checkout sessionGET /api/purchases- List company purchases
POST /api/admin/inventory- Add inventoryGET /api/admin/inventory- List all inventoryPOST /api/admin/purchases/[id]/broker-status- Update broker statusGET /api/admin/export/inventory- Export inventory CSVGET /api/admin/export/purchases- Export purchases CSV
POST /api/webhooks/stripe- Stripe payment webhook
- Push to GitHub:
git init
git add .
git commit -m "Initial commit"
git remote add origin <your-repo-url>
git push -u origin main-
Deploy to Vercel:
- Import project from GitHub
- Add all environment variables from
.env.local - Update
NEXTAUTH_URLto your Vercel URL - Deploy
-
Configure Stripe Webhook:
- Go to Stripe Dashboard → Webhooks
- Add endpoint:
https://your-app.vercel.app/api/webhooks/stripe - Select event:
checkout.session.completed - Copy webhook secret to
STRIPE_WEBHOOK_SECRET
- PostgreSQL Database: Set
DATABASE_URL - NextAuth: Set
NEXTAUTH_SECRETandNEXTAUTH_URL - Stripe:
- Set
STRIPE_SECRET_KEY(test key:sk_test_...) - Set
STRIPE_WEBHOOK_SECRETafter configuring webhook
- Set
- Email (Optional): Set
RESEND_API_KEYfor email notifications - Admin Password: Set
ADMIN_PASSWORDin .env
- Create Stripe account at stripe.com
- Get test API key from Dashboard → Developers → API keys
- Use test card:
4242 4242 4242 4242, any future expiry, any CVC
- Create account at resend.com
- Get API key from Dashboard
- If not configured, emails will be logged to console
-
Register Company:
- Go to
/register - Select "Company (Buyer)"
- Fill in company details
- Create account
- Go to
-
Browse & Purchase:
- Login and go to
/marketplace - Select a credit (e.g., ITC 2024)
- Click "Purchase Now"
- Complete Stripe checkout with test card:
4242 4242 4242 4242
- Login and go to
-
Admin Approval:
- Login as admin (
admin@suverse.io) - Go to Admin → Purchase Orders
- Review paid order
- Approve purchase
- Login as admin (
-
Verify Certificate:
- Check company email for closing certificate
- Download PDF from purchases page
├── app/
│ ├── api/ # API routes
│ ├── admin/ # Admin pages
│ ├── checkout/ # Checkout success/cancel
│ ├── dashboard/ # Main dashboard
│ ├── login/ # Login page
│ ├── marketplace/ # Marketplace page
│ ├── purchases/ # Purchase history
│ └── register/ # Registration
├── components/ # Reusable UI components
├── lib/ # Utilities (auth, db, email, pdf)
├── prisma/ # Database schema and migrations
│ ├── schema.prisma
│ └── seed.ts
└── types/ # TypeScript type definitions
Key models:
- User: Authentication and role management
- Company: Business entity details
- CreditInventory: Available tax credits
- Hold: 72-hour reservations
- PurchaseOrder: Purchase transactions
- Document: Uploaded compliance files
- AuditLog: System activity tracking
- Password hashing with bcrypt
- NextAuth session management
- Role-based access control (RBAC)
- Stripe webhook signature verification
- Input validation with Zod
- SQL injection prevention via Prisma
"Invalid credentials" on login
- Ensure database is seeded:
npm run db:seed - Check admin credentials match
.env.local
Stripe checkout fails
- Verify
STRIPE_SECRET_KEYis set - Use test card in test mode
- Check console for errors
Emails not sending
- Set
RESEND_API_KEYin .env - Emails log to console if not configured
Database connection error
- Verify
DATABASE_URLis correct - Run
npm run db:pushto sync schema
MIT
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open Pull Request
Built with ❤️ for the tax credit marketplace