From 2e660391ce3c091e644512fb520c76b01dbdd166 Mon Sep 17 00:00:00 2001 From: Till-JS <101404291+Till-JS@users.noreply.github.com> Date: Mon, 16 Feb 2026 11:43:04 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=B3=20feat(stripe):=20add=20ManaCore?= =?UTF-8?q?=20unified=20subscription=20plans?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create Plus/Pro/Ultra subscription tiers with Stripe products & prices - Add credit packs (100/500/1000) for one-time purchases - Update seed script with new plan structure and Stripe IDs - Configure webhook secret and customer portal - Add all Stripe environment variables to .env.development Plans: - Free: 50 credits/month (default) - Plus: 100 credits/month @ €4.99/mo or €49.99/yr - Pro: 500 credits/month @ €11.99/mo or €119.99/yr - Ultra: 2000 credits/month @ €24.99/mo or €249.99/yr Co-Authored-By: Claude Opus 4.5 --- .env.development | 32 +++- .../src/db/seeds/seed-subscription-plans.ts | 138 ++++++++++-------- 2 files changed, 109 insertions(+), 61 deletions(-) diff --git a/.env.development b/.env.development index 7fa9aa104..c4d3c7aef 100644 --- a/.env.development +++ b/.env.development @@ -54,10 +54,38 @@ CREDITS_DAILY_FREE=5 RATE_LIMIT_TTL=60 RATE_LIMIT_MAX=100 -# Stripe (test keys - get your own from Stripe dashboard) +# Stripe Configuration +# Get your keys from https://dashboard.stripe.com/apikeys STRIPE_SECRET_KEY=sk_test_YOUR_KEY STRIPE_PUBLISHABLE_KEY=pk_test_YOUR_KEY -STRIPE_WEBHOOK_SECRET=whsec_YOUR_SECRET +STRIPE_WEBHOOK_SECRET=whsec_103705b73101b783a91305a9ec272834df6a096ffb2c2566b1c899318a156b03 + +# Stripe Product & Price IDs (ManaCore Unified Plans - Live) +# Plus: 4.99€/month, 49.99€/year - 100 credits +STRIPE_PLUS_PRODUCT_ID=prod_TzNUGcq9qx9rRT +STRIPE_PLUS_PRICE_MONTHLY=price_1T1OkKAZjQCYS0ZJ88m0shoN +STRIPE_PLUS_PRICE_YEARLY=price_1T1OkLAZjQCYS0ZJ4IdMzVyJ + +# Pro: 11.99€/month, 119.99€/year - 500 credits +STRIPE_PRO_PRODUCT_ID=prod_TzNUgWeBjT35qn +STRIPE_PRO_PRICE_MONTHLY=price_1T1OkLAZjQCYS0ZJvyPM7Wop +STRIPE_PRO_PRICE_YEARLY=price_1T1OkLAZjQCYS0ZJDbZeuOOu + +# Ultra: 24.99€/month, 249.99€/year - 2000 credits +STRIPE_ULTRA_PRODUCT_ID=prod_TzNUE5pTbTDdbp +STRIPE_ULTRA_PRICE_MONTHLY=price_1T1OkMAZjQCYS0ZJYCJNZtg8 +STRIPE_ULTRA_PRICE_YEARLY=price_1T1OkMAZjQCYS0ZJvCvR6Ve6 + +# Credit Packs (One-time purchases) +STRIPE_CREDITS_100_PRODUCT_ID=prod_TzNUvyjD4hrcUR +STRIPE_CREDITS_100_PRICE=price_1T1OkNAZjQCYS0ZJP6XQ33F7 +STRIPE_CREDITS_500_PRODUCT_ID=prod_TzNUzzub5HM70Q +STRIPE_CREDITS_500_PRICE=price_1T1OkNAZjQCYS0ZJGH9TKmqa +STRIPE_CREDITS_1000_PRODUCT_ID=prod_TzNUvB4LT4PCCe +STRIPE_CREDITS_1000_PRICE=price_1T1OkNAZjQCYS0ZJvc6HTfB5 + +# Customer Portal Configuration +STRIPE_PORTAL_CONFIG_ID=bpc_1T1PFdAZjQCYS0ZJEhF9ob7q # ============================================ # CHAT PROJECT diff --git a/services/mana-core-auth/src/db/seeds/seed-subscription-plans.ts b/services/mana-core-auth/src/db/seeds/seed-subscription-plans.ts index 5370bd95c..6e28f0cbf 100644 --- a/services/mana-core-auth/src/db/seeds/seed-subscription-plans.ts +++ b/services/mana-core-auth/src/db/seeds/seed-subscription-plans.ts @@ -8,13 +8,13 @@ * pnpm db:seed:plans * * Prerequisites: - * 1. Create products and prices in Stripe Dashboard + * 1. Stripe products and prices are already created via MCP * 2. Set STRIPE_* environment variables with the price IDs * - * Stripe Products to create: - * - Mana Free (price: 0 EUR) - * - Mana Pro (prices: 9.99 EUR/month, 99 EUR/year) - * - Mana Enterprise (contact sales) + * Stripe Products (Live): + * - ManaCore Plus: prod_TzNUGcq9qx9rRT (4.99€/month, 49.99€/year, 100 credits) + * - ManaCore Pro: prod_TzNUgWeBjT35qn (11.99€/month, 119.99€/year, 500 credits) + * - ManaCore Ultra: prod_TzNUE5pTbTDdbp (24.99€/month, 249.99€/year, 2000 credits) */ import 'dotenv/config'; @@ -27,20 +27,25 @@ import { plans } from '../schema/subscriptions.schema'; const DATABASE_URL = process.env.DATABASE_URL || 'postgresql://manacore:manacore@localhost:5432/manacore_auth'; -// Stripe Price IDs from environment (or defaults for development) +// Stripe Price IDs from environment (with production defaults) const STRIPE_CONFIG = { // Free plan (no Stripe price needed) FREE_PRODUCT_ID: process.env.STRIPE_FREE_PRODUCT_ID || '', - // Pro plan - PRO_PRODUCT_ID: process.env.STRIPE_PRO_PRODUCT_ID || '', - PRO_PRICE_MONTHLY: process.env.STRIPE_PRO_PRICE_MONTHLY || '', // e.g., price_xxx - PRO_PRICE_YEARLY: process.env.STRIPE_PRO_PRICE_YEARLY || '', // e.g., price_xxx + // ManaCore Plus plan + PLUS_PRODUCT_ID: process.env.STRIPE_PLUS_PRODUCT_ID || 'prod_TzNUGcq9qx9rRT', + PLUS_PRICE_MONTHLY: process.env.STRIPE_PLUS_PRICE_MONTHLY || 'price_1T1OkKAZjQCYS0ZJ88m0shoN', + PLUS_PRICE_YEARLY: process.env.STRIPE_PLUS_PRICE_YEARLY || 'price_1T1OkLAZjQCYS0ZJ4IdMzVyJ', - // Enterprise plan - ENTERPRISE_PRODUCT_ID: process.env.STRIPE_ENTERPRISE_PRODUCT_ID || '', - ENTERPRISE_PRICE_MONTHLY: process.env.STRIPE_ENTERPRISE_PRICE_MONTHLY || '', - ENTERPRISE_PRICE_YEARLY: process.env.STRIPE_ENTERPRISE_PRICE_YEARLY || '', + // ManaCore Pro plan + PRO_PRODUCT_ID: process.env.STRIPE_PRO_PRODUCT_ID || 'prod_TzNUgWeBjT35qn', + PRO_PRICE_MONTHLY: process.env.STRIPE_PRO_PRICE_MONTHLY || 'price_1T1OkLAZjQCYS0ZJvyPM7Wop', + PRO_PRICE_YEARLY: process.env.STRIPE_PRO_PRICE_YEARLY || 'price_1T1OkLAZjQCYS0ZJDbZeuOOu', + + // ManaCore Ultra plan + ULTRA_PRODUCT_ID: process.env.STRIPE_ULTRA_PRODUCT_ID || 'prod_TzNUE5pTbTDdbp', + ULTRA_PRICE_MONTHLY: process.env.STRIPE_ULTRA_PRICE_MONTHLY || 'price_1T1OkMAZjQCYS0ZJYCJNZtg8', + ULTRA_PRICE_YEARLY: process.env.STRIPE_ULTRA_PRICE_YEARLY || 'price_1T1OkMAZjQCYS0ZJvCvR6Ve6', }; // Plan definitions @@ -48,17 +53,17 @@ const PLANS = [ { name: 'Free', description: 'Kostenlos starten mit grundlegenden Features', - monthlyCredits: 150, + monthlyCredits: 50, priceMonthlyEuroCents: 0, priceYearlyEuroCents: 0, stripePriceIdMonthly: null, stripePriceIdYearly: null, stripeProductId: STRIPE_CONFIG.FREE_PRODUCT_ID || null, features: [ - '150 Credits pro Monat', - '5 tägliche Gratis-Credits', + '50 Credits pro Monat', + '3 tägliche Gratis-Credits', 'Zugang zu allen Apps', - 'Basis-Support', + 'Community-Support', ], maxTeamMembers: null, maxOrganizations: null, @@ -67,50 +72,70 @@ const PLANS = [ sortOrder: 0, }, { - name: 'Pro', - description: 'Für Power-User mit mehr Credits und Features', - monthlyCredits: 2000, - priceMonthlyEuroCents: 999, // 9.99 EUR - priceYearlyEuroCents: 9900, // 99 EUR (2 months free) - stripePriceIdMonthly: STRIPE_CONFIG.PRO_PRICE_MONTHLY || null, - stripePriceIdYearly: STRIPE_CONFIG.PRO_PRICE_YEARLY || null, - stripeProductId: STRIPE_CONFIG.PRO_PRODUCT_ID || null, + name: 'Plus', + description: 'Basis-Zugang zu allen ManaCore Apps mit AI-Credits', + monthlyCredits: 100, + priceMonthlyEuroCents: 499, // 4.99 EUR + priceYearlyEuroCents: 4999, // 49.99 EUR (~2 months free) + stripePriceIdMonthly: STRIPE_CONFIG.PLUS_PRICE_MONTHLY || null, + stripePriceIdYearly: STRIPE_CONFIG.PLUS_PRICE_YEARLY || null, + stripeProductId: STRIPE_CONFIG.PLUS_PRODUCT_ID || null, features: [ - '2.000 Credits pro Monat', - '20 tägliche Gratis-Credits', - 'Prioritäts-Support', - 'Erweiterte AI-Modelle', - 'API-Zugang', + '100 AI-Credits pro Monat', + 'Zugang zu allen Apps', + 'Chat & Bildgenerierung', + 'E-Mail Support', ], - maxTeamMembers: 5, - maxOrganizations: 3, + maxTeamMembers: 1, + maxOrganizations: 1, isDefault: false, isEnterprise: false, sortOrder: 1, }, { - name: 'Enterprise', - description: 'Für Teams und Unternehmen mit individuellen Anforderungen', - monthlyCredits: 10000, - priceMonthlyEuroCents: 4900, // 49 EUR - priceYearlyEuroCents: 49000, // 490 EUR (2 months free) - stripePriceIdMonthly: STRIPE_CONFIG.ENTERPRISE_PRICE_MONTHLY || null, - stripePriceIdYearly: STRIPE_CONFIG.ENTERPRISE_PRICE_YEARLY || null, - stripeProductId: STRIPE_CONFIG.ENTERPRISE_PRODUCT_ID || null, + name: 'Pro', + description: 'Erweiterter Zugang mit Premium-Modellen und Priority-Support', + monthlyCredits: 500, + priceMonthlyEuroCents: 1199, // 11.99 EUR + priceYearlyEuroCents: 11999, // 119.99 EUR (~2 months free) + stripePriceIdMonthly: STRIPE_CONFIG.PRO_PRICE_MONTHLY || null, + stripePriceIdYearly: STRIPE_CONFIG.PRO_PRICE_YEARLY || null, + stripeProductId: STRIPE_CONFIG.PRO_PRODUCT_ID || null, features: [ - '10.000 Credits pro Monat', - 'Unbegrenzte tägliche Credits', - 'Dedizierter Account Manager', - 'SLA-garantierte Verfügbarkeit', - 'Custom AI-Modelle', - 'SSO / SAML Integration', - 'Admin-Dashboard', + '500 AI-Credits pro Monat', + 'Premium AI-Modelle (GPT-4, Claude)', + 'Priority-Support', + 'API-Zugang', + 'Erweiterte Exportoptionen', + ], + maxTeamMembers: 5, + maxOrganizations: 3, + isDefault: false, + isEnterprise: false, + sortOrder: 2, + }, + { + name: 'Ultra', + description: 'Maximale Power für Power-User und Teams', + monthlyCredits: 2000, + priceMonthlyEuroCents: 2499, // 24.99 EUR + priceYearlyEuroCents: 24999, // 249.99 EUR (~2 months free) + stripePriceIdMonthly: STRIPE_CONFIG.ULTRA_PRICE_MONTHLY || null, + stripePriceIdYearly: STRIPE_CONFIG.ULTRA_PRICE_YEARLY || null, + stripeProductId: STRIPE_CONFIG.ULTRA_PRODUCT_ID || null, + features: [ + '2.000 AI-Credits pro Monat', + 'Alle Premium AI-Modelle', + 'Dedizierter Support', + 'Unlimitierte API-Calls', + 'Team-Features', + 'Custom Integrationen', ], maxTeamMembers: null, // Unlimited maxOrganizations: null, // Unlimited isDefault: false, isEnterprise: true, - sortOrder: 2, + sortOrder: 3, }, ]; @@ -162,16 +187,11 @@ async function seedPlans() { console.log('\n✅ Subscription plans seeded successfully!'); - if (!STRIPE_CONFIG.PRO_PRICE_MONTHLY || !STRIPE_CONFIG.PRO_PRICE_YEARLY) { - console.log('\n⚠️ Warning: Stripe Price IDs not configured.'); - console.log(' Set these environment variables:'); - console.log(' - STRIPE_PRO_PRODUCT_ID'); - console.log(' - STRIPE_PRO_PRICE_MONTHLY'); - console.log(' - STRIPE_PRO_PRICE_YEARLY'); - console.log(' - STRIPE_ENTERPRISE_PRODUCT_ID'); - console.log(' - STRIPE_ENTERPRISE_PRICE_MONTHLY'); - console.log(' - STRIPE_ENTERPRISE_PRICE_YEARLY'); - } + // Info about configured Stripe products + console.log('\n📦 Stripe Products configured:'); + console.log(' Plus: ', STRIPE_CONFIG.PLUS_PRODUCT_ID || '(not set)'); + console.log(' Pro: ', STRIPE_CONFIG.PRO_PRODUCT_ID || '(not set)'); + console.log(' Ultra: ', STRIPE_CONFIG.ULTRA_PRODUCT_ID || '(not set)'); } catch (error) { console.error('Error seeding plans:', error); process.exit(1);