Stripe creating subscription: Unauthorized 401
Hello, I'm running into an issue with Stripe Subscriptions whereas I cannot generate a new subscription for an user. I'm using @better-auth/strip and receive a 401 Unauthorized when I'm creating a subscription on the client. The only weird thing AFAIK is that I use the convexAdapter, so I cannot run migrations for stripe myself (but this seems unrelated to the unauthorized).
I've checked the .env.local keys a dozen times. I'm running a Tanstack Start app.
auth.tsx
I've checked the .env.local keys a dozen times. I'm running a Tanstack Start app.
auth.tsx
import { betterAuth } from "better-auth";
import { APP_NAME, DEFAULT_AVATAR, DEFAULT_LANGUAGE } from "@/config/constants";
import { ConvexHttpClient } from "convex/browser";
import { convexAdapter } from "@better-auth-kit/convex";
import { stripe } from "@better-auth/stripe";
import Stripe from "stripe";
const convexClient = new ConvexHttpClient(import.meta.env.VITE_CONVEX_URL);
const stripeClient = new Stripe(import.meta.env.VITE_STRIPE_SECRET_KEY);
export const AUTH_PROVIDERS = {
CREDENTIAL: "credential",
APPLE: "apple",
GOOGLE: "google",
} as const;
export const auth = betterAuth({
appName: APP_NAME,
secret: import.meta.env.VITE_BETTER_AUTH_SECRET,
baseURL: import.meta.env.VITE_BETTER_AUTH_URL,
database: convexAdapter(convexClient),
plugins: [
stripe({
stripeClient,
stripeWebhookSecret: import.meta.env.VITE_STRIPE_WEBHOOKS_ENDPOINT_SECRET,
createCustomerOnSignUp: true,
subscription: {
enabled: true,
plans: [
{
name: "monthly", // the name of the plan, it'll be automatically lower cased when stored in the database
priceId: import.meta.env.VITE_STRIPE_MONTHLY_PRICE_ID, // the price id from stripe
},
{
name: "yearly",
priceId: import.meta.env.VITE_STRIPE_YEARLY_PRICE_ID,
},
],
},
}),
],import { betterAuth } from "better-auth";
import { APP_NAME, DEFAULT_AVATAR, DEFAULT_LANGUAGE } from "@/config/constants";
import { ConvexHttpClient } from "convex/browser";
import { convexAdapter } from "@better-auth-kit/convex";
import { stripe } from "@better-auth/stripe";
import Stripe from "stripe";
const convexClient = new ConvexHttpClient(import.meta.env.VITE_CONVEX_URL);
const stripeClient = new Stripe(import.meta.env.VITE_STRIPE_SECRET_KEY);
export const AUTH_PROVIDERS = {
CREDENTIAL: "credential",
APPLE: "apple",
GOOGLE: "google",
} as const;
export const auth = betterAuth({
appName: APP_NAME,
secret: import.meta.env.VITE_BETTER_AUTH_SECRET,
baseURL: import.meta.env.VITE_BETTER_AUTH_URL,
database: convexAdapter(convexClient),
plugins: [
stripe({
stripeClient,
stripeWebhookSecret: import.meta.env.VITE_STRIPE_WEBHOOKS_ENDPOINT_SECRET,
createCustomerOnSignUp: true,
subscription: {
enabled: true,
plans: [
{
name: "monthly", // the name of the plan, it'll be automatically lower cased when stored in the database
priceId: import.meta.env.VITE_STRIPE_MONTHLY_PRICE_ID, // the price id from stripe
},
{
name: "yearly",
priceId: import.meta.env.VITE_STRIPE_YEARLY_PRICE_ID,
},
],
},
}),
],Solution
subscription: defineTable({
id: v.string(), // <-- this was the problem
plan: v.string(),
referenceId: v.id("user"),
stripeCustomerId: v.optional(v.string()),
stripeSubscriptionId: v.optional(v.string()),
status: v.string(),
periodStart: v.optional(v.string()),
periodEnd: v.optional(v.string()),
cancelAtPeriodEnd: v.optional(v.boolean()),
seats: v.optional(v.number()),
trialStart: v.optional(v.string()),
trialEnd: v.optional(v.string()),
}), subscription: defineTable({
id: v.string(), // <-- this was the problem
plan: v.string(),
referenceId: v.id("user"),
stripeCustomerId: v.optional(v.string()),
stripeSubscriptionId: v.optional(v.string()),
status: v.string(),
periodStart: v.optional(v.string()),
periodEnd: v.optional(v.string()),
cancelAtPeriodEnd: v.optional(v.boolean()),
seats: v.optional(v.number()),
trialStart: v.optional(v.string()),
trialEnd: v.optional(v.string()),
}),