fix(stripe): prevent duplicate customers (#3459)

* prevent duplicate stripe customer

* prevent duplicate stripe customer
This commit is contained in:
Dagmawi Babi
2025-07-18 19:13:50 -07:00
committed by GitHub
parent 1a1594d7f9
commit a9e099775b
2 changed files with 38 additions and 7 deletions
+15 -7
View File
@@ -239,19 +239,26 @@ export const stripe = <O extends StripeOptions>(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 = <O extends StripeOptions>(options: O) => {
},
],
});
customerId = stripeCustomer.id;
} catch (e: any) {
ctx.context.logger.error(e);
+23
View File
@@ -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);
});
});