Document external DashCaddy billing architecture

This commit is contained in:
Krystie
2026-04-17 21:29:01 -07:00
parent f5104578c9
commit aedaf4b4b5
4 changed files with 137 additions and 164 deletions

View File

@@ -1,16 +1,7 @@
# Stripe Configuration # DashCaddy website configuration
# Get your keys from https://dashboard.stripe.com/apikeys
STRIPE_SECRET_KEY=sk_test_your_secret_key_here
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_your_publishable_key_here
# Stripe Webhook Secret
# Get this from https://dashboard.stripe.com/webhooks after creating an endpoint
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret_here
# Stripe Price IDs
# Create these in your Stripe Dashboard under Products > Pricing
STRIPE_PRICE_MONTHLY=price_your_monthly_price_id
STRIPE_PRICE_YEARLY=price_your_yearly_price_id
# App URL
NEXT_PUBLIC_APP_URL=https://dashcaddy.net NEXT_PUBLIC_APP_URL=https://dashcaddy.net
NEXT_PUBLIC_LICENSE_SERVER_URL=https://licenses.dashcaddy.net
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_your_publishable_key_here
# The website no longer owns Stripe secret or webhook handling.
# Stripe Checkout sessions and webhook processing live in dashcaddy-license-server.

View File

@@ -12,7 +12,7 @@
| `CLAUDE.md` | Project instructions for Claude | | `CLAUDE.md` | Project instructions for Claude |
| `FILELIST.md` | This file | | `FILELIST.md` | This file |
| `README.md` | Project overview and setup guide | | `README.md` | Project overview and setup guide |
| `STRIPE_SETUP.md` | Step-by-step Stripe configuration guide | | `STRIPE_SETUP.md` | Billing architecture and license-server setup guide |
| `eslint.config.mjs` | ESLint configuration | | `eslint.config.mjs` | ESLint configuration |
| `next-env.d.ts` | Next.js TypeScript declarations | | `next-env.d.ts` | Next.js TypeScript declarations |
| `next.config.ts` | Next.js configuration | | `next.config.ts` | Next.js configuration |
@@ -53,8 +53,8 @@
| File | Endpoint | Purpose | | File | Endpoint | Purpose |
|------|----------|---------| |------|----------|---------|
| `src/app/api/checkout/route.ts` | `POST /api/checkout` | Creates Stripe Checkout session with 14-day trial | | `src/app/api/checkout/route.ts` | `POST /api/checkout` | Disabled compatibility stub; production checkout lives in dashcaddy-license-server |
| `src/app/api/webhooks/stripe/route.ts` | `POST /api/webhooks/stripe` | Handles Stripe subscription lifecycle events | | `src/app/api/webhooks/stripe/route.ts` | `POST /api/webhooks/stripe` | Disabled compatibility stub; production webhook lives in dashcaddy-license-server |
## Components (`src/components/`) ## Components (`src/components/`)

126
README.md
View File

@@ -1,63 +1,63 @@
# DashCaddy.net - Marketing Website # DashCaddy.net - Marketing Website
Marketing and sales website for [DashCaddy](https://git.dashcaddy.net/sami7777/dashcaddy), the self-hosted Docker dashboard with automatic SSL, DNS, and reverse proxy configuration. Marketing and sales website for [DashCaddy](https://git.dashcaddy.net/sami7777/dashcaddy), the self-hosted Docker dashboard with automatic SSL, DNS, and reverse proxy configuration.
## Tech Stack ## Tech Stack
- **Next.js 16** with App Router and TypeScript - **Next.js 16** with App Router and TypeScript
- **Tailwind CSS** for styling - **Tailwind CSS** for styling
- **Stripe** for subscription payments ($20/mo or $99/yr) - **Stripe** for subscription payments ($20/mo or $99/yr)
## Getting Started ## Getting Started
```bash ```bash
# Install dependencies # Install dependencies
npm install npm install
# Copy environment file and configure # Copy environment file and configure
cp .env.example .env.local cp .env.example .env.local
# Run development server # Run development server
npm run dev npm run dev
``` ```
Open [http://localhost:3000](http://localhost:3000) to see the site. Open [http://localhost:3000](http://localhost:3000) to see the site.
## Pages ## Pages
| Route | Description | | Route | Description |
|-------|-------------| |-------|-------------|
| `/` | Landing page with hero, features, app showcase | | `/` | Landing page with hero, features, app showcase |
| `/features` | Detailed feature breakdown | | `/features` | Detailed feature breakdown |
| `/pricing` | Pricing plans with Stripe Checkout | | `/pricing` | Pricing plans with Stripe Checkout |
| `/docs` | Getting started guide and documentation | | `/docs` | Getting started guide and documentation |
| `/about` | About page and company info | | `/about` | About page and company info |
| `/success` | Post-checkout success page | | `/success` | Post-checkout success page |
## Stripe Integration ## Stripe Integration
See [STRIPE_SETUP.md](./STRIPE_SETUP.md) for detailed setup instructions. See [STRIPE_SETUP.md](./STRIPE_SETUP.md) for the current billing and license-server setup.
**API Routes:** **API Routes:**
- `POST /api/checkout` - Creates Stripe Checkout session - Website pricing uses the external DashCaddy license server for checkout initiation.
- `POST /api/webhooks/stripe` - Handles Stripe webhook events - Website-local Stripe routes are disabled compatibility stubs and are not the production billing path.
## Logo Setup ## Logo Setup
Place your `samiahmed7777-logo.png` file in `public/images/` for the footer copyright branding. Place your `samiahmed7777-logo.png` file in `public/images/` for the footer copyright branding.
## Deployment ## Deployment
```bash ```bash
# Build for production # Build for production
npm run build npm run build
# Start production server # Start production server
npm start npm start
``` ```
The site can be deployed to Vercel, your own server (with Node.js), or any platform that supports Next.js. The site can be deployed to Vercel, your own server (with Node.js), or any platform that supports Next.js.
## License ## License
Proprietary - DashCaddy Proprietary - DashCaddy

View File

@@ -1,83 +1,65 @@
# Stripe Setup Guide for DashCaddy.net # DashCaddy Billing Setup
## 1. Create a Stripe Account DashCaddy website no longer processes Stripe webhooks locally.
Go to [stripe.com](https://stripe.com) and create an account (or log in). Current architecture:
- `dashcaddy.net` handles pricing UI and starts checkout by calling the external license server
## 2. Create Your Product and Prices - `dashcaddy-license-server` owns Stripe secret usage, webhook handling, subscription state, and license generation
- DashCaddy app instances validate/deactivate against the external license server
In the Stripe Dashboard:
## Required website environment
1. Go to **Products** > **Add Product**
2. Name: `DashCaddy Premium` ```env
3. Description: `Premium license for DashCaddy - Self-hosting dashboard` NEXT_PUBLIC_APP_URL=https://dashcaddy.net
4. Create two prices: NEXT_PUBLIC_LICENSE_SERVER_URL=https://licenses.dashcaddy.net
- **Monthly**: $20.00 USD / month (recurring) NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_your_publishable_key_here
- **Yearly**: $99.00 USD / year (recurring) ```
5. Note down both **Price IDs** (they look like `price_1234...`)
## Required license server environment
## 3. Get Your API Keys
```env
1. Go to **Developers** > **API Keys** PORT=3010
2. Copy your **Publishable key** (`pk_test_...` or `pk_live_...`) APP_BASE_URL=https://licenses.dashcaddy.net
3. Copy your **Secret key** (`sk_test_...` or `sk_live_...`) DASHCADDY_WEBSITE_URL=https://dashcaddy.net
STRIPE_SECRET_KEY=sk_live_...
## 4. Set Up Webhooks STRIPE_PUBLISHABLE_KEY=pk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
1. Go to **Developers** > **Webhooks** ```
2. Click **Add endpoint**
3. URL: `https://dashcaddy.net/api/webhooks/stripe` ## Stripe product model
4. Select these events:
- `checkout.session.completed` One Premium tier, four subscription cadences:
- `customer.subscription.updated` - 1 month — $25
- `customer.subscription.deleted` - 3 months — $50
- `invoice.payment_failed` - 6 months — $65
5. Copy the **Webhook signing secret** (`whsec_...`) - 12 months — $99
## 5. Configure Environment Variables No free trial.
7-day grace period.
Copy `.env.example` to `.env.local` and fill in your values: Cancel at period end.
One active machine at a time.
```bash Premium features only: `sso`, `recipes`, `swarm`.
cp .env.example .env.local
``` ## Stripe webhook target
Edit `.env.local`: Configure Stripe to send events to the license server, not the website.
```env Recommended webhook endpoint:
STRIPE_SECRET_KEY=sk_live_your_actual_secret_key
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_your_actual_publishable_key ```text
STRIPE_WEBHOOK_SECRET=whsec_your_actual_webhook_secret https://licenses.dashcaddy.net/api/stripe/webhook
STRIPE_PRICE_MONTHLY=price_your_monthly_price_id ```
STRIPE_PRICE_YEARLY=price_your_yearly_price_id
NEXT_PUBLIC_APP_URL=https://dashcaddy.net Recommended events:
``` - `checkout.session.completed`
- `customer.subscription.created`
## 6. Test with Stripe CLI (Optional) - `customer.subscription.updated`
- `customer.subscription.deleted`
For local development, use Stripe CLI to forward webhooks: - `invoice.payment_failed`
```bash ## Website behavior
stripe listen --forward-to localhost:3000/api/webhooks/stripe
``` The website pricing page should start checkout via:
- `POST /api/checkout/session` on the external license server
Use test card `4242 4242 4242 4242` with any future date and any CVC.
The website-local routes under `src/app/api/checkout` and `src/app/api/webhooks/stripe` are intentionally disabled compatibility stubs and should not be used for production billing.
## 7. License Key Delivery
The webhook handler at `src/app/api/webhooks/stripe/route.ts` has TODO comments
where you need to implement:
1. **Generate license key** using the same format as DashCaddy's license-keygen
(DC-XXXXX-XXXXX-XXXXX-XXXXX-XXXXX)
2. **Store it** in a database (Stripe metadata can also hold it)
3. **Email it** to the customer (use Stripe's receipt email or a service like
SendGrid/Resend)
4. **Link it** to the Stripe subscription ID so you can manage renewals/cancellations
## Pricing Strategy Notes
- **Monthly ($20/mo)**: Positioned as the flexibility option
- **Yearly ($99/yr)**: ~$8.25/mo — 58% savings, this will be the primary seller
- **14-day free trial**: Enabled on both plans via `trial_period_days: 14`
- **Promotion codes**: Enabled via `allow_promotion_codes: true`