From a9e099775b2cb9341c65d57d691b8dccdbaf2dcd Mon Sep 17 00:00:00 2001 From: Dagmawi Babi <44819176+dagmawibabi@users.noreply.github.com> Date: Sat, 19 Jul 2025 05:13:50 +0300 Subject: [PATCH] fix(stripe): prevent duplicate customers (#3459) * prevent duplicate stripe customer * prevent duplicate stripe customer --- packages/stripe/src/index.ts | 22 +++++++++++++++------- packages/stripe/src/stripe.test.ts | 23 +++++++++++++++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/packages/stripe/src/index.ts b/packages/stripe/src/index.ts index 633e981fa0..cc4c853e09 100644 --- a/packages/stripe/src/index.ts +++ b/packages/stripe/src/index.ts @@ -239,19 +239,26 @@ export const stripe = (options: O) => { if (!customerId) { try { - const stripeCustomer = await client.customers.create( - { + // Try to find existing Stripe customer by email + const existingCustomers = await client.customers.list({ + email: user.email, + limit: 1, + }); + + let stripeCustomer = existingCustomers.data[0]; + + if (!stripeCustomer) { + stripeCustomer = await client.customers.create({ email: user.email, name: user.name, metadata: { ...ctx.body.metadata, userId: user.id, }, - }, - { - idempotencyKey: generateRandomString(32, "a-z", "0-9"), - }, - ); + }); + } + + // Update local DB with Stripe customer ID await ctx.context.adapter.update({ model: "user", update: { @@ -264,6 +271,7 @@ export const stripe = (options: O) => { }, ], }); + customerId = stripeCustomer.id; } catch (e: any) { ctx.context.logger.error(e); diff --git a/packages/stripe/src/stripe.test.ts b/packages/stripe/src/stripe.test.ts index e8abe3e487..ae33c0db26 100644 --- a/packages/stripe/src/stripe.test.ts +++ b/packages/stripe/src/stripe.test.ts @@ -817,4 +817,27 @@ describe("stripe", async () => { expect(upgradeRes.error).toBeDefined(); expect(upgradeRes.error?.message).toContain("already subscribed"); }); + + it("should only call Stripe customers.create once for signup and upgrade", async () => { + const userRes = await authClient.signUp.email( + { ...testUser, email: "single-create@email.com" }, + { throw: true }, + ); + + const headers = new Headers(); + await authClient.signIn.email( + { ...testUser, email: "single-create@email.com" }, + { + throw: true, + onSuccess: setCookieToHeader(headers), + }, + ); + + await authClient.subscription.upgrade({ + plan: "starter", + fetchOptions: { headers }, + }); + + expect(mockStripe.customers.create).toHaveBeenCalledTimes(1); + }); });