search console SEO ableitungen

This commit is contained in:
2026-03-23 19:01:52 -05:00
parent d47108d27c
commit e6b19e7a1c
150 changed files with 26257 additions and 25909 deletions

View File

@@ -1,80 +1,80 @@
import Stripe from 'stripe';
// Use a placeholder during build time, real key at runtime
const stripeKey = process.env.STRIPE_SECRET_KEY || 'sk_test_placeholder_for_build';
export const stripe = new Stripe(stripeKey, {
apiVersion: '2025-10-29.clover',
typescript: true,
});
// Runtime validation (will throw when actually used in production if not set)
export function validateStripeKey() {
if (!process.env.STRIPE_SECRET_KEY) {
throw new Error('STRIPE_SECRET_KEY is not set');
}
}
export const STRIPE_PLANS = {
FREE: {
name: 'Free / Starter',
price: 0,
currency: 'EUR',
interval: 'month',
features: [
'3 dynamische QR-Codes',
'Basis-Tracking (Scans + Standort)',
'Einfache Designs',
'Unbegrenzte statische QR-Codes',
],
limits: {
dynamicQRCodes: 3,
staticQRCodes: -1, // unlimited
teamMembers: 1,
},
priceId: null, // No Stripe price for free plan
},
PRO: {
name: 'Pro',
price: 9,
priceYearly: 90,
currency: 'EUR',
interval: 'month',
features: [
'50 QR Codes',
'Branding (Colors)',
'Detailed Analytics (Date, Device, City)',
'CSV Export',
'SVG/PNG Download',
],
limits: {
dynamicQRCodes: 50,
staticQRCodes: -1,
teamMembers: 1,
},
priceId: process.env.STRIPE_PRICE_ID_PRO_MONTHLY,
priceIdYearly: process.env.STRIPE_PRICE_ID_PRO_YEARLY,
},
BUSINESS: {
name: 'Business',
price: 29,
priceYearly: 290,
currency: 'EUR',
interval: 'month',
features: [
'500 QR-Codes',
'Everything from Pro',
'Bulk QR Generation (up to 1,000)',
'Priority Support',
],
limits: {
dynamicQRCodes: 500,
staticQRCodes: -1,
teamMembers: 1,
},
priceId: process.env.STRIPE_PRICE_ID_BUSINESS_MONTHLY,
priceIdYearly: process.env.STRIPE_PRICE_ID_BUSINESS_YEARLY,
},
} as const;
export type PlanType = keyof typeof STRIPE_PLANS;
import Stripe from 'stripe';
// Use a placeholder during build time, real key at runtime
const stripeKey = process.env.STRIPE_SECRET_KEY || 'sk_test_placeholder_for_build';
export const stripe = new Stripe(stripeKey, {
apiVersion: '2025-10-29.clover',
typescript: true,
});
// Runtime validation (will throw when actually used in production if not set)
export function validateStripeKey() {
if (!process.env.STRIPE_SECRET_KEY) {
throw new Error('STRIPE_SECRET_KEY is not set');
}
}
export const STRIPE_PLANS = {
FREE: {
name: 'Free / Starter',
price: 0,
currency: 'EUR',
interval: 'month',
features: [
'3 dynamische QR-Codes',
'Basis-Tracking (Scans + Standort)',
'Einfache Designs',
'Unbegrenzte statische QR-Codes',
],
limits: {
dynamicQRCodes: 3,
staticQRCodes: -1, // unlimited
teamMembers: 1,
},
priceId: null, // No Stripe price for free plan
},
PRO: {
name: 'Pro',
price: 9,
priceYearly: 90,
currency: 'EUR',
interval: 'month',
features: [
'50 QR Codes',
'Branding (Colors)',
'Detailed Analytics (Date, Device, City)',
'CSV Export',
'SVG/PNG Download',
],
limits: {
dynamicQRCodes: 50,
staticQRCodes: -1,
teamMembers: 1,
},
priceId: process.env.STRIPE_PRICE_ID_PRO_MONTHLY,
priceIdYearly: process.env.STRIPE_PRICE_ID_PRO_YEARLY,
},
BUSINESS: {
name: 'Business',
price: 29,
priceYearly: 290,
currency: 'EUR',
interval: 'month',
features: [
'500 QR-Codes',
'Everything from Pro',
'Bulk QR Generation (up to 1,000)',
'Priority Support',
],
limits: {
dynamicQRCodes: 500,
staticQRCodes: -1,
teamMembers: 1,
},
priceId: process.env.STRIPE_PRICE_ID_BUSINESS_MONTHLY,
priceIdYearly: process.env.STRIPE_PRICE_ID_BUSINESS_YEARLY,
},
} as const;
export type PlanType = keyof typeof STRIPE_PLANS;