Beta testing stripe plugin
Hey! I'm trying to follow these:
https://www.better-auth.com/docs/plugins/stripe
instructions to get the stripe plugin working, but I get stuck at the db migration step, here's the error I'm getting:
I'm using prisma connected to a neon db, any help is appreciated!
npx @better-auth/cli generate
2025-03-02T08:26:29.329Z ERROR [Better Auth]: [#better-auth]: Couldn't read your auth config. Error: Neither apiKey nor config.authenticator provided
at Stripe._setAuthenticator (file:///home/dd0k/prog/site/node_modules/stripe/esm/stripe.core.js:163:23)
at new Stripe (file:///home/dd0k/prog/site/node_modules/stripe/esm/stripe.core.js:99:14)
at /home/dd0k/prog/site/lib/auth.ts:7:22
at async Function.import (/home/dd0k/.npm/_npx/167ca1f116d365e6/node_modules/jiti/dist/jiti.cjs:1:199772)
at async resolveConfig (file:///home/dd0k/.npm/_npx/167ca1f116d365e6/node_modules/c12/dist/shared/c12.PQMoYrit.mjs:346:18)
at async loadConfig (file:///home/dd0k/.npm/_npx/167ca1f116d365e6/node_modules/c12/dist/shared/c12.PQMoYrit.mjs:146:23)
at async getConfig (file:///home/dd0k/.npm/_npx/167ca1f116d365e6/node_modules/@better-auth/cli/dist/index.mjs:234:30)
at async Command.generateAction (file:///home/dd0k/.npm/_npx/167ca1f116d365e6/node_modules/@better-auth/cli/dist/index.mjs:643:18)
npx @better-auth/cli generate
2025-03-02T08:26:29.329Z ERROR [Better Auth]: [#better-auth]: Couldn't read your auth config. Error: Neither apiKey nor config.authenticator provided
at Stripe._setAuthenticator (file:///home/dd0k/prog/site/node_modules/stripe/esm/stripe.core.js:163:23)
at new Stripe (file:///home/dd0k/prog/site/node_modules/stripe/esm/stripe.core.js:99:14)
at /home/dd0k/prog/site/lib/auth.ts:7:22
at async Function.import (/home/dd0k/.npm/_npx/167ca1f116d365e6/node_modules/jiti/dist/jiti.cjs:1:199772)
at async resolveConfig (file:///home/dd0k/.npm/_npx/167ca1f116d365e6/node_modules/c12/dist/shared/c12.PQMoYrit.mjs:346:18)
at async loadConfig (file:///home/dd0k/.npm/_npx/167ca1f116d365e6/node_modules/c12/dist/shared/c12.PQMoYrit.mjs:146:23)
at async getConfig (file:///home/dd0k/.npm/_npx/167ca1f116d365e6/node_modules/@better-auth/cli/dist/index.mjs:234:30)
at async Command.generateAction (file:///home/dd0k/.npm/_npx/167ca1f116d365e6/node_modules/@better-auth/cli/dist/index.mjs:643:18)
Stripe | Better Auth
Stripe plugin for Better Auth to manage subscriptions and payments.
11 Replies
GitHub
stripe plugin doesnt generate customer table with the drizzle adapt...
Is this suited for github? Yes, this is suited for github To Reproduce did not generate to customer table Current vs. Expected behavior to get the schema spesified here: https://www.better-auth.com...
go there
and look at the code i provided
its due to env variables missing
did it worked for you with drizzle adapter?
Yeah it did
take that
import { pgTable, text, timestamp, boolean, integer } from "drizzle-orm/pg-core"
export const user = pgTable("user", {
id: text("id").primaryKey(),
name: text('name').notNull(),
email: text('email').notNull().unique(),
emailVerified: boolean('email_verified').notNull(),
image: text('image'),
createdAt: timestamp('created_at').notNull(),
updatedAt: timestamp('updated_at').notNull(),
role: text('role'),
banned: boolean('banned'),
banReason: text('ban_reason'),
banExpires: timestamp('ban_expires'),
stripeCustomerId: text('stripe_customer_id')
});
export const session = pgTable("session", {
id: text("id").primaryKey(),
expiresAt: timestamp('expires_at').notNull(),
token: text('token').notNull().unique(),
createdAt: timestamp('created_at').notNull(),
updatedAt: timestamp('updated_at').notNull(),
ipAddress: text('ip_address'),
userAgent: text('user_agent'),
userId: text('user_id').notNull().references(()=> user.id, { onDelete: 'cascade' }),
impersonatedBy: text('impersonated_by')
});
export const account = pgTable("account", {
id: text("id").primaryKey(),
accountId: text('account_id').notNull(),
providerId: text('provider_id').notNull(),
userId: text('user_id').notNull().references(()=> user.id, { onDelete: 'cascade' }),
accessToken: text('access_token'),
refreshToken: text('refresh_token'),
idToken: text('id_token'),
accessTokenExpiresAt: timestamp('access_token_expires_at'),
refreshTokenExpiresAt: timestamp('refresh_token_expires_at'),
scope: text('scope'),
password: text('password'),
createdAt: timestamp('created_at').notNull(),
updatedAt: timestamp('updated_at').notNull()
});
export const verification = pgTable("verification", {
id: text("id").primaryKey(),
identifier: text('identifier').notNull(),
value: text('value').notNull(),
expiresAt: timestamp('expires_at').notNull(),
createdAt: timestamp('created_at'),
updatedAt: timestamp('updated_at')
});
export const subscription = pgTable("subscription", {
id: text("id").primaryKey(),
plan: text('plan').notNull(),
referenceId: text('reference_id').notNull(),
stripeCustomerId: text('stripe_customer_id'),
stripeSubscriptionId: text('stripe_subscription_id'),
status: text('status'),
periodStart: timestamp('period_start'),
periodEnd: timestamp('period_end'),
cancelAtPeriodEnd: boolean('cancel_at_period_end'),
seats: integer('seats')
});
import { pgTable, text, timestamp, boolean, integer } from "drizzle-orm/pg-core"
export const user = pgTable("user", {
id: text("id").primaryKey(),
name: text('name').notNull(),
email: text('email').notNull().unique(),
emailVerified: boolean('email_verified').notNull(),
image: text('image'),
createdAt: timestamp('created_at').notNull(),
updatedAt: timestamp('updated_at').notNull(),
role: text('role'),
banned: boolean('banned'),
banReason: text('ban_reason'),
banExpires: timestamp('ban_expires'),
stripeCustomerId: text('stripe_customer_id')
});
export const session = pgTable("session", {
id: text("id").primaryKey(),
expiresAt: timestamp('expires_at').notNull(),
token: text('token').notNull().unique(),
createdAt: timestamp('created_at').notNull(),
updatedAt: timestamp('updated_at').notNull(),
ipAddress: text('ip_address'),
userAgent: text('user_agent'),
userId: text('user_id').notNull().references(()=> user.id, { onDelete: 'cascade' }),
impersonatedBy: text('impersonated_by')
});
export const account = pgTable("account", {
id: text("id").primaryKey(),
accountId: text('account_id').notNull(),
providerId: text('provider_id').notNull(),
userId: text('user_id').notNull().references(()=> user.id, { onDelete: 'cascade' }),
accessToken: text('access_token'),
refreshToken: text('refresh_token'),
idToken: text('id_token'),
accessTokenExpiresAt: timestamp('access_token_expires_at'),
refreshTokenExpiresAt: timestamp('refresh_token_expires_at'),
scope: text('scope'),
password: text('password'),
createdAt: timestamp('created_at').notNull(),
updatedAt: timestamp('updated_at').notNull()
});
export const verification = pgTable("verification", {
id: text("id").primaryKey(),
identifier: text('identifier').notNull(),
value: text('value').notNull(),
expiresAt: timestamp('expires_at').notNull(),
createdAt: timestamp('created_at'),
updatedAt: timestamp('updated_at')
});
export const subscription = pgTable("subscription", {
id: text("id").primaryKey(),
plan: text('plan').notNull(),
referenceId: text('reference_id').notNull(),
stripeCustomerId: text('stripe_customer_id'),
stripeSubscriptionId: text('stripe_subscription_id'),
status: text('status'),
periodStart: timestamp('period_start'),
periodEnd: timestamp('period_end'),
cancelAtPeriodEnd: boolean('cancel_at_period_end'),
seats: integer('seats')
});
The code you have in your Auth.ts is very similar to the code I have
u got the env variables set?
I have the env variables for stripe webhook secret
In my .env.local
STRIPE_WEBHOOK_SECRET
is required too
Um, yeah, I have stripe webhook secret
^
oh no clue then
import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
import { PrismaClient } from "@prisma/client";
import { stripe } from "@better-auth/stripe";
import Stripe from "stripe";
const stripeClient = new Stripe(process.env.STRIPE_SECRET_KEY as string);
const prisma = new PrismaClient();
export const auth = betterAuth({
database: prismaAdapter(prisma, {
provider: "postgresql",
}),
socialProviders: {
github: {
clientId: process.env.AUTH_GITHUB_ID as string,
clientSecret: process.env.AUTH_GITHUB_SECRET as string,
},
google: {
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
},
},
plugins: [
stripe({
stripeClient,
stripeWebhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,
createCustomerOnSignUp: true,
subscription: {
enabled: true,
plans: [
{
name: "basic",
priceId: "price_1QxY9oQeJndFgkfkUFjAEnH4",
},
],
},
}),
],
});
import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
import { PrismaClient } from "@prisma/client";
import { stripe } from "@better-auth/stripe";
import Stripe from "stripe";
const stripeClient = new Stripe(process.env.STRIPE_SECRET_KEY as string);
const prisma = new PrismaClient();
export const auth = betterAuth({
database: prismaAdapter(prisma, {
provider: "postgresql",
}),
socialProviders: {
github: {
clientId: process.env.AUTH_GITHUB_ID as string,
clientSecret: process.env.AUTH_GITHUB_SECRET as string,
},
google: {
clientId: process.env.GOOGLE_CLIENT_ID as string,
clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
},
},
plugins: [
stripe({
stripeClient,
stripeWebhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,
createCustomerOnSignUp: true,
subscription: {
enabled: true,
plans: [
{
name: "basic",
priceId: "price_1QxY9oQeJndFgkfkUFjAEnH4",
},
],
},
}),
],
});