Public Access
1
0

feat: launch Stripe billing flows with lifecycle hardening and analytics

add Stripe checkout, portal, webhook ingestion, and idempotent event persistence

add billing lifecycle state (grace/sync/timeline/admin visibility) and stronger entitlement handling

add analytics event tracking and admin summary APIs plus account/pricing UI integration
This commit is contained in:
pguerrerox
2026-05-22 22:55:04 +00:00
parent 94b8c357b4
commit 5508e15da1
35 changed files with 2851 additions and 50 deletions
+27
View File
@@ -26,6 +26,19 @@ const envSchema = z.object({
GOOGLE_MAPS_SERVER_KEY: z.string().optional(),
PG_BOSS_SCHEMA: z.string().default('pgboss'),
SESSION_TTL_DAYS: z.coerce.number().int().positive().default(30),
STRIPE_SECRET_KEY: z.string().optional(),
STRIPE_PUBLISHABLE_KEY: z.string().optional(),
STRIPE_WEBHOOK_SECRET: z.string().optional(),
STRIPE_PRICE_STARTER_MONTHLY: z.string().optional(),
STRIPE_PRICE_STARTER_ANNUAL: z.string().optional(),
STRIPE_PRICE_GROWTH_MONTHLY: z.string().optional(),
STRIPE_PRICE_GROWTH_ANNUAL: z.string().optional(),
STRIPE_PRICE_PRO_MONTHLY: z.string().optional(),
STRIPE_PRICE_PRO_ANNUAL: z.string().optional(),
STRIPE_PRICE_EXPORT_PACK_10K: z.string().optional(),
STRIPE_PRICE_EXPORT_PACK_50K: z.string().optional(),
STRIPE_BILLING_PORTAL_CONFIGURATION_ID: z.string().optional(),
BILLING_ADMIN_EMAILS: z.string().optional(),
});
export type AppEnv = z.infer<typeof envSchema>;
@@ -40,3 +53,17 @@ export function getEnv(): AppEnv {
cachedEnv = envSchema.parse(process.env);
return cachedEnv;
}
export function isBillingAdminEmail(email: string) {
const allowlist = getEnv().BILLING_ADMIN_EMAILS;
if (!allowlist) {
return false;
}
return allowlist
.split(',')
.map((entry) => entry.trim().toLowerCase())
.filter(Boolean)
.includes(email.trim().toLowerCase());
}