- Replace 8 placeholder price IDs (price_starter_monthly, etc.) with real Stripe test-mode price IDs created via API - Add STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, NEXT_PUBLIC_BILLING_PROVIDER, and NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY to docker-compose.yml (build args + runtime) - Add NEXT_PUBLIC_BILLING_PROVIDER ARG/ENV to Dockerfile - Enable team and personal account billing (was 'false') - Created Stripe webhook endpoint for production URL - Created 4 Stripe products (Starter/Pro/Verband/Enterprise) with monthly+yearly prices Checkout was crashing because: 1. STRIPE_SECRET_KEY was missing → Zod validation failed at createStripeClient() 2. STRIPE_WEBHOOK_SECRET was missing → same Zod schema rejection 3. NEXT_PUBLIC_BILLING_PROVIDER was unset → BillingProviderSchema.parse() failed 4. Price IDs were placeholders, not real Stripe price_xxx IDs
217 lines
6.1 KiB
TypeScript
217 lines
6.1 KiB
TypeScript
/**
|
|
* MyEasyCMS Billing Configuration
|
|
*
|
|
* Four tiers based on club/organization size:
|
|
* Starter — 29 €/mo (up to 250 members)
|
|
* Pro — 59 €/mo (up to 1.000 members)
|
|
* Verband — 199 €/mo (up to 10.000 members, multi-level hierarchy)
|
|
* Enterprise — 349 €/mo (unlimited, dedicated support)
|
|
*
|
|
* Yearly plans get ~2 months free (billed annually).
|
|
*/
|
|
import { BillingProviderSchema, createBillingSchema } from '@kit/billing';
|
|
|
|
const provider = BillingProviderSchema.parse(
|
|
process.env.NEXT_PUBLIC_BILLING_PROVIDER,
|
|
);
|
|
|
|
export default createBillingSchema({
|
|
provider,
|
|
products: [
|
|
// ── Starter ──────────────────────────────────────────────
|
|
{
|
|
id: 'starter',
|
|
name: 'Starter',
|
|
description: 'Für kleine Vereine bis 250 Mitglieder',
|
|
currency: 'EUR',
|
|
badge: 'Einstieg',
|
|
plans: [
|
|
{
|
|
name: 'Starter Monatlich',
|
|
id: 'starter-monthly',
|
|
paymentType: 'recurring',
|
|
interval: 'month',
|
|
lineItems: [
|
|
{
|
|
id: 'price_1THsqKKttnWb7SsFttMu9VzG',
|
|
name: 'Starter',
|
|
cost: 29,
|
|
type: 'flat' as const,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'Starter Jährlich',
|
|
id: 'starter-yearly',
|
|
paymentType: 'recurring',
|
|
interval: 'year',
|
|
lineItems: [
|
|
{
|
|
id: 'price_1THsqLKttnWb7SsFgvjsKXzs',
|
|
name: 'Starter',
|
|
cost: 290,
|
|
type: 'flat' as const,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
features: [
|
|
'Bis zu 250 Mitglieder',
|
|
'Mitgliederverwaltung',
|
|
'SEPA-Lastschrifteinzug',
|
|
'Veranstaltungsmanagement',
|
|
'Vereins-Website (Baukasten)',
|
|
'Newsletter-Versand',
|
|
'Dokumenten-Generator',
|
|
'E-Mail-Support',
|
|
],
|
|
},
|
|
// ── Pro ───────────────────────────────────────────────────
|
|
{
|
|
id: 'pro',
|
|
name: 'Pro',
|
|
badge: 'Beliebt',
|
|
highlighted: true,
|
|
description: 'Für aktive Vereine bis 1.000 Mitglieder',
|
|
currency: 'EUR',
|
|
plans: [
|
|
{
|
|
name: 'Pro Monatlich',
|
|
id: 'pro-monthly',
|
|
paymentType: 'recurring',
|
|
interval: 'month',
|
|
lineItems: [
|
|
{
|
|
id: 'price_1THsqLKttnWb7SsFlWPf5IdP',
|
|
name: 'Pro',
|
|
cost: 59,
|
|
type: 'flat' as const,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'Pro Jährlich',
|
|
id: 'pro-yearly',
|
|
paymentType: 'recurring',
|
|
interval: 'year',
|
|
lineItems: [
|
|
{
|
|
id: 'price_1THsqMKttnWb7SsFZq3A4QkU',
|
|
name: 'Pro',
|
|
cost: 590,
|
|
type: 'flat' as const,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
features: [
|
|
'Bis zu 1.000 Mitglieder',
|
|
'Alles aus Starter',
|
|
'Kursverwaltung (VHS-Modus)',
|
|
'Buchungssystem (Räume & Gäste)',
|
|
'Rechnungswesen & Mahnungen',
|
|
'Unbegrenzte Benutzer',
|
|
'Benutzerdefinierte Module',
|
|
'Telefon-Support',
|
|
],
|
|
},
|
|
// ── Verband ──────────────────────────────────────────────
|
|
{
|
|
id: 'verband',
|
|
name: 'Verband',
|
|
badge: 'Verbände',
|
|
description: 'Für Verbände und Dachorganisationen',
|
|
currency: 'EUR',
|
|
plans: [
|
|
{
|
|
name: 'Verband Monatlich',
|
|
id: 'verband-monthly',
|
|
paymentType: 'recurring',
|
|
interval: 'month',
|
|
lineItems: [
|
|
{
|
|
id: 'price_1THsqNKttnWb7SsFGv7YskgJ',
|
|
name: 'Verband',
|
|
cost: 199,
|
|
type: 'flat' as const,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'Verband Jährlich',
|
|
id: 'verband-yearly',
|
|
paymentType: 'recurring',
|
|
interval: 'year',
|
|
lineItems: [
|
|
{
|
|
id: 'price_1THsqNKttnWb7SsFhNl2bVn8',
|
|
name: 'Verband',
|
|
cost: 1990,
|
|
type: 'flat' as const,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
features: [
|
|
'Bis zu 10.000 Mitglieder',
|
|
'Alles aus Pro',
|
|
'Mehrebenen-Verbandshierarchie',
|
|
'Verbandsweite Mitgliedersuche',
|
|
'Geteilte Vorlagen & Events',
|
|
'Verbands-Berichtswesen',
|
|
'Fischerei-Modul (optional)',
|
|
'Sitzungsprotokolle (optional)',
|
|
'Prioritäts-Support',
|
|
],
|
|
},
|
|
// ── Enterprise ───────────────────────────────────────────
|
|
{
|
|
id: 'enterprise',
|
|
name: 'Enterprise',
|
|
description: 'Für große Organisationen mit individuellen Anforderungen',
|
|
currency: 'EUR',
|
|
plans: [
|
|
{
|
|
name: 'Enterprise Monatlich',
|
|
id: 'enterprise-monthly',
|
|
paymentType: 'recurring',
|
|
interval: 'month',
|
|
lineItems: [
|
|
{
|
|
id: 'price_1THsqOKttnWb7SsFlLjfLw72',
|
|
name: 'Enterprise',
|
|
cost: 349,
|
|
type: 'flat' as const,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'Enterprise Jährlich',
|
|
id: 'enterprise-yearly',
|
|
paymentType: 'recurring',
|
|
interval: 'year',
|
|
lineItems: [
|
|
{
|
|
id: 'price_1THsqOKttnWb7SsF8Sr12isW',
|
|
name: 'Enterprise',
|
|
cost: 3490,
|
|
type: 'flat' as const,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
features: [
|
|
'Unbegrenzte Mitglieder',
|
|
'Alles aus Verband',
|
|
'Dedizierte Infrastruktur',
|
|
'Individuelle Modulentwicklung',
|
|
'SLA & Uptime-Garantie',
|
|
'Persönlicher Account-Manager',
|
|
'Onboarding & Schulung',
|
|
'API-Zugang',
|
|
'Datenmigration inklusive',
|
|
],
|
|
},
|
|
],
|
|
});
|