Argument `stripeCustomerId` is missing.

I'm getting the following error:
2025-04-18T03:02:49.602Z ERROR [Better Auth]: PrismaClientValidationError:
Invalid `prisma.user.create()` invocation:

{
data: {
name: "gabriel",
emailVerified: true,
image: "https://cdn.discordapp.com/avatars/721944365114851399/45d0a35d42c301ab7a8a0fbb4f3ecb09.png",
createdAt: new Date("2025-04-18T03:02:49.577Z"),
updatedAt: new Date("2025-04-18T03:02:49.577Z"),
role: "user",
id: "bXLuNql6aY2lMl1I4CoZUloeazQKsSgg",
+ stripeCustomerId: String
},
select: undefined
}

Argument `stripeCustomerId` is missing.
2025-04-18T03:02:49.604Z ERROR [Better Auth]: unable_to_create_user
2025-04-18T03:02:49.602Z ERROR [Better Auth]: PrismaClientValidationError:
Invalid `prisma.user.create()` invocation:

{
data: {
name: "gabriel",
emailVerified: true,
image: "https://cdn.discordapp.com/avatars/721944365114851399/45d0a35d42c301ab7a8a0fbb4f3ecb09.png",
createdAt: new Date("2025-04-18T03:02:49.577Z"),
updatedAt: new Date("2025-04-18T03:02:49.577Z"),
role: "user",
id: "bXLuNql6aY2lMl1I4CoZUloeazQKsSgg",
+ stripeCustomerId: String
},
select: undefined
}

Argument `stripeCustomerId` is missing.
2025-04-18T03:02:49.604Z ERROR [Better Auth]: unable_to_create_user
This happens when I try to register in my application with the createCustomerOnSignUp option enabled in the Stripe plugin. I have already run the database migration, but the error still persists.
Solution:
BA probably creates the stripe customer after the user is created in the database not before
Jump to solution
17 Replies
gabriel
gabrielOP•4d ago
My auth config:
import { database } from '@repo/database';
import { betterAuth } from 'better-auth';
import { prismaAdapter } from 'better-auth/adapters/prisma';
import { nextCookies } from 'better-auth/next-js';
import { admin as adminPlugin } from 'better-auth/plugins';
import { keys } from './keys';
export { toNextJsHandler } from 'better-auth/next-js';
import { accessControl, user, developer, admin } from './permissions';
import { stripe } from '@repo/payments';
import { keys as paymentKeys } from '@repo/payments/keys';
import { stripe as stripePlugin } from '@better-auth/stripe';

export const auth = betterAuth({
database: prismaAdapter(database, {
provider: 'postgresql',
}),
socialProviders: {
discord: {
clientId: keys().DISCORD_CLIENT_ID,
clientSecret: keys().DISCORD_CLIENT_SECRET,
redirectURI: keys().DISCORD_REDIRECT_URI,
},
},
advanced: {
crossSubDomainCookies: {
enabled: true,
domain: 'localhost',
},
defaultCookieAttributes: {
secure: true,
httpOnly: true,
sameSite: 'none',
partitioned: true,
},
},
trustedOrigins: [
'http://localhost:3000', // APP (panel)
'http://localhost:3001', // WEB (landing & products)
'http://localhost:3002', // API
],
plugins: [
nextCookies(),
adminPlugin({
accessControl,
roles: {
admin,
developer,
user,
},
}),
stripePlugin({
stripeClient: stripe,
stripeWebhookSecret: paymentKeys().STRIPE_WEBHOOK_SECRET!,
createCustomerOnSignUp: true,
}),
],
});
import { database } from '@repo/database';
import { betterAuth } from 'better-auth';
import { prismaAdapter } from 'better-auth/adapters/prisma';
import { nextCookies } from 'better-auth/next-js';
import { admin as adminPlugin } from 'better-auth/plugins';
import { keys } from './keys';
export { toNextJsHandler } from 'better-auth/next-js';
import { accessControl, user, developer, admin } from './permissions';
import { stripe } from '@repo/payments';
import { keys as paymentKeys } from '@repo/payments/keys';
import { stripe as stripePlugin } from '@better-auth/stripe';

export const auth = betterAuth({
database: prismaAdapter(database, {
provider: 'postgresql',
}),
socialProviders: {
discord: {
clientId: keys().DISCORD_CLIENT_ID,
clientSecret: keys().DISCORD_CLIENT_SECRET,
redirectURI: keys().DISCORD_REDIRECT_URI,
},
},
advanced: {
crossSubDomainCookies: {
enabled: true,
domain: 'localhost',
},
defaultCookieAttributes: {
secure: true,
httpOnly: true,
sameSite: 'none',
partitioned: true,
},
},
trustedOrigins: [
'http://localhost:3000', // APP (panel)
'http://localhost:3001', // WEB (landing & products)
'http://localhost:3002', // API
],
plugins: [
nextCookies(),
adminPlugin({
accessControl,
roles: {
admin,
developer,
user,
},
}),
stripePlugin({
stripeClient: stripe,
stripeWebhookSecret: paymentKeys().STRIPE_WEBHOOK_SECRET!,
createCustomerOnSignUp: true,
}),
],
});
Ping
Ping•4d ago
What version of BA are you on?
gabriel
gabrielOP•3d ago
I'm on v1.2.7
Ping
Ping•3d ago
@gabriel I'll try to reproduce on my end and let you know how it goes.
🌠kkMihai ⚡
did you setup correctly the stripe client?
gabriel
gabrielOP•3d ago
GitHub
next-forge/packages/payments/index.ts at main · haydenbleasel/next...
Production-grade Turborepo template for Next.js apps. - haydenbleasel/next-forge
gabriel
gabrielOP•3d ago
Ok
🌠kkMihai ⚡
make stripeCustomerId optional in your schema
Solution
🌠kkMihai ⚡
BA probably creates the stripe customer after the user is created in the database not before
🌠kkMihai ⚡
not probably, for sure it does
Ping
Ping•3d ago
@gabriel Can I see your prisma schema that was generated by Better Auth?
🌠kkMihai ⚡
he for sure didint make stripeCustomerId optional, thats the only reason i could possible think he gets that error logically
gabriel
gabrielOP•3d ago
@🌠kkMihai ⚡ is right — Better Auth is creating the customer after login. I had manually added the stripeCustomerId field based on the plugin's documentation schema. After changing the field to optional, the issue was resolved. Thank you all!
No description
🌠kkMihai ⚡
np, happy to help also quick question did you used the BA cli to generated the schema or?
gabriel
gabrielOP•3d ago
No, I manually added the field just like the documentation
gabriel
gabrielOP•3d ago
No description
🌠kkMihai ⚡
ye makes sense why u got that @gabriel mark this as resolved @Ping update the docs to specify stripeCustomerId to be set as optional

Did you find this page helpful?