mirror of
https://github.com/marcogll/TaxHacker_s23.git
synced 2026-01-13 13:25:18 +00:00
feat: stripe integration
This commit is contained in:
@@ -1,12 +1,6 @@
|
||||
import { stripeClient } from "@better-auth/stripe/client"
|
||||
import { createAuthClient } from "better-auth/client"
|
||||
import { emailOTPClient } from "better-auth/client/plugins"
|
||||
|
||||
export const authClient = createAuthClient({
|
||||
plugins: [
|
||||
emailOTPClient(),
|
||||
stripeClient({
|
||||
subscription: true,
|
||||
}),
|
||||
],
|
||||
plugins: [emailOTPClient()],
|
||||
})
|
||||
|
||||
28
lib/auth.ts
28
lib/auth.ts
@@ -1,7 +1,5 @@
|
||||
import config from "@/lib/config"
|
||||
import { createUserDefaults } from "@/models/defaults"
|
||||
import { getSelfHostedUser, getUserByEmail, getUserById } from "@/models/users"
|
||||
import { stripe } from "@better-auth/stripe"
|
||||
import { User } from "@prisma/client"
|
||||
import { betterAuth } from "better-auth"
|
||||
import { prismaAdapter } from "better-auth/adapters/prisma"
|
||||
@@ -12,7 +10,6 @@ import { headers } from "next/headers"
|
||||
import { redirect } from "next/navigation"
|
||||
import { prisma } from "./db"
|
||||
import { resend, sendOTPCodeEmail } from "./email"
|
||||
import { isStripeEnabled, stripeClient } from "./stripe"
|
||||
|
||||
export type UserProfile = {
|
||||
id: string
|
||||
@@ -21,7 +18,7 @@ export type UserProfile = {
|
||||
avatar?: string
|
||||
storageUsed: number
|
||||
storageLimit: number
|
||||
tokenBalance: number
|
||||
aiBalance: number
|
||||
}
|
||||
|
||||
export const auth = betterAuth({
|
||||
@@ -47,15 +44,6 @@ export const auth = betterAuth({
|
||||
generateId: false,
|
||||
cookiePrefix: "taxhacker",
|
||||
},
|
||||
databaseHooks: {
|
||||
user: {
|
||||
create: {
|
||||
after: async (user) => {
|
||||
await createUserDefaults(user.id)
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
emailOTP({
|
||||
disableSignUp: config.auth.disableSignup,
|
||||
@@ -69,13 +57,6 @@ export const auth = betterAuth({
|
||||
await sendOTPCodeEmail({ email, otp })
|
||||
},
|
||||
}),
|
||||
isStripeEnabled(stripeClient)
|
||||
? stripe({
|
||||
stripeClient: stripeClient!,
|
||||
stripeWebhookSecret: config.stripe.webhookSecret,
|
||||
createCustomerOnSignUp: true,
|
||||
})
|
||||
: { id: "stripe", endpoints: {} },
|
||||
nextCookies(), // make sure this is the last plugin in the array
|
||||
],
|
||||
})
|
||||
@@ -113,3 +94,10 @@ export async function getCurrentUser(): Promise<User> {
|
||||
// No session or user found
|
||||
redirect(config.auth.loginUrl)
|
||||
}
|
||||
|
||||
export function isSubscriptionExpired(user: User) {
|
||||
if (config.selfHosted.isEnabled) {
|
||||
return false
|
||||
}
|
||||
return user.membershipExpiresAt && user.membershipExpiresAt < new Date()
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ const config = {
|
||||
},
|
||||
ai: {
|
||||
openaiApiKey: env.OPENAI_API_KEY,
|
||||
modelName: "gpt-4o-mini",
|
||||
},
|
||||
auth: {
|
||||
secret: env.BETTER_AUTH_SECRET,
|
||||
@@ -45,6 +46,8 @@ const config = {
|
||||
stripe: {
|
||||
secretKey: env.STRIPE_SECRET_KEY,
|
||||
webhookSecret: env.STRIPE_WEBHOOK_SECRET,
|
||||
paymentSuccessUrl: `${env.BASE_URL}/cloud/payment/success?session_id={CHECKOUT_SESSION_ID}`,
|
||||
paymentCancelUrl: `${env.BASE_URL}/cloud`,
|
||||
},
|
||||
email: {
|
||||
apiKey: env.RESEND_API_KEY,
|
||||
|
||||
@@ -7,7 +7,50 @@ export const stripeClient: Stripe | null = config.stripe.secretKey
|
||||
})
|
||||
: null
|
||||
|
||||
// Type guard to check if Stripe is initialized
|
||||
export const isStripeEnabled = (client: Stripe | null): client is Stripe => {
|
||||
return client !== null
|
||||
export type Plan = {
|
||||
code: string
|
||||
name: string
|
||||
description: string
|
||||
benefits: string[]
|
||||
price: string
|
||||
stripePriceId: string
|
||||
limits: {
|
||||
storage: number
|
||||
ai: number
|
||||
}
|
||||
isAvailable: boolean
|
||||
}
|
||||
|
||||
export const PLANS: Record<string, Plan> = {
|
||||
unlimited: {
|
||||
code: "unlimited",
|
||||
name: "Unlimited",
|
||||
description: "Special unlimited plan",
|
||||
benefits: ["Unlimited storage", "Unlimited AI analysis", "Unlimited everything"],
|
||||
price: "",
|
||||
stripePriceId: "",
|
||||
limits: {
|
||||
storage: -1,
|
||||
ai: -1,
|
||||
},
|
||||
isAvailable: false,
|
||||
},
|
||||
early: {
|
||||
code: "early",
|
||||
name: "Early Adopter",
|
||||
description: "Special plan for our early users",
|
||||
benefits: [
|
||||
"512 Mb of storage",
|
||||
"1000 AI file analysis",
|
||||
"Unlimited transactions",
|
||||
"Unlimited fields, categories and projects",
|
||||
],
|
||||
price: "€50/year",
|
||||
stripePriceId: "price_1RGzKUPKOUEUzVB3hVyo2n57",
|
||||
limits: {
|
||||
storage: 512 * 1024 * 1024,
|
||||
ai: 1000,
|
||||
},
|
||||
isAvailable: true,
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user